Add basic support for drawers
This commit is contained in:
parent
c012b0a533
commit
0186545123
8 changed files with 102 additions and 8 deletions
|
@ -43,6 +43,7 @@ type token struct {
|
||||||
|
|
||||||
var lexFns = []lexFn{
|
var lexFns = []lexFn{
|
||||||
lexHeadline,
|
lexHeadline,
|
||||||
|
lexDrawer,
|
||||||
lexBlock,
|
lexBlock,
|
||||||
lexList,
|
lexList,
|
||||||
lexTable,
|
lexTable,
|
||||||
|
@ -168,6 +169,8 @@ func (d *Document) parseOne(i int, stop stopFn) (consumed int, node Node) {
|
||||||
consumed, node = d.parseTable(i, stop)
|
consumed, node = d.parseTable(i, stop)
|
||||||
case "beginBlock":
|
case "beginBlock":
|
||||||
consumed, node = d.parseBlock(i, stop)
|
consumed, node = d.parseBlock(i, stop)
|
||||||
|
case "beginDrawer":
|
||||||
|
consumed, node = d.parseDrawer(i, stop)
|
||||||
case "text":
|
case "text":
|
||||||
consumed, node = d.parseParagraph(i, stop)
|
consumed, node = d.parseParagraph(i, stop)
|
||||||
case "example":
|
case "example":
|
||||||
|
|
37
org/drawer.go
Normal file
37
org/drawer.go
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
package org
|
||||||
|
|
||||||
|
import (
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Drawer struct {
|
||||||
|
Name string
|
||||||
|
Children []Node
|
||||||
|
}
|
||||||
|
|
||||||
|
var beginDrawerRegexp = regexp.MustCompile(`^(\s*):(\S+):\s*$`)
|
||||||
|
var endDrawerRegexp = regexp.MustCompile(`^(\s*):END:\s*$`)
|
||||||
|
|
||||||
|
func lexDrawer(line string) (token, bool) {
|
||||||
|
if m := endDrawerRegexp.FindStringSubmatch(line); m != nil {
|
||||||
|
return token{"endDrawer", len(m[1]), "", m}, true
|
||||||
|
} else if m := beginDrawerRegexp.FindStringSubmatch(line); m != nil {
|
||||||
|
return token{"beginDrawer", len(m[1]), strings.ToUpper(m[2]), m}, true
|
||||||
|
}
|
||||||
|
return nilToken, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Document) parseDrawer(i int, parentStop stopFn) (int, Node) {
|
||||||
|
drawer, start := Drawer{Name: strings.ToUpper(d.tokens[i].content)}, i
|
||||||
|
i++
|
||||||
|
stop := func(d *Document, i int) bool {
|
||||||
|
return parentStop(d, i) || d.tokens[i].kind == "endDrawer" || d.tokens[i].kind == "headline"
|
||||||
|
}
|
||||||
|
consumed, nodes := d.parseMany(i, stop)
|
||||||
|
drawer.Children = nodes
|
||||||
|
if d.tokens[i+consumed].kind == "endDrawer" {
|
||||||
|
consumed++
|
||||||
|
}
|
||||||
|
return i + consumed - start, drawer
|
||||||
|
}
|
|
@ -7,12 +7,13 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Headline struct {
|
type Headline struct {
|
||||||
Lvl int
|
Lvl int
|
||||||
Status string
|
Status string
|
||||||
Priority string
|
Priority string
|
||||||
Title []Node
|
Properties Node
|
||||||
Tags []string
|
Title []Node
|
||||||
Children []Node
|
Tags []string
|
||||||
|
Children []Node
|
||||||
}
|
}
|
||||||
|
|
||||||
var headlineRegexp = regexp.MustCompile(`^([*]+)\s+(.*)`)
|
var headlineRegexp = regexp.MustCompile(`^([*]+)\s+(.*)`)
|
||||||
|
@ -60,6 +61,12 @@ func (d *Document) parseHeadline(i int, parentStop stopFn) (int, Node) {
|
||||||
return parentStop(d, i) || d.tokens[i].kind == "headline" && d.tokens[i].lvl <= headline.Lvl
|
return parentStop(d, i) || d.tokens[i].kind == "headline" && d.tokens[i].lvl <= headline.Lvl
|
||||||
}
|
}
|
||||||
consumed, nodes := d.parseMany(i+1, stop)
|
consumed, nodes := d.parseMany(i+1, stop)
|
||||||
|
if len(nodes) > 0 {
|
||||||
|
if d, ok := nodes[0].(Drawer); ok && d.Name == "PROPERTIES" {
|
||||||
|
headline.Properties = d
|
||||||
|
nodes = nodes[1:]
|
||||||
|
}
|
||||||
|
}
|
||||||
headline.Children = nodes
|
headline.Children = nodes
|
||||||
|
|
||||||
if headline.Lvl == 1 && text == d.Footnotes.Title && d.Footnotes.ExcludeHeading {
|
if headline.Lvl == 1 && text == d.Footnotes.Title && d.Footnotes.ExcludeHeading {
|
||||||
|
|
|
@ -74,6 +74,8 @@ func (w *HTMLWriter) writeNodes(ns ...Node) {
|
||||||
w.writeHeadline(n)
|
w.writeHeadline(n)
|
||||||
case Block:
|
case Block:
|
||||||
w.writeBlock(n)
|
w.writeBlock(n)
|
||||||
|
case Drawer:
|
||||||
|
w.writeDrawer(n)
|
||||||
|
|
||||||
case FootnoteDefinition:
|
case FootnoteDefinition:
|
||||||
w.writeFootnoteDefinition(n)
|
w.writeFootnoteDefinition(n)
|
||||||
|
@ -141,6 +143,10 @@ func (w *HTMLWriter) writeBlock(b Block) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *HTMLWriter) writeDrawer(d Drawer) {
|
||||||
|
w.writeNodes(d.Children...)
|
||||||
|
}
|
||||||
|
|
||||||
func (w *HTMLWriter) writeKeyword(k Keyword) {
|
func (w *HTMLWriter) writeKeyword(k Keyword) {
|
||||||
if k.Key == "HTML" {
|
if k.Key == "HTML" {
|
||||||
w.WriteString(k.Value + "\n")
|
w.WriteString(k.Value + "\n")
|
||||||
|
|
11
org/org.go
11
org/org.go
|
@ -62,6 +62,8 @@ func (w *OrgWriter) writeNodes(ns ...Node) {
|
||||||
w.writeHeadline(n)
|
w.writeHeadline(n)
|
||||||
case Block:
|
case Block:
|
||||||
w.writeBlock(n)
|
w.writeBlock(n)
|
||||||
|
case Drawer:
|
||||||
|
w.writeDrawer(n)
|
||||||
|
|
||||||
case FootnoteDefinition:
|
case FootnoteDefinition:
|
||||||
w.writeFootnoteDefinition(n)
|
w.writeFootnoteDefinition(n)
|
||||||
|
@ -127,6 +129,9 @@ func (w *OrgWriter) writeHeadline(h Headline) {
|
||||||
if len(h.Children) != 0 {
|
if len(h.Children) != 0 {
|
||||||
w.WriteString(w.indent)
|
w.WriteString(w.indent)
|
||||||
}
|
}
|
||||||
|
if h.Properties != nil {
|
||||||
|
w.writeNodes(h.Properties)
|
||||||
|
}
|
||||||
w.writeNodes(h.Children...)
|
w.writeNodes(h.Children...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,6 +152,12 @@ func (w *OrgWriter) writeBlock(b Block) {
|
||||||
w.WriteString(w.indent + "#+END_" + b.Name + "\n")
|
w.WriteString(w.indent + "#+END_" + b.Name + "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *OrgWriter) writeDrawer(d Drawer) {
|
||||||
|
w.WriteString(w.indent + ":" + d.Name + ":\n")
|
||||||
|
w.writeNodes(d.Children...)
|
||||||
|
w.WriteString(w.indent + ":END:\n")
|
||||||
|
}
|
||||||
|
|
||||||
func (w *OrgWriter) writeFootnotes(d *Document) {
|
func (w *OrgWriter) writeFootnotes(d *Document) {
|
||||||
fs := d.Footnotes
|
fs := d.Footnotes
|
||||||
if len(fs.Definitions) == 0 {
|
if len(fs.Definitions) == 0 {
|
||||||
|
|
12
org/testdata/headlines.html
vendored
12
org/testdata/headlines.html
vendored
|
@ -9,6 +9,18 @@ Headline with todo status & priority
|
||||||
<span class="todo">DONE</span>
|
<span class="todo">DONE</span>
|
||||||
Headline with TODO status
|
Headline with TODO status
|
||||||
</h1>
|
</h1>
|
||||||
|
<p>
|
||||||
|
the <strong>content</strong>
|
||||||
|
</p>
|
||||||
<h1>
|
<h1>
|
||||||
Headline with tags & priority   <span class="tags"><span>foo</span> <span>bar</span></span>
|
Headline with tags & priority   <span class="tags"><span>foo</span> <span>bar</span></span>
|
||||||
</h1>
|
</h1>
|
||||||
|
<p>
|
||||||
|
Still outside the drawer
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
This is inside the drawer
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Still outside the drawer
|
||||||
|
</p>
|
||||||
|
|
11
org/testdata/headlines.org
vendored
11
org/testdata/headlines.org
vendored
|
@ -1,5 +1,14 @@
|
||||||
* Simple Headline
|
* Simple Headline
|
||||||
* TODO [#B] Headline with todo status & priority
|
* TODO [#B] Headline with todo status & priority
|
||||||
* DONE Headline with TODO status
|
* DONE Headline with TODO status
|
||||||
* [#A] Headline with tags & priority :foo:bar:
|
:PROPERTIES:
|
||||||
|
:Note: property drawers are not exported as html like other drawers
|
||||||
|
:END:
|
||||||
|
|
||||||
|
the *content*
|
||||||
|
* [#A] Headline with tags & priority :foo:bar:
|
||||||
|
Still outside the drawer
|
||||||
|
:DRAWERNAME:
|
||||||
|
This is inside the drawer
|
||||||
|
:END:
|
||||||
|
Still outside the drawer
|
||||||
|
|
11
org/testdata/misc.html
vendored
11
org/testdata/misc.html
vendored
|
@ -46,8 +46,17 @@ src block
|
||||||
* Simple Headline
|
* Simple Headline
|
||||||
* TODO [#B] Headline with todo status & priority
|
* TODO [#B] Headline with todo status & priority
|
||||||
* DONE Headline with TODO status
|
* DONE Headline with TODO status
|
||||||
* [#A] Headline with tags & priority :foo:bar:
|
:PROPERTIES:
|
||||||
|
:Note: property drawers are not exported as html like other drawers
|
||||||
|
:END:
|
||||||
|
|
||||||
|
the *content*
|
||||||
|
* [#A] Headline with tags & priority :foo:bar:
|
||||||
|
Still outside the drawer
|
||||||
|
:DRAWERNAME:
|
||||||
|
This is inside the drawer
|
||||||
|
:END:
|
||||||
|
Still outside the drawer
|
||||||
|
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue