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{
|
||||
lexHeadline,
|
||||
lexDrawer,
|
||||
lexBlock,
|
||||
lexList,
|
||||
lexTable,
|
||||
|
@ -168,6 +169,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 "beginDrawer":
|
||||
consumed, node = d.parseDrawer(i, stop)
|
||||
case "text":
|
||||
consumed, node = d.parseParagraph(i, stop)
|
||||
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 {
|
||||
Lvl int
|
||||
Status string
|
||||
Priority string
|
||||
Title []Node
|
||||
Tags []string
|
||||
Children []Node
|
||||
Lvl int
|
||||
Status string
|
||||
Priority string
|
||||
Properties Node
|
||||
Title []Node
|
||||
Tags []string
|
||||
Children []Node
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
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
|
||||
|
||||
if headline.Lvl == 1 && text == d.Footnotes.Title && d.Footnotes.ExcludeHeading {
|
||||
|
|
|
@ -74,6 +74,8 @@ func (w *HTMLWriter) writeNodes(ns ...Node) {
|
|||
w.writeHeadline(n)
|
||||
case Block:
|
||||
w.writeBlock(n)
|
||||
case Drawer:
|
||||
w.writeDrawer(n)
|
||||
|
||||
case FootnoteDefinition:
|
||||
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) {
|
||||
if k.Key == "HTML" {
|
||||
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)
|
||||
case Block:
|
||||
w.writeBlock(n)
|
||||
case Drawer:
|
||||
w.writeDrawer(n)
|
||||
|
||||
case FootnoteDefinition:
|
||||
w.writeFootnoteDefinition(n)
|
||||
|
@ -127,6 +129,9 @@ func (w *OrgWriter) writeHeadline(h Headline) {
|
|||
if len(h.Children) != 0 {
|
||||
w.WriteString(w.indent)
|
||||
}
|
||||
if h.Properties != nil {
|
||||
w.writeNodes(h.Properties)
|
||||
}
|
||||
w.writeNodes(h.Children...)
|
||||
}
|
||||
|
||||
|
@ -147,6 +152,12 @@ func (w *OrgWriter) writeBlock(b Block) {
|
|||
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) {
|
||||
fs := d.Footnotes
|
||||
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>
|
||||
Headline with TODO status
|
||||
</h1>
|
||||
<p>
|
||||
the <strong>content</strong>
|
||||
</p>
|
||||
<h1>
|
||||
Headline with tags & priority   <span class="tags"><span>foo</span> <span>bar</span></span>
|
||||
</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
|
||||
* TODO [#B] Headline with todo status & priority
|
||||
* 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
|
||||
* TODO [#B] Headline with todo status & priority
|
||||
* 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>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue