From 42dc70e7ada85319eb4e43e47d6174cf8b7cead2 Mon Sep 17 00:00:00 2001 From: Niklas Fasching Date: Tue, 18 Dec 2018 23:36:51 +0100 Subject: [PATCH] Support blocks with unindented content list items only contain content that is indented to their respective level. Except when that content is inside a block. To allow for this we have to ignore the parentStop when parsing a block and just include everything until the end of that block. Can't think of any problems with this right now. Let's see if this comes back to bite me. --- README.org | 4 ---- org/block.go | 16 +++++++------- org/org.go | 7 +++++-- org/testdata/blocks.html | 38 ++++++++++++++++++++++++++++++++++ org/testdata/blocks.org | 18 ++++++++++++++++ org/testdata/blocks.pretty_org | 18 ++++++++++++++++ 6 files changed, 87 insertions(+), 14 deletions(-) diff --git a/README.org b/README.org index 03031fe..bb2a309 100644 --- a/README.org +++ b/README.org @@ -4,10 +4,6 @@ Take a look at [[https://niklasfasching.github.io/go-org/][github pages]] for so * next - test against [[https://raw.githubusercontent.com/kaushalmodi/ox-hugo/master/test/site/content-org/all-posts.org][ox-hugo all-posts.org]] - ATTR_HTML without printing child - i.e. above other, non-affiliated keyword - - blocks with indent < their parent - #+BEGIN_SRC -> this - #+END_SRC - more keywords: https://orgmode.org/manual/In_002dbuffer-settings.html - headlines - unique ids diff --git a/org/block.go b/org/block.go index 6ba264f..be6b9b6 100644 --- a/org/block.go +++ b/org/block.go @@ -31,24 +31,24 @@ func (d *Document) parseBlock(i int, parentStop stopFn) (int, Node) { name, parameters := t.content, strings.Fields(t.matches[3]) trim := trimIndentUpTo(d.tokens[i].lvl) stop := func(d *Document, i int) bool { - return parentStop(d, i) || (d.tokens[i].kind == "endBlock" && d.tokens[i].content == name) + return i >= len(d.tokens) || (d.tokens[i].kind == "endBlock" && d.tokens[i].content == name) } - block, consumed, i := Block{name, parameters, nil}, 0, i+1 + block, i := Block{name, parameters, nil}, i+1 if isRawTextBlock(name) { rawText := "" for ; !stop(d, i); i++ { rawText += trim(d.tokens[i].matches[0]) + "\n" } - consumed = i - start block.Children = d.parseRawInline(rawText) } else { - consumed, block.Children = d.parseMany(i, stop) - consumed++ // line with BEGIN + consumed, nodes := d.parseMany(i, stop) + block.Children = nodes + i += consumed } - if parentStop(d, i) { - return 0, nil + if i < len(d.tokens) && d.tokens[i].kind == "endBlock" && d.tokens[i].content == name { + return i + 1 - start, block } - return consumed + 1, block + return 0, nil } func trimIndentUpTo(max int) func(string) string { diff --git a/org/org.go b/org/org.go index ee813c9..070eedc 100644 --- a/org/org.go +++ b/org/org.go @@ -162,8 +162,11 @@ func (w *OrgWriter) writeFootnoteDefinition(f FootnoteDefinition) { } func (w *OrgWriter) writeParagraph(p Paragraph) { - w.writeNodes(p.Children...) - w.WriteString("\n") + content := w.nodesAsString(p.Children...) + if len(content) > 0 && content[0] != '\n' { + w.WriteString(w.indent) + } + w.WriteString(content + "\n") } func (w *OrgWriter) writeExample(e Example) { diff --git a/org/testdata/blocks.html b/org/testdata/blocks.html index d6d5ebd..a5d7a23 100644 --- a/org/testdata/blocks.html +++ b/org/testdata/blocks.html @@ -86,3 +86,41 @@ paragraphs + +

+this unindented line is outside of the list item +

+ diff --git a/org/testdata/blocks.org b/org/testdata/blocks.org index 1ed1c7e..374c0a0 100644 --- a/org/testdata/blocks.org +++ b/org/testdata/blocks.org @@ -48,3 +48,21 @@ blocks can contain other elements like console.log("Hello World!") #+END_EXPORT + +- list item 1 + blocks can contain unindented lines that would normally end a list item + #+BEGIN_EXAMPLE +this line is not indented - if it was outside of a block the list item would end + #+END_EXAMPLE + now we're outside the block again and the following unindented line will be outside of the list item +this unindented line is outside of the list item +- list item 2 + #+BEGIN_SRC + #+BEGIN_EXAMPLE + #+END_SRC + #+END_EXAMPLE + + #+BEGIN_QUOTE + #+BEGIN_EXAMPLE + #+END_QUOTE + #+END_EXAMPLE diff --git a/org/testdata/blocks.pretty_org b/org/testdata/blocks.pretty_org index 1ed1c7e..f32ba8e 100644 --- a/org/testdata/blocks.pretty_org +++ b/org/testdata/blocks.pretty_org @@ -48,3 +48,21 @@ blocks can contain other elements like console.log("Hello World!") #+END_EXPORT + +- list item 1 + blocks can contain unindented lines that would normally end a list item + #+BEGIN_EXAMPLE + this line is not indented - if it was outside of a block the list item would end + #+END_EXAMPLE + now we're outside the block again and the following unindented line will be outside of the list item +this unindented line is outside of the list item +- list item 2 + #+BEGIN_SRC + #+BEGIN_EXAMPLE + #+END_SRC + #+END_EXAMPLE + + #+BEGIN_QUOTE + #+BEGIN_EXAMPLE + #+END_QUOTE + #+END_EXAMPLE