diff options
| author | Shulhan <ms@kilabit.info> | 2023-12-10 02:38:42 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2023-12-10 02:40:21 +0700 |
| commit | cdd1faa6b97de023ef7129399483e841fb4a9b16 (patch) | |
| tree | 1d16642ad81c391554e3c9e2420f4fdd7003d738 | |
| parent | 9242df367ec97093dbfce62830db020ec53def11 (diff) | |
| download | asciidoctor-go-cdd1faa6b97de023ef7129399483e841fb4a9b16.tar.xz | |
all: fix custom IDs on first section got replaced
Any custom ID on the first section always replaced with the subsection
because, first, when detecting preamble we did not check for line with
kind ID "[[...]]" an short ID "[#...]".
Second, when parsing preamble we did not stop when we found line kind
ID and short ID.
This preamble thing is kind of annoying.
We need to revisit again how to detect preamble, maybe not calling
separate block parser, but making it linear as the default first child of
parent element.
| -rw-r--r-- | asciidoctor_test.go | 20 | ||||
| -rw-r--r-- | document_parser.go | 31 | ||||
| -rw-r--r-- | parser.go | 2 | ||||
| -rw-r--r-- | testdata/custom_ids_test.txt | 70 |
4 files changed, 99 insertions, 24 deletions
diff --git a/asciidoctor_test.go b/asciidoctor_test.go index 8944165..886e84c 100644 --- a/asciidoctor_test.go +++ b/asciidoctor_test.go @@ -20,11 +20,13 @@ func TestData(t *testing.T) { var ( listTData []*test.Data tdata *test.Data - inputCall string + bbuf bytes.Buffer outputCall string inputName string subtestName string inputContent []byte + exp []byte + got []byte err error ) @@ -34,28 +36,15 @@ func TestData(t *testing.T) { } for _, tdata = range listTData { - inputCall = tdata.Flag[`input_call`] outputCall = tdata.Flag[`output_call`] for inputName, inputContent = range tdata.Input { subtestName = tdata.Name + `/` + inputName t.Run(subtestName, func(t *testing.T) { - var ( - doc *Document - bbuf bytes.Buffer - exp []byte - got []byte - ) - - exp = tdata.Output[inputName] - bbuf.Reset() - switch inputCall { - default: - doc = Parse(inputContent) - } + var doc = Parse(inputContent) switch outputCall { case outputCallHTMLWriteHeader: @@ -73,6 +62,7 @@ func TestData(t *testing.T) { got = bbuf.Bytes() } + exp = tdata.Output[inputName] test.Assert(t, subtestName, string(exp), string(got)) }) } diff --git a/document_parser.go b/document_parser.go index d165ff9..27f92be 100644 --- a/document_parser.go +++ b/document_parser.go @@ -61,6 +61,8 @@ func parseSub(parentDoc *Document, content []byte) (subdoc *Document) { return subdoc } +// consumeLinesUntil given an element el, consume all lines until we found +// a line with kind match with term or match with one in terms. func (docp *documentParser) consumeLinesUntil(el *element, term int, terms []int) (line []byte) { var ( logp = `consumeLinesUntil` @@ -148,7 +150,9 @@ func (docp *documentParser) hasPreamble() bool { kind, _, _ = whatKindOfLine(line) if kind == elKindSectionL1 || kind == elKindSectionL2 || kind == elKindSectionL3 || kind == elKindSectionL4 || - kind == elKindSectionL5 { + kind == elKindSectionL5 || + kind == lineKindID || + kind == lineKindIDShort { return notEmtpy > 0 } notEmtpy++ @@ -276,9 +280,7 @@ func (docp *documentParser) parseMultiline(out io.Writer) { func (docp *documentParser) parseBlock(parent *element, term int) { var ( logp = `parseBlock` - el = &element{ - kind: elKindUnknown, - } + el = &element{} line []byte isTerm bool @@ -314,13 +316,19 @@ func (docp *documentParser) parseBlock(parent *element, term int) { continue case lineKindID: + if parent.kind == elKindPreamble { + docp.kind = lineKindEmpty + docp.prevKind = lineKindEmpty + docp.lineNum-- + isTerm = true + continue + } var ( idLabel = line[2 : len(line)-2] id, label = parseIDLabel(idLabel) ) if len(id) > 0 { - el.ID = docp.doc.registerAnchor( - string(id), string(label)) + el.ID = docp.doc.registerAnchor(string(id), string(label)) line = nil continue } @@ -330,6 +338,14 @@ func (docp *documentParser) parseBlock(parent *element, term int) { continue case lineKindIDShort: + if parent.kind == elKindPreamble { + docp.kind = lineKindEmpty + docp.prevKind = lineKindEmpty + docp.lineNum-- + isTerm = true + continue + } + var ( id = line[2 : len(line)-1] label []byte @@ -338,8 +354,7 @@ func (docp *documentParser) parseBlock(parent *element, term int) { id, label = parseIDLabel(id) if len(id) > 0 { - el.ID = docp.doc.registerAnchor( - string(id), string(label)) + el.ID = docp.doc.registerAnchor(string(id), string(label)) line = nil continue } @@ -665,7 +665,7 @@ func parseClosedBracket(input []byte, openb, closedb byte) (out []byte, idx int) return nil, -1 } -// parseIDLabel parse the string "ID (,LABEL)" into ID and label. +// parseIDLabel parse the string "ID (,LABEL)" into id and label. // It will return empty id and label if ID is not valid. func parseIDLabel(s []byte) (id, label []byte) { var idLabel = bytes.Split(s, []byte(`,`)) diff --git a/testdata/custom_ids_test.txt b/testdata/custom_ids_test.txt new file mode 100644 index 0000000..917a492 --- /dev/null +++ b/testdata/custom_ids_test.txt @@ -0,0 +1,70 @@ +output_call: ToHTMLBody + +>>> without_preamble += Without preamble + +[#foo_v1_1_0] +== foo v1.1.0 (2023-02-01) + +[#foo_v1_0_0] +== foo v1.0.0 (2023-01-01) + +<<< without_preamble +<div id="header"> +<h1>Without preamble</h1> +</div> +<div id="content"> +<div class="sect1"> +<h2 id="foo_v1_1_0">foo v1.1.0 (2023-02-01)</h2> +<div class="sectionbody"> +</div> +</div> +<div class="sect1"> +<h2 id="foo_v1_0_0">foo v1.0.0 (2023-01-01)</h2> +<div class="sectionbody"> +</div> +</div> +</div> +<div id="footer"> +<div id="footer-text"> +</div> +</div> + +>>> with_preamble += With preamble + +This is a preamble. + +[#foo_v1_1_0] +== foo v1.1.0 (2023-02-01) + +[#foo_v1_0_0] +== foo v1.0.0 (2023-01-01) + +<<< with_preamble +<div id="header"> +<h1>With preamble</h1> +</div> +<div id="content"> +<div id="preamble"> +<div class="sectionbody"> +<div class="paragraph"> +<p>This is a preamble.</p> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="foo_v1_1_0">foo v1.1.0 (2023-02-01)</h2> +<div class="sectionbody"> +</div> +</div> +<div class="sect1"> +<h2 id="foo_v1_0_0">foo v1.0.0 (2023-01-01)</h2> +<div class="sectionbody"> +</div> +</div> +</div> +<div id="footer"> +<div id="footer-text"> +</div> +</div> |
