aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2023-12-10 02:38:42 +0700
committerShulhan <ms@kilabit.info>2023-12-10 02:40:21 +0700
commitcdd1faa6b97de023ef7129399483e841fb4a9b16 (patch)
tree1d16642ad81c391554e3c9e2420f4fdd7003d738
parent9242df367ec97093dbfce62830db020ec53def11 (diff)
downloadasciidoctor-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.go20
-rw-r--r--document_parser.go31
-rw-r--r--parser.go2
-rw-r--r--testdata/custom_ids_test.txt70
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
}
diff --git a/parser.go b/parser.go
index a748bde..6d47d1d 100644
--- a/parser.go
+++ b/parser.go
@@ -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>