Proper markdown comments.
commit daf485e889ec2b99199e4b46b8688a3df6414623 · parent 2d2d4c2b79
· browse this tree
Eric Myhre, 2021-08-17 20:11:21 UTC
Apparently they also have parenthesis. Fine. The syntactic load of that is sort of horrific, but if the goal of "the data is in markdown documents that are also being parsed by other things" appeals to you, then this is where you have to live. (Or we'd have to make a different convention, like using h4 tags, or something. But that seems more opinionated, and wouldn't always fit with other tools.)
diff --git a/patch.go b/patch.go index ba66170..e1342c4 100644 --- a/patch.go +++ b/patch.go @@ -92,7 +92,7 @@ func Patch(oldDoc *Document, hunks ...Hunk) (newDoc *Document) { } func appendHunkLines(lines [][]byte, hunkName string, hunkBlockTag string, hunkBodyLines [][]byte) [][]byte { - lines = append(lines, bytes.Join([][]byte{sigilTestmark, []byte(hunkName)}, nil)) + lines = append(lines, bytes.Join([][]byte{sigilTestmark, []byte{'('}, []byte(hunkName), []byte{')'}}, nil)) lines = append(lines, bytes.Join([][]byte{sigilCodeBlock, []byte(hunkBlockTag)}, nil)) lines = append(lines, hunkBodyLines...) lines = append(lines, sigilCodeBlock) diff --git a/read.go b/read.go index 9745090..50df5b1 100644 --- a/read.go +++ b/read.go @@ -83,19 +83,30 @@ func Parse(data []byte) (*Document, error) { } // Look for testmark block indicators. if bytes.HasPrefix(line, sigilTestmark) { + // If this line, after the sigil prefix, doesn't begin with "(" and end with ")", it's not a well-formed markdown comment, and you should probably be told about that. remainder := line[len(sigilTestmark):] + if len(remainder) < 2 || remainder[0] != '(' || remainder[len(remainder)-1] != ')' { + return &doc, fmt.Errorf("invalid markdown comment on line %d (should look like %q, mind the parens)", i+1, "[testmark]:# (data-name-here)") + } + remainder = remainder[1 : len(remainder)-1] + + // Parse the name. If there's whitespace inside here, we'll just quietly stop at that. Maybe we'll do extensions with that info space in the future. nameEnd := bytes.IndexFunc(remainder, unicode.IsSpace) if nameEnd < 0 { nameEnd = len(remainder) } name := string(remainder[0:nameEnd]) if len(name) == 0 { - // ... Log a complaint? Empty block names are very silly. + return &doc, fmt.Errorf("invalid markdown comment on line %d, hunk name is empty", i+1) } + + // Error if the hunk name is repeated. if already, exists := doc.HunksByName[name]; exists { // You can actually ignore this error, and things will even still mostly work. HunksByName will only look up the first occurence, and Patch will change only the first occurence, and that is weird, but perhaps fine. return &doc, fmt.Errorf("repeated testmark hunk name %q, first seen on line %d, and again on line %d", name, already.LineStart+1, i+1) } + + // Okay: hunk started (probably), name is parsed out, we expect a code block to start on the next line, cool. expectCodeBlock = true hunkInProgress.LineStart = i hunkInProgress.Name = name diff --git a/read_test.go b/read_test.go index d06481f..961b611 100644 --- a/read_test.go +++ b/read_test.go @@ -12,6 +12,7 @@ func TestRead(t *testing.T) { panic(err) } doc, err := ReadFile(filepath.Join(testdata, "example.md")) + fmt.Printf("err: %v\n", err) for _, hunk := range doc.DataHunks { fmt.Printf("hunk %q is on lines %d:%d, has body %q\n", hunk.Name, hunk.LineStart+1, hunk.LineEnd+1, string(hunk.Body)) } diff --git a/testdata/example.md b/testdata/example.md index b81d5b3..c8246d8 100644 --- a/testdata/example.md +++ b/testdata/example.md @@ -10,7 +10,7 @@ They're freetext, and you can use markdown to describe whatever you want. Except these: -[testmark]:# this-is-the-data-name +[testmark]:# (this-is-the-data-name) ```text the content of this code block is data which can be read, and *replaced*, by testmark. @@ -21,7 +21,7 @@ I mean, it is -- but be sure to look at this file in a "raw" mode. There's also a comment above it, which tells testmark to look at it: ``` -[testmark]:# this-is-the-data-name +[testmark]:# (this-is-the-data-name) ``` That comment, coming right before a triple-backtick code block, is a signal. @@ -33,7 +33,7 @@ Multiple data hunks per file You can have more than one block like that in a file: -[testmark]:# more-data +[testmark]:# (more-data) ```go func OtherMarkdownParsers() (shouldHighlight bool) { return true @@ -67,7 +67,7 @@ One note There is one thing this format is bad at: you can't easily describe data that doesn't have a trailing linebreak. -[testmark]:# cannot-describe-no-linebreak +[testmark]:# (cannot-describe-no-linebreak) ``` A markdown codeblock always has a trailing linebreak before its close indicator, you see. ```