aboutsummaryrefslogtreecommitdiff
path: root/document_parser.go
diff options
context:
space:
mode:
Diffstat (limited to 'document_parser.go')
-rw-r--r--document_parser.go71
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{}