From 20970ec872e8c2a4491b3b44f2df502c51ea043a Mon Sep 17 00:00:00 2001 From: Niklas Fasching Date: Sun, 27 Oct 2019 15:04:55 +0100 Subject: [PATCH] Add support for NAME keyword --- org/document.go | 2 ++ org/html_writer.go | 4 ++++ org/keyword.go | 24 ++++++++++++++++++++++-- org/org_writer.go | 5 +++++ org/testdata/keywords.html | 10 ++++++++++ org/testdata/keywords.org | 8 ++++++++ org/testdata/keywords.pretty_org | 8 ++++++++ org/writer.go | 5 ++++- 8 files changed, 63 insertions(+), 3 deletions(-) diff --git a/org/document.go b/org/document.go index a8f6201..e43eb62 100644 --- a/org/document.go +++ b/org/document.go @@ -36,6 +36,7 @@ type Document struct { Path string // Path of the file containing the parse input - used to resolve relative paths during parsing (e.g. INCLUDE). tokens []token Nodes []Node + NamedNodes map[string]Node Outline Outline // Outline is a Table Of Contents for the document and contains all sections (headline + content). BufferSettings map[string]string // Settings contains all settings that were parsed from keywords. Error error @@ -117,6 +118,7 @@ func (c *Configuration) Parse(input io.Reader, path string) (d *Document) { Configuration: c, Outline: Outline{outlineSection, outlineSection, 0}, BufferSettings: map[string]string{}, + NamedNodes: map[string]Node{}, Path: path, } defer func() { diff --git a/org/html_writer.go b/org/html_writer.go index e8bc1e4..eb88b28 100644 --- a/org/html_writer.go +++ b/org/html_writer.go @@ -397,6 +397,10 @@ func (w *HTMLWriter) WriteNodeWithMeta(n NodeWithMeta) { w.WriteString(out) } +func (w *HTMLWriter) WriteNodeWithName(n NodeWithName) { + WriteNodes(w, n.Node) +} + func (w *HTMLWriter) WriteTable(t Table) { w.WriteString("\n") beforeFirstContentRow := true diff --git a/org/keyword.go b/org/keyword.go index 6909630..7762417 100644 --- a/org/keyword.go +++ b/org/keyword.go @@ -14,6 +14,11 @@ type Keyword struct { Value string } +type NodeWithName struct { + Name string + Node Node +} + type NodeWithMeta struct { Node Node Meta Metadata @@ -51,10 +56,12 @@ func (d *Document) parseComment(i int, stop stopFn) (int, Node) { func (d *Document) parseKeyword(i int, stop stopFn) (int, Node) { k := parseKeyword(d.tokens[i]) switch k.Key { + case "NAME": + return d.parseNodeWithName(k, i, stop) case "SETUPFILE": return d.loadSetupFile(k) case "INCLUDE": - return d.newInclude(k) + return d.parseInclude(k) case "CAPTION", "ATTR_HTML": consumed, node := d.parseAffiliated(i, stop) if consumed != 0 { @@ -71,6 +78,18 @@ func (d *Document) parseKeyword(i int, stop stopFn) (int, Node) { } } +func (d *Document) parseNodeWithName(k Keyword, i int, stop stopFn) (int, Node) { + if stop(d, i+1) { + return 0, nil + } + consumed, node := d.parseOne(i+1, stop) + if consumed == 0 || node == nil { + return 0, nil + } + d.NamedNodes[k.Value] = node + return consumed + 1, NodeWithName{k.Value, node} +} + func (d *Document) parseAffiliated(i int, stop stopFn) (int, Node) { start, meta := i, Metadata{} for ; !stop(d, i) && d.tokens[i].kind == "keyword"; i++ { @@ -115,7 +134,7 @@ func parseKeyword(t token) Keyword { return Keyword{strings.ToUpper(k), strings.TrimSpace(v)} } -func (d *Document) newInclude(k Keyword) (int, Node) { +func (d *Document) parseInclude(k Keyword) (int, Node) { resolve := func() Node { d.Log.Printf("Bad include %#v", k) return k @@ -161,4 +180,5 @@ func (d *Document) loadSetupFile(k Keyword) (int, Node) { func (n Comment) String() string { return orgWriter.nodesAsString(n) } func (n Keyword) String() string { return orgWriter.nodesAsString(n) } func (n NodeWithMeta) String() string { return orgWriter.nodesAsString(n) } +func (n NodeWithName) String() string { return orgWriter.nodesAsString(n) } func (n Include) String() string { return orgWriter.nodesAsString(n) } diff --git a/org/org_writer.go b/org/org_writer.go index 9312fea..1abff16 100644 --- a/org/org_writer.go +++ b/org/org_writer.go @@ -164,6 +164,11 @@ func (w *OrgWriter) WriteNodeWithMeta(n NodeWithMeta) { WriteNodes(w, n.Node) } +func (w *OrgWriter) WriteNodeWithName(n NodeWithName) { + w.WriteString(fmt.Sprintf("#+NAME: %s\n", n.Name)) + WriteNodes(w, n.Node) +} + func (w *OrgWriter) WriteComment(c Comment) { w.WriteString(w.indent + "#" + c.Content + "\n") } diff --git a/org/testdata/keywords.html b/org/testdata/keywords.html index 351df78..050d403 100644 --- a/org/testdata/keywords.html +++ b/org/testdata/keywords.html @@ -18,3 +18,13 @@ and an image with custom html attributes and a caption kittens! +

+named paragraph +

+
+
+
+named block
+
+
+
diff --git a/org/testdata/keywords.org b/org/testdata/keywords.org index e6b8ce9..440949d 100644 --- a/org/testdata/keywords.org +++ b/org/testdata/keywords.org @@ -12,3 +12,11 @@ and an image with custom html attributes and a caption #+ATTR_HTML: :style height: 100%; :id overwritten #+ATTR_HTML: :style border: 10px solid black; :id kittens [[https://placekitten.com/200/200#.png]] + +#+NAME: foo +named paragraph + +#+NAME: bar +#+begin_src +named block +#+end_src diff --git a/org/testdata/keywords.pretty_org b/org/testdata/keywords.pretty_org index e6b8ce9..7b0bf23 100644 --- a/org/testdata/keywords.pretty_org +++ b/org/testdata/keywords.pretty_org @@ -12,3 +12,11 @@ and an image with custom html attributes and a caption #+ATTR_HTML: :style height: 100%; :id overwritten #+ATTR_HTML: :style border: 10px solid black; :id kittens [[https://placekitten.com/200/200#.png]] + +#+NAME: foo +named paragraph + +#+NAME: bar +#+BEGIN_SRC +named block +#+END_SRC diff --git a/org/writer.go b/org/writer.go index 005b27f..d3f622e 100644 --- a/org/writer.go +++ b/org/writer.go @@ -12,6 +12,7 @@ type Writer interface { WriteInclude(Include) WriteComment(Comment) WriteNodeWithMeta(NodeWithMeta) + WriteNodeWithName(NodeWithName) WriteHeadline(Headline) WriteBlock(Block) WriteExample(Example) @@ -46,6 +47,8 @@ func WriteNodes(w Writer, nodes ...Node) { w.WriteComment(n) case NodeWithMeta: w.WriteNodeWithMeta(n) + case NodeWithName: + w.WriteNodeWithName(n) case Headline: w.WriteHeadline(n) case Block: @@ -90,7 +93,7 @@ func WriteNodes(w Writer, nodes ...Node) { w.WriteFootnoteDefinition(n) default: if n != nil { - panic(fmt.Sprintf("bad node %#v", n)) + panic(fmt.Sprintf("bad node %T %#v", n, n)) } } }