From f6f4646d45d1425b8e6d494847ec732d39f97279 Mon Sep 17 00:00:00 2001 From: Niklas Fasching Date: Thu, 16 Apr 2020 17:28:49 +0200 Subject: [PATCH] Implement result blocks --- org/block.go | 18 ++++++++++++++++++ org/document.go | 3 +++ org/html_writer.go | 2 ++ org/org_writer.go | 5 +++++ org/testdata/blocks.html | 13 +++++++++++++ org/testdata/blocks.org | 11 +++++++++++ org/testdata/blocks.pretty_org | 11 +++++++++++ org/writer.go | 3 +++ 8 files changed, 66 insertions(+) diff --git a/org/block.go b/org/block.go index 4b88439..46d031d 100644 --- a/org/block.go +++ b/org/block.go @@ -12,6 +12,10 @@ type Block struct { Children []Node } +type Result struct { + Node Node +} + type Example struct { Children []Node } @@ -19,6 +23,7 @@ type Example struct { var exampleLineRegexp = regexp.MustCompile(`^(\s*):(\s(.*)|\s*$)`) var beginBlockRegexp = regexp.MustCompile(`(?i)^(\s*)#\+BEGIN_(\w+)(.*)`) var endBlockRegexp = regexp.MustCompile(`(?i)^(\s*)#\+END_(\w+)`) +var resultRegexp = regexp.MustCompile(`(?i)^(\s*)#\+RESULTS:`) var exampleBlockEscapeRegexp = regexp.MustCompile(`(^|\n)([ \t]*),([ \t]*)(\*|,\*|#\+|,#\+)`) func lexBlock(line string) (token, bool) { @@ -30,6 +35,13 @@ func lexBlock(line string) (token, bool) { return nilToken, false } +func lexResult(line string) (token, bool) { + if m := resultRegexp.FindStringSubmatch(line); m != nil { + return token{"result", len(m[1]), "", m}, true + } + return nilToken, false +} + func lexExample(line string) (token, bool) { if m := exampleLineRegexp.FindStringSubmatch(line); m != nil { return token{"example", len(m[1]), m[3], m}, true @@ -75,6 +87,11 @@ func (d *Document) parseExample(i int, parentStop stopFn) (int, Node) { return i - start, example } +func (d *Document) parseResult(i int, parentStop stopFn) (int, Node) { + consumed, node := d.parseOne(i+1, parentStop) + return consumed + 1, Result{node} +} + func trimIndentUpTo(max int) func(string) string { return func(line string) string { i := 0 @@ -86,3 +103,4 @@ func trimIndentUpTo(max int) func(string) string { func (n Example) String() string { return orgWriter.WriteNodesAsString(n) } func (n Block) String() string { return orgWriter.WriteNodesAsString(n) } +func (n Result) String() string { return orgWriter.WriteNodesAsString(n) } diff --git a/org/document.go b/org/document.go index acdd5c4..f7efb14 100644 --- a/org/document.go +++ b/org/document.go @@ -63,6 +63,7 @@ var lexFns = []lexFn{ lexHeadline, lexDrawer, lexBlock, + lexResult, lexList, lexTable, lexHorizontalRule, @@ -202,6 +203,8 @@ func (d *Document) parseOne(i int, stop stopFn) (consumed int, node Node) { consumed, node = d.parseTable(i, stop) case "beginBlock": consumed, node = d.parseBlock(i, stop) + case "result": + consumed, node = d.parseResult(i, stop) case "beginDrawer": consumed, node = d.parseDrawer(i, stop) case "text": diff --git a/org/html_writer.go b/org/html_writer.go index 1a12b8b..e9871cf 100644 --- a/org/html_writer.go +++ b/org/html_writer.go @@ -136,6 +136,8 @@ func (w *HTMLWriter) WriteBlock(b Block) { } } +func (w *HTMLWriter) WriteResult(r Result) { WriteNodes(w, r.Node) } + func (w *HTMLWriter) WriteInlineBlock(b InlineBlock) { content := w.blockContent(strings.ToUpper(b.Name), b.Children) switch b.Name { diff --git a/org/org_writer.go b/org/org_writer.go index a59461d..cd41e0c 100644 --- a/org/org_writer.go +++ b/org/org_writer.go @@ -104,6 +104,11 @@ func (w *OrgWriter) WriteBlock(b Block) { w.WriteString("#+END_" + b.Name + "\n") } +func (w *OrgWriter) WriteResult(r Result) { + w.WriteString("#+RESULTS:\n") + WriteNodes(w, r.Node) +} + func (w *OrgWriter) WriteInlineBlock(b InlineBlock) { switch b.Name { case "src": diff --git a/org/testdata/blocks.html b/org/testdata/blocks.html index 48b7245..1e801cf 100644 --- a/org/testdata/blocks.html +++ b/org/testdata/blocks.html @@ -1,3 +1,6 @@ +
+some results without a block
+
@@ -23,6 +26,16 @@ a source block without a language
+
+
+
+echo a source block with results
+
+
+
+
+a source block with results
+
 an example block with
 multiple lines including
diff --git a/org/testdata/blocks.org b/org/testdata/blocks.org
index a5b24f5..7667c23 100644
--- a/org/testdata/blocks.org
+++ b/org/testdata/blocks.org
@@ -1,3 +1,6 @@
+#+RESULTS:
+: some results without a block
+
 #+CAPTION: block caption
 #+BEGIN_SRC bash :results raw
 echo "a bash source block"
@@ -13,6 +16,14 @@ hello
 a source block without a language
 #+END_SRC
 
+
+#+BEGIN_SRC bash
+echo a source block with results
+#+END_SRC
+
+#+RESULTS:
+: a source block with results
+
 #+BEGIN_EXAMPLE foo bar baz
 an example block with
 multiple lines including
diff --git a/org/testdata/blocks.pretty_org b/org/testdata/blocks.pretty_org
index 8623988..ce4d5b9 100644
--- a/org/testdata/blocks.pretty_org
+++ b/org/testdata/blocks.pretty_org
@@ -1,3 +1,6 @@
+#+RESULTS:
+: some results without a block
+
 #+CAPTION: block caption
 #+BEGIN_SRC bash :results raw
 echo "a bash source block"
@@ -13,6 +16,14 @@ hello
 a source block without a language
 #+END_SRC
 
+
+#+BEGIN_SRC bash
+echo a source block with results
+#+END_SRC
+
+#+RESULTS:
+: a source block with results
+
 #+BEGIN_EXAMPLE foo bar baz
 an example block with
 multiple lines including
diff --git a/org/writer.go b/org/writer.go
index c84ce9f..9a50237 100644
--- a/org/writer.go
+++ b/org/writer.go
@@ -18,6 +18,7 @@ type Writer interface {
 	WriteNodeWithName(NodeWithName)
 	WriteHeadline(Headline)
 	WriteBlock(Block)
+	WriteResult(Result)
 	WriteInlineBlock(InlineBlock)
 	WriteExample(Example)
 	WriteDrawer(Drawer)
@@ -58,6 +59,8 @@ func WriteNodes(w Writer, nodes ...Node) {
 			w.WriteHeadline(n)
 		case Block:
 			w.WriteBlock(n)
+		case Result:
+			w.WriteResult(n)
 		case InlineBlock:
 			w.WriteInlineBlock(n)
 		case Example: