diff --git a/README.org b/README.org index f72c252..a20f0a2 100644 --- a/README.org +++ b/README.org @@ -3,6 +3,10 @@ A basic org-mode parser in go. Take a look at [[https://niklasfasching.github.io/go-org/][github pages]] for some examples and an online org->html demo. * next - more keywords: https://orgmode.org/manual/In_002dbuffer-settings.html +- improve list parsing + - handle list items with empty first line + - handle checkboxes & statistic cookies + - handle ordered list overrides [@10] ** TODO list checkboxes & statistics [0/2] https://orgmode.org/manual/Checkboxes.html 1. [ ] parse checkbox of list item diff --git a/org/list.go b/org/list.go index 853a1b6..3e2ece6 100644 --- a/org/list.go +++ b/org/list.go @@ -83,9 +83,6 @@ func (d *Document) parseListItem(l List, i int, parentStop stopFn) (int, Node) { if l.Kind == "descriptive" { if m := descriptiveListItemRegexp.FindStringIndex(content); m != nil { dterm, content = content[:m[0]], content[m[1]:] - if len(content) == 0 { - content = "\n" - } } } d.tokens[i] = tokenize(strings.Repeat(" ", minIndent) + content) @@ -96,7 +93,7 @@ func (d *Document) parseListItem(l List, i int, parentStop stopFn) (int, Node) { t := d.tokens[i] return t.lvl < minIndent && !(t.kind == "text" && t.content == "") } - for !stop(d, i) && !isSecondBlankLine(d, i) { + for !stop(d, i) && (i <= start+1 || !isSecondBlankLine(d, i)) { consumed, node := d.parseOne(i, stop) i += consumed nodes = append(nodes, node) diff --git a/org/org.go b/org/org.go index 116038d..fe90179 100644 --- a/org/org.go +++ b/org/org.go @@ -201,22 +201,30 @@ func (w *OrgWriter) writeComment(c Comment) { func (w *OrgWriter) writeList(l List) { w.writeNodes(l.Items...) } func (w *OrgWriter) writeListItem(li ListItem) { - w.WriteString(w.indent + li.Bullet + " ") liWriter := w.emptyClone() liWriter.indent = w.indent + strings.Repeat(" ", len(li.Bullet)+1) liWriter.writeNodes(li.Children...) - w.WriteString(strings.TrimPrefix(liWriter.String(), liWriter.indent)) + content := strings.TrimPrefix(liWriter.String(), liWriter.indent) + w.WriteString(w.indent + li.Bullet) + if len(content) > 0 && content[0] == '\n' { + w.WriteString(content) + } else { + w.WriteString(" " + content) + } } func (w *OrgWriter) writeDescriptiveListItem(di DescriptiveListItem) { + w.WriteString(w.indent + di.Bullet) + indent := w.indent + strings.Repeat(" ", len(di.Bullet)+1) + if len(di.Term) != 0 { + term := w.nodesAsString(di.Term...) + w.WriteString(" " + term + " ::") + indent = indent + strings.Repeat(" ", len(term)+4) + } diWriter := w.emptyClone() - diWriter.indent = w.indent + strings.Repeat(" ", len(di.Bullet)+1) + diWriter.indent = indent diWriter.writeNodes(di.Details...) details := strings.TrimPrefix(diWriter.String(), diWriter.indent) - w.WriteString(w.indent + di.Bullet) - if len(di.Term) != 0 { - w.WriteString(" " + w.nodesAsString(di.Term...) + " ::") - } if len(details) > 0 && details[0] == '\n' { w.WriteString(details) } else { diff --git a/org/testdata/lists.html b/org/testdata/lists.html index 4d93680..63af830 100644 --- a/org/testdata/lists.html +++ b/org/testdata/lists.html @@ -98,19 +98,32 @@ descriptive lists
-description +details +continued details
-without term +details without a term
-description +details on a new line
+details on a new line (with an empty line in between) +continued +
+
+echo "Hello World!"
+
+