diff options
| author | Shulhan <ms@kilabit.info> | 2026-04-04 16:38:06 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2026-04-04 16:38:06 +0700 |
| commit | 45526ab31b93debffd51e1aaad43c9acf9d61ab6 (patch) | |
| tree | a23ccc730093cf8d251c1d6e43a3c9679f42112c /document_parser.go | |
| parent | a9e626c6306697a64af87b1b7fa4f61b0580d5a8 (diff) | |
| download | asciidoctor-go-45526ab31b93debffd51e1aaad43c9acf9d61ab6.tar.xz | |
all: fix parsing literal paragraph
A line that start with one or more space will be considered
as literal paragraph.
Once literal line found it will end until an empty line.
Diffstat (limited to 'document_parser.go')
| -rw-r--r-- | document_parser.go | 71 |
1 files changed, 59 insertions, 12 deletions
diff --git a/document_parser.go b/document_parser.go index 8de91cc..18c0817 100644 --- a/document_parser.go +++ b/document_parser.go @@ -11,6 +11,13 @@ import ( "git.sr.ht/~shulhan/pakakeh.go/lib/ascii" ) +// From the [Document.parse] its all start from parseBlock. +// +// -> parseBlock() +// -> line() +// -> whatKindOfLine() +// The parsing branched here based on docp.kind. + const debugLevel = 0 type documentParser struct { @@ -133,6 +140,48 @@ func (docp *documentParser) consumeLinesUntil(el *element, term int, terms []int return line } +// consumeLiteralParagraph consumes lines that start with spaces and returns +// the next line that does not have it. +func (docp *documentParser) consumeLiteralParagraph(el *element, + origSpaces []byte, terms ...int, +) (line []byte) { + logp := `consumeLiteralParagraph` + lenOrigSpaces := len(origSpaces) + var spaces []byte + var ok bool + for { + spaces, line, ok = docp.line(logp) + if !ok { + break + } + if bytes.HasPrefix(spaces, origSpaces) { + el.Write(spaces[lenOrigSpaces:]) + el.Write(line) + el.WriteByte('\n') + continue + } + if len(spaces) != 0 { + // If start with spaces, remove single space only and + // append the rest. + el.Write(spaces[1:]) + el.Write(line) + el.WriteByte('\n') + continue + } + for _, kind := range terms { + if kind == docp.kind { + goto out + } + } + // Keep consume lines until we found terminating conditions. + el.Write(line) + el.WriteByte('\n') + } +out: + el.raw = applySubstitutions(docp.doc, el.raw) + return line +} + // hasPreamble will return true if the contents contains preamble, indicated // by the first section that found after current line. func (docp *documentParser) hasPreamble() bool { @@ -285,12 +334,13 @@ func (docp *documentParser) parseBlock(parent *element, term int) { el = &element{} line []byte + spaces []byte isTerm bool ok bool ) for !isTerm { if len(line) == 0 { - _, line, ok = docp.line(logp) + spaces, line, ok = docp.line(logp) if !ok { return } @@ -514,17 +564,14 @@ func (docp *documentParser) parseBlock(parent *element, term int) { el.addRole(classNameLiteralBlock) el.Write(line) el.WriteByte('\n') - line = docp.consumeLinesUntil( - el, - lineKindEmpty, - []int{ - term, - elKindBlockListing, - elKindBlockListingNamed, - elKindBlockLiteral, - elKindBlockLiteralNamed, - }) - el.raw = applySubstitutions(docp.doc, el.raw) + line = docp.consumeLiteralParagraph(el, + spaces, lineKindEmpty, + term, + elKindBlockListing, + elKindBlockListingNamed, + elKindBlockLiteral, + elKindBlockLiteralNamed, + ) } parent.addChild(el) el = &element{} |
