diff --git a/org/block.go b/org/block.go
index 9793f81..2f30a7a 100644
--- a/org/block.go
+++ b/org/block.go
@@ -1,6 +1,7 @@
package org
import (
+ "math"
"regexp"
"strings"
"unicode"
@@ -21,9 +22,15 @@ type Example struct {
Children []Node
}
+type LatexBlock struct {
+ Content []Node
+}
+
var exampleLineRegexp = regexp.MustCompile(`^(\s*):(\s(.*)|\s*$)`)
var beginBlockRegexp = regexp.MustCompile(`(?i)^(\s*)#\+BEGIN_(\w+)(.*)`)
var endBlockRegexp = regexp.MustCompile(`(?i)^(\s*)#\+END_(\w+)`)
+var beginLatexBlockRegexp = regexp.MustCompile(`(?i)^(\s*)\\begin{([^}]+)}(\s*)$`)
+var endLatexBlockRegexp = regexp.MustCompile(`(?i)^(\s*)\\end{([^}]+)}(\s*)$`)
var resultRegexp = regexp.MustCompile(`(?i)^(\s*)#\+RESULTS:`)
var exampleBlockEscapeRegexp = regexp.MustCompile(`(^|\n)([ \t]*),([ \t]*)(\*|,\*|#\+|,#\+)`)
@@ -36,6 +43,15 @@ func lexBlock(line string) (token, bool) {
return nilToken, false
}
+func lexLatexBlock(line string) (token, bool) {
+ if m := beginLatexBlockRegexp.FindStringSubmatch(line); m != nil {
+ return token{"beginLatexBlock", len(m[1]), strings.ToUpper(m[2]), m}, true
+ } else if m := endLatexBlockRegexp.FindStringSubmatch(line); m != nil {
+ return token{"endLatexBlock", len(m[1]), strings.ToUpper(m[2]), m}, true
+ }
+ return nilToken, false
+}
+
func lexResult(line string) (token, bool) {
if m := resultRegexp.FindStringSubmatch(line); m != nil {
return token{"result", len(m[1]), "", m}, true
@@ -85,6 +101,22 @@ func (d *Document) parseBlock(i int, parentStop stopFn) (int, Node) {
return i + 1 - start, block
}
+func (d *Document) parseLatexBlock(i int, parentStop stopFn) (int, Node) {
+ t, start := d.tokens[i], i
+ name, rawText, trim := t.content, "", trimIndentUpTo(int(math.Max((float64(d.baseLvl)), float64(t.lvl))))
+ stop := func(d *Document, i int) bool {
+ return i >= len(d.tokens) || (d.tokens[i].kind == "endLatexBlock" && d.tokens[i].content == name)
+ }
+ for ; !stop(d, i); i++ {
+ rawText += trim(d.tokens[i].matches[0]) + "\n"
+ }
+ if i >= len(d.tokens) || d.tokens[i].kind != "endLatexBlock" || d.tokens[i].content != name {
+ return 0, nil
+ }
+ rawText += trim(d.tokens[i].matches[0])
+ return i + 1 - start, LatexBlock{d.parseRawInline(rawText)}
+}
+
func (d *Document) parseSrcBlockResult(i int, parentStop stopFn) (int, Node) {
start := i
for ; !parentStop(d, i) && d.tokens[i].kind == "text" && d.tokens[i].content == ""; i++ {
@@ -145,6 +177,7 @@ func (b Block) ParameterMap() map[string]string {
return m
}
-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) }
+func (n Example) String() string { return orgWriter.WriteNodesAsString(n) }
+func (n Block) String() string { return orgWriter.WriteNodesAsString(n) }
+func (n LatexBlock) 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 755864b..9da27b9 100644
--- a/org/document.go
+++ b/org/document.go
@@ -72,6 +72,7 @@ var lexFns = []lexFn{
lexKeywordOrComment,
lexFootnoteDefinition,
lexExample,
+ lexLatexBlock,
lexText,
}
@@ -209,6 +210,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 "beginLatexBlock":
+ consumed, node = d.parseLatexBlock(i, stop)
case "result":
consumed, node = d.parseResult(i, stop)
case "beginDrawer":
diff --git a/org/html_writer.go b/org/html_writer.go
index 28c402c..5918af6 100644
--- a/org/html_writer.go
+++ b/org/html_writer.go
@@ -162,6 +162,11 @@ func (w *HTMLWriter) WriteBlock(b Block) {
}
}
+func (w *HTMLWriter) WriteLatexBlock(b LatexBlock) {
+ WriteNodes(w, b.Content...)
+ w.WriteString("\n")
+}
+
func (w *HTMLWriter) WriteResult(r Result) { WriteNodes(w, r.Node) }
func (w *HTMLWriter) WriteInlineBlock(b InlineBlock) {
diff --git a/org/org_writer.go b/org/org_writer.go
index 0cfaead..fce6d20 100644
--- a/org/org_writer.go
+++ b/org/org_writer.go
@@ -109,6 +109,12 @@ func (w *OrgWriter) WriteBlock(b Block) {
}
}
+func (w *OrgWriter) WriteLatexBlock(b LatexBlock) {
+ w.WriteString(w.indent)
+ WriteNodes(w, b.Content...)
+ w.WriteString("\n")
+}
+
func (w *OrgWriter) WriteResult(r Result) {
w.WriteString("#+RESULTS:\n")
WriteNodes(w, r.Node)
diff --git a/org/testdata/latex.html b/org/testdata/latex.html
index 58bbb8a..8659467 100644
--- a/org/testdata/latex.html
+++ b/org/testdata/latex.html
@@ -6,8 +6,18 @@ we support \(...\)
, \[...\]
\[\sum_{i=1}^n a_n\]
$$\sum_{i=1}^n a_n$$
\begin{xyz}\sum_{i=1}^n a_n\end{xyz}
-\begin{xyz}
+
+\begin{xyz}
\sum_{i=1}^n a_n
-\end{xyz}
+\end{xyz}
+
$2 + 2$, $3 - 3$
+
+\begin{xyz}
+latex block ignores block lvl elements (e.g. list - line starting with -)
+a = b
+- c
+- d
+\end{xyz}
+
diff --git a/org/testdata/latex.org b/org/testdata/latex.org
index 5a4c953..534d026 100644
--- a/org/testdata/latex.org
+++ b/org/testdata/latex.org
@@ -10,3 +10,9 @@ we support =\(...\)=, =\[...\]=, =$$...$$= and =\begin{$env}...\end{$env}= as la
\sum_{i=1}^n a_n
\end{xyz}
- $2 + 2$, $3 - 3$
+- \begin{xyz}
+ latex block ignores block lvl elements (e.g. list - line starting with -)
+ a = b
+ - c
+ - d
+ \end{xyz}
diff --git a/org/testdata/latex.pretty_org b/org/testdata/latex.pretty_org
index 5a4c953..534d026 100644
--- a/org/testdata/latex.pretty_org
+++ b/org/testdata/latex.pretty_org
@@ -10,3 +10,9 @@ we support =\(...\)=, =\[...\]=, =$$...$$= and =\begin{$env}...\end{$env}= as la
\sum_{i=1}^n a_n
\end{xyz}
- $2 + 2$, $3 - 3$
+- \begin{xyz}
+ latex block ignores block lvl elements (e.g. list - line starting with -)
+ a = b
+ - c
+ - d
+ \end{xyz}
diff --git a/org/writer.go b/org/writer.go
index 29b64bd..fb918e8 100644
--- a/org/writer.go
+++ b/org/writer.go
@@ -19,6 +19,7 @@ type Writer interface {
WriteHeadline(Headline)
WriteBlock(Block)
WriteResult(Result)
+ WriteLatexBlock(LatexBlock)
WriteInlineBlock(InlineBlock)
WriteExample(Example)
WriteDrawer(Drawer)
@@ -62,6 +63,8 @@ func WriteNodes(w Writer, nodes ...Node) {
w.WriteBlock(n)
case Result:
w.WriteResult(n)
+ case LatexBlock:
+ w.WriteLatexBlock(n)
case InlineBlock:
w.WriteInlineBlock(n)
case Example: