Add support for some #+OPTIONS toggles
see https://orgmode.org/manual/Export-settings.html
This commit is contained in:
parent
5c51067b59
commit
d036ddea4d
5 changed files with 120 additions and 9 deletions
|
@ -85,6 +85,7 @@ func NewDocument() *Document {
|
||||||
DefaultSettings: map[string]string{
|
DefaultSettings: map[string]string{
|
||||||
"TODO": "TODO | DONE",
|
"TODO": "TODO | DONE",
|
||||||
"EXCLUDE_TAGS": "noexport",
|
"EXCLUDE_TAGS": "noexport",
|
||||||
|
"OPTIONS": "toc:t e:t f:t pri:t todo:t tags:t",
|
||||||
},
|
},
|
||||||
Log: log.New(os.Stderr, "go-org: ", 0),
|
Log: log.New(os.Stderr, "go-org: ", 0),
|
||||||
}
|
}
|
||||||
|
@ -180,6 +181,24 @@ func (d *Document) Get(key string) string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// see https://orgmode.org/manual/Export-settings.html
|
||||||
|
func (d *Document) GetOption(key string) bool {
|
||||||
|
for _, field := range strings.Fields(d.Get("OPTIONS")) {
|
||||||
|
if strings.HasPrefix(field, key) {
|
||||||
|
switch field[len(key)+len(":"):] {
|
||||||
|
case "t":
|
||||||
|
return true
|
||||||
|
case "nil":
|
||||||
|
return false
|
||||||
|
default:
|
||||||
|
d.Log.Printf("Bad value for export option %s (%s)", key, field)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func (d *Document) parseOne(i int, stop stopFn) (consumed int, node Node) {
|
func (d *Document) parseOne(i int, stop stopFn) (consumed int, node Node) {
|
||||||
switch d.tokens[i].kind {
|
switch d.tokens[i].kind {
|
||||||
case "unorderedList", "orderedList":
|
case "unorderedList", "orderedList":
|
||||||
|
|
|
@ -14,9 +14,9 @@ import (
|
||||||
|
|
||||||
type HTMLWriter struct {
|
type HTMLWriter struct {
|
||||||
stringBuilder
|
stringBuilder
|
||||||
|
document *Document
|
||||||
HighlightCodeBlock func(source, lang string) string
|
HighlightCodeBlock func(source, lang string) string
|
||||||
htmlEscape bool
|
htmlEscape bool
|
||||||
excludeTags []string
|
|
||||||
log *log.Logger
|
log *log.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ func (w *HTMLWriter) nodesAsString(nodes ...Node) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *HTMLWriter) before(d *Document) {
|
func (w *HTMLWriter) before(d *Document) {
|
||||||
w.excludeTags = strings.Fields(d.Get("EXCLUDE_TAGS"))
|
w.document = d
|
||||||
w.log = d.Log
|
w.log = d.Log
|
||||||
w.writeOutline(d)
|
w.writeOutline(d)
|
||||||
}
|
}
|
||||||
|
@ -193,7 +193,7 @@ func (w *HTMLWriter) writeFootnoteDefinition(f FootnoteDefinition) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *HTMLWriter) writeFootnotes(d *Document) {
|
func (w *HTMLWriter) writeFootnotes(d *Document) {
|
||||||
if len(d.Footnotes.Definitions) == 0 {
|
if !w.document.GetOption("f") || len(d.Footnotes.Definitions) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.WriteString(`<div class="footnotes">` + "\n")
|
w.WriteString(`<div class="footnotes">` + "\n")
|
||||||
|
@ -206,7 +206,7 @@ func (w *HTMLWriter) writeFootnotes(d *Document) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *HTMLWriter) writeOutline(d *Document) {
|
func (w *HTMLWriter) writeOutline(d *Document) {
|
||||||
if len(d.Outline.Children) != 0 {
|
if w.document.GetOption("toc") && len(d.Outline.Children) != 0 {
|
||||||
w.WriteString("<nav>\n<ul>\n")
|
w.WriteString("<nav>\n<ul>\n")
|
||||||
for _, section := range d.Outline.Children {
|
for _, section := range d.Outline.Children {
|
||||||
w.writeSection(section)
|
w.writeSection(section)
|
||||||
|
@ -231,7 +231,7 @@ func (w *HTMLWriter) writeSection(section *Section) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *HTMLWriter) writeHeadline(h Headline) {
|
func (w *HTMLWriter) writeHeadline(h Headline) {
|
||||||
for _, excludeTag := range w.excludeTags {
|
for _, excludeTag := range strings.Fields(w.document.Get("EXCLUDE_TAGS")) {
|
||||||
for _, tag := range h.Tags {
|
for _, tag := range h.Tags {
|
||||||
if excludeTag == tag {
|
if excludeTag == tag {
|
||||||
return
|
return
|
||||||
|
@ -240,15 +240,15 @@ func (w *HTMLWriter) writeHeadline(h Headline) {
|
||||||
}
|
}
|
||||||
|
|
||||||
w.WriteString(fmt.Sprintf(`<h%d id="%s">`, h.Lvl, h.ID()) + "\n")
|
w.WriteString(fmt.Sprintf(`<h%d id="%s">`, h.Lvl, h.ID()) + "\n")
|
||||||
if h.Status != "" {
|
if w.document.GetOption("todo") && h.Status != "" {
|
||||||
w.WriteString(fmt.Sprintf(`<span class="todo">%s</span>`, h.Status) + "\n")
|
w.WriteString(fmt.Sprintf(`<span class="todo">%s</span>`, h.Status) + "\n")
|
||||||
}
|
}
|
||||||
if h.Priority != "" {
|
if w.document.GetOption("pri") && h.Priority != "" {
|
||||||
w.WriteString(fmt.Sprintf(`<span class="priority">[%s]</span>`, h.Priority) + "\n")
|
w.WriteString(fmt.Sprintf(`<span class="priority">[%s]</span>`, h.Priority) + "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
w.writeNodes(h.Title...)
|
w.writeNodes(h.Title...)
|
||||||
if len(h.Tags) != 0 {
|
if w.document.GetOption("tags") && len(h.Tags) != 0 {
|
||||||
tags := make([]string, len(h.Tags))
|
tags := make([]string, len(h.Tags))
|
||||||
for i, tag := range h.Tags {
|
for i, tag := range h.Tags {
|
||||||
tags[i] = fmt.Sprintf(`<span>%s</span>`, tag)
|
tags[i] = fmt.Sprintf(`<span>%s</span>`, tag)
|
||||||
|
@ -263,7 +263,7 @@ func (w *HTMLWriter) writeHeadline(h Headline) {
|
||||||
func (w *HTMLWriter) writeText(t Text) {
|
func (w *HTMLWriter) writeText(t Text) {
|
||||||
if !w.htmlEscape {
|
if !w.htmlEscape {
|
||||||
w.WriteString(t.Content)
|
w.WriteString(t.Content)
|
||||||
} else if t.IsRaw {
|
} else if !w.document.GetOption("e") || t.IsRaw {
|
||||||
w.WriteString(html.EscapeString(t.Content))
|
w.WriteString(html.EscapeString(t.Content))
|
||||||
} else {
|
} else {
|
||||||
w.WriteString(html.EscapeString(htmlEntityReplacer.Replace(t.Content)))
|
w.WriteString(html.EscapeString(htmlEntityReplacer.Replace(t.Content)))
|
||||||
|
@ -293,6 +293,9 @@ func (w *HTMLWriter) writeExplicitLineBreak(l ExplicitLineBreak) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *HTMLWriter) writeFootnoteLink(l FootnoteLink) {
|
func (w *HTMLWriter) writeFootnoteLink(l FootnoteLink) {
|
||||||
|
if !w.document.GetOption("f") {
|
||||||
|
return
|
||||||
|
}
|
||||||
n := html.EscapeString(l.Name)
|
n := html.EscapeString(l.Name)
|
||||||
w.WriteString(fmt.Sprintf(`<sup class="footnote-reference"><a id="footnote-reference-%s" href="#footnote-%s">%s</a></sup>`, n, n, n))
|
w.WriteString(fmt.Sprintf(`<sup class="footnote-reference"><a id="footnote-reference-%s" href="#footnote-%s">%s</a></sup>`, n, n, n))
|
||||||
}
|
}
|
||||||
|
|
45
org/testdata/options.html
vendored
Normal file
45
org/testdata/options.html
vendored
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
<h1 id="headline-1">
|
||||||
|
<code class="verbatim">#+OPTIONS:</code> toggles supported by <code class="verbatim">go-org</code>
|
||||||
|
</h1>
|
||||||
|
<p>
|
||||||
|
<code class="verbatim">go-org</code> supports multiple export toggles as described in the <a href="https://orgmode.org/manual/Export-settings.html">export settings</a> Org mode manual.
|
||||||
|
By default those toggles are enabled. This files starts with <code class="verbatim">#+OPTIONS:</code> (empty options) and thus
|
||||||
|
disables all settings.
|
||||||
|
That means, entities like <code class="verbatim">---</code> --- (mdash) will be left untouched, footnotes like <code class="verbatim">[fn:1]</code> will
|
||||||
|
not be exported and there won't be a table of contents at the top.
|
||||||
|
Also, the above headline will be exported without priority, todo status & tags.
|
||||||
|
</p>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>key</th>
|
||||||
|
<th>description</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>f</td>
|
||||||
|
<td>Include footnotes (definitions & links)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>e</td>
|
||||||
|
<td>Include entities</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>toc</td>
|
||||||
|
<td>Include table of contents (outline)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>pri</td>
|
||||||
|
<td>Include priority <code class="verbatim">[#A]</code>, <code class="verbatim">[#B]</code>, <code class="verbatim">[#C]</code> in headline title</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>todo</td>
|
||||||
|
<td>Include todo status in headline title</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>tags</td>
|
||||||
|
<td>Include tags in headline title</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
22
org/testdata/options.org
vendored
Normal file
22
org/testdata/options.org
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#+OPTIONS:
|
||||||
|
|
||||||
|
* DONE [#A] =#+OPTIONS:= toggles supported by =go-org= :tag1:tag2:
|
||||||
|
=go-org= supports multiple export toggles as described in the [[https://orgmode.org/manual/Export-settings.html][export settings]] Org mode manual.
|
||||||
|
By default those toggles are enabled. This files starts with =#+OPTIONS:= (empty options) and thus
|
||||||
|
disables all settings.
|
||||||
|
That means, entities like =---= --- (mdash) will be left untouched, footnotes like =[fn:1]= [fn:1] will
|
||||||
|
not be exported and there won't be a table of contents at the top.
|
||||||
|
Also, the above headline will be exported without priority, todo status & tags.
|
||||||
|
|
||||||
|
|
||||||
|
| key | description |
|
||||||
|
|------+-----------------------------------------------------------|
|
||||||
|
| f | Include footnotes (definitions & links) |
|
||||||
|
| e | Include entities |
|
||||||
|
| toc | Include table of contents (outline) |
|
||||||
|
|------+-----------------------------------------------------------|
|
||||||
|
| pri | Include priority =[#A]=, =[#B]=, =[#C]= in headline title |
|
||||||
|
| todo | Include todo status in headline title |
|
||||||
|
| tags | Include tags in headline title |
|
||||||
|
|
||||||
|
[fn:1] This footnote definition won't be printed
|
22
org/testdata/options.pretty_org
vendored
Normal file
22
org/testdata/options.pretty_org
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#+OPTIONS:
|
||||||
|
|
||||||
|
* DONE [#A] =#+OPTIONS:= toggles supported by =go-org= :tag1:tag2:
|
||||||
|
=go-org= supports multiple export toggles as described in the [[https://orgmode.org/manual/Export-settings.html][export settings]] Org mode manual.
|
||||||
|
By default those toggles are enabled. This files starts with =#+OPTIONS:= (empty options) and thus
|
||||||
|
disables all settings.
|
||||||
|
That means, entities like =---= --- (mdash) will be left untouched, footnotes like =[fn:1]= [fn:1] will
|
||||||
|
not be exported and there won't be a table of contents at the top.
|
||||||
|
Also, the above headline will be exported without priority, todo status & tags.
|
||||||
|
|
||||||
|
|
||||||
|
| key | description |
|
||||||
|
|------+-----------------------------------------------------------|
|
||||||
|
| f | Include footnotes (definitions & links) |
|
||||||
|
| e | Include entities |
|
||||||
|
| toc | Include table of contents (outline) |
|
||||||
|
|------+-----------------------------------------------------------|
|
||||||
|
| pri | Include priority =[#A]=, =[#B]=, =[#C]= in headline title |
|
||||||
|
| todo | Include todo status in headline title |
|
||||||
|
| tags | Include tags in headline title |
|
||||||
|
|
||||||
|
[fn:1] This footnote definition won't be printed
|
Loading…
Add table
Add a link
Reference in a new issue