Merge pull request 'fix(docs): pair comment ids with the document order (#92)' (#93) from fix/docs-comment-id#92 into main
This commit was merged in pull request #93.
This commit is contained in:
+4
-6
@@ -65,6 +65,7 @@ func InjectDocxComments(src []byte, author string, comments []DocxComment) ([]by
|
||||
}
|
||||
|
||||
used := make([]bool, len(comments))
|
||||
applied := make([]DocxComment, 0, len(comments))
|
||||
id := 0
|
||||
newDoc := docxParaRe.ReplaceAllStringFunc(string(doc), func(p string) string {
|
||||
txt := docxPlain(p)
|
||||
@@ -73,6 +74,9 @@ func InjectDocxComments(src []byte, author string, comments []DocxComment) ([]by
|
||||
continue
|
||||
}
|
||||
used[i] = true
|
||||
// Record in document order so comments.xml id N matches the marker
|
||||
// with id N (the spec order may differ from the document order).
|
||||
applied = append(applied, c)
|
||||
p = docxAddMarkers(p, id)
|
||||
id++
|
||||
break
|
||||
@@ -80,12 +84,6 @@ func InjectDocxComments(src []byte, author string, comments []DocxComment) ([]by
|
||||
return p
|
||||
})
|
||||
|
||||
applied := make([]DocxComment, 0, len(comments))
|
||||
for i, c := range comments {
|
||||
if used[i] {
|
||||
applied = append(applied, c)
|
||||
}
|
||||
}
|
||||
parts["word/document.xml"] = []byte(newDoc)
|
||||
parts["word/comments.xml"] = docxBuildComments(author, applied)
|
||||
parts["[Content_Types].xml"] = docxAddContentType(parts["[Content_Types].xml"])
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"archive/zip"
|
||||
"bytes"
|
||||
"io"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
@@ -124,6 +125,48 @@ func TestInjectDocxCommentsNoMatch(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestInjectDocxCommentsOrder guards the marker-id ↔ comments.xml pairing when
|
||||
// the spec order differs from the document order.
|
||||
func TestInjectDocxCommentsOrder(t *testing.T) {
|
||||
src := buildTestDocx(t)
|
||||
spec := []DocxComment{
|
||||
{Anchor: "Nothing relevant", Text: "comment B"},
|
||||
{Anchor: "The term is two years", Text: "comment A"},
|
||||
}
|
||||
out, applied, err := InjectDocxComments(src, "A", spec)
|
||||
if err != nil || applied != 2 {
|
||||
t.Fatalf("inject: applied=%d err=%v", applied, err)
|
||||
}
|
||||
doc := unzipPart(t, out, "word/document.xml")
|
||||
cmts := unzipPart(t, out, "word/comments.xml")
|
||||
|
||||
// id -> text from comments.xml
|
||||
byID := map[string]string{}
|
||||
for _, m := range regexp.MustCompile(`(?s)<w:comment w:id="(\d+)"[^>]*>(.*?)</w:comment>`).FindAllStringSubmatch(cmts, -1) {
|
||||
txt := strings.TrimSpace(stripTags(m[2]))
|
||||
byID[m[1]] = txt
|
||||
}
|
||||
// paragraph that starts with the term text must point at "comment A"
|
||||
for _, p := range regexp.MustCompile(`(?s)<w:p\b[^>]*>.*?</w:p>`).FindAllString(doc, -1) {
|
||||
if !strings.Contains(stripTags(p), "The term is two years") {
|
||||
continue
|
||||
}
|
||||
m := regexp.MustCompile(`<w:commentRangeStart w:id="(\d+)"/>`).FindStringSubmatch(p)
|
||||
if m == nil {
|
||||
t.Fatal("no commentRangeStart in the term paragraph")
|
||||
}
|
||||
if got := byID[m[1]]; got != "comment A" {
|
||||
t.Fatalf("term paragraph points at id %s = %q, want \"comment A\"", m[1], got)
|
||||
}
|
||||
return
|
||||
}
|
||||
t.Fatal("term paragraph not found")
|
||||
}
|
||||
|
||||
func stripTags(s string) string {
|
||||
return regexp.MustCompile(`<[^>]*>`).ReplaceAllString(s, "")
|
||||
}
|
||||
|
||||
func TestParseDocxComments(t *testing.T) {
|
||||
got, err := ParseDocxComments([]byte(`[{"anchor":"a","text":"b"}]`))
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user