diff --git a/org/html.go b/org/html.go
index 7d03e9b..be5a965 100644
--- a/org/html.go
+++ b/org/html.go
@@ -103,6 +103,8 @@ func (w *HTMLWriter) writeNodes(ns ...Node) {
w.writeText(n)
case Emphasis:
w.writeEmphasis(n)
+ case StatisticToken:
+ w.writeStatisticToken(n)
case ExplicitLineBreak:
w.writeExplicitLineBreak(n)
case LineBreak:
@@ -234,6 +236,10 @@ func (w *HTMLWriter) writeEmphasis(e Emphasis) {
w.WriteString(tags[1])
}
+func (w *HTMLWriter) writeStatisticToken(s StatisticToken) {
+ w.WriteString(fmt.Sprintf(`[%s]
`, s.Content))
+}
+
func (w *HTMLWriter) writeLineBreak(l LineBreak) {
w.WriteString(strings.Repeat("\n", l.Count))
}
diff --git a/org/inline.go b/org/inline.go
index 52f2ff7..c040687 100644
--- a/org/inline.go
+++ b/org/inline.go
@@ -15,6 +15,8 @@ type Text struct {
type LineBreak struct{ Count int }
type ExplicitLineBreak struct{}
+type StatisticToken struct{ Content string }
+
type Emphasis struct {
Kind string
Content []Node
@@ -39,6 +41,7 @@ var videoExtensionRegexp = regexp.MustCompile(`^[.](webm|mp4)$`)
var subScriptSuperScriptRegexp = regexp.MustCompile(`([_^])\{(.*?)\}`)
var footnoteRegexp = regexp.MustCompile(`\[fn:([\w-]+?)(:(.*?))?\]`)
+var statisticsTokenRegexp = regexp.MustCompile(`\[(\d+/\d+|\d+%)\]`)
func (d *Document) parseInline(input string) (nodes []Node) {
previous, current := 0, 0
@@ -54,7 +57,7 @@ func (d *Document) parseInline(input string) (nodes []Node) {
case '=', '~':
consumed, node = d.parseEmphasis(input, current, true)
case '[':
- consumed, node = d.parseRegularLinkOrFootnoteReference(input, current)
+ consumed, node = d.parseOpeningBracket(input, current)
case '\\':
consumed, node = d.parseExplicitLineBreak(input, current)
case '\n':
@@ -140,11 +143,13 @@ func (d *Document) parseSubScriptOrEmphasis(input string, start int) (int, Node)
return d.parseEmphasis(input, start, false)
}
-func (d *Document) parseRegularLinkOrFootnoteReference(input string, start int) (int, Node) {
+func (d *Document) parseOpeningBracket(input string, start int) (int, Node) {
if len(input[start:]) >= 2 && input[start] == '[' && input[start+1] == '[' {
return d.parseRegularLink(input, start)
- } else if len(input[start:]) >= 1 && input[start] == '[' {
+ } else if footnoteRegexp.MatchString(input[start:]) {
return d.parseFootnoteReference(input, start)
+ } else if statisticsTokenRegexp.MatchString(input[start:]) {
+ return d.parseStatisticToken(input, start)
}
return 0, nil
}
@@ -162,6 +167,13 @@ func (d *Document) parseFootnoteReference(input string, start int) (int, Node) {
return 0, nil
}
+func (d *Document) parseStatisticToken(input string, start int) (int, Node) {
+ if m := statisticsTokenRegexp.FindStringSubmatch(input[start:]); m != nil {
+ return len(m[1]) + 2, StatisticToken{m[1]}
+ }
+ return 0, nil
+}
+
func (d *Document) parseAutoLink(input string, start int) (int, int, Node) {
if !d.AutoLink || len(input[start:]) < 3 || input[start+1] != '/' || input[start+2] != '/' {
return 0, 0, nil
diff --git a/org/org.go b/org/org.go
index ad82a65..386ea6e 100644
--- a/org/org.go
+++ b/org/org.go
@@ -86,6 +86,8 @@ func (w *OrgWriter) writeNodes(ns ...Node) {
w.writeText(n)
case Emphasis:
w.writeEmphasis(n)
+ case StatisticToken:
+ w.writeStatisticToken(n)
case LineBreak:
w.writeLineBreak(n)
case ExplicitLineBreak:
@@ -285,6 +287,10 @@ func (w *OrgWriter) writeEmphasis(e Emphasis) {
w.WriteString(borders[1])
}
+func (w *OrgWriter) writeStatisticToken(s StatisticToken) {
+ w.WriteString(fmt.Sprintf("[%s]", s.Content))
+}
+
func (w *OrgWriter) writeLineBreak(l LineBreak) {
w.WriteString(strings.Repeat("\n"+w.indent, l.Count))
}
diff --git a/org/testdata/headlines.html b/org/testdata/headlines.html
index 75bfff7..ef0c3b8 100644
--- a/org/testdata/headlines.html
+++ b/org/testdata/headlines.html
@@ -1,6 +1,25 @@
[1/2]
+[X] checked +
++[ ] unchecked +
+
+note that statistic tokens are marked up anywhere
+not just where they are actually meant to be - even here > [100%]
<
+(Org mode proper does the same)
+
-* Simple Headline
+* Simple Headline [1/2]
+- [X] checked
+- [ ] unchecked
+- note that statistic tokens are marked up anywhere
+ not just where they are actually meant to be - even here > [100%] <
+ (Org mode proper does the same)
* TODO [#B] Headline with todo status & priority
* DONE Headline with TODO status
:PROPERTIES: