From 7c239a7aeb26a3de2027838d31d22d60828ce17e Mon Sep 17 00:00:00 2001 From: Niklas Fasching Date: Sun, 28 Mar 2021 16:59:36 +0200 Subject: [PATCH] html: Add support for #+TOC keyword org mode allows rendering the toc anywhere in the html document using the `TOC` keyword [1]. There's more options but `#+TOC: headlines $n` should be enough for starters. Note that org mode still requires setting `#+OPTIONS: toc:nil` to disable the default toc [1] https://orgmode.org/manual/Table-of-Contents.html --- org/html_writer.go | 16 ++++++++++++---- org/testdata/keywords.html | 31 +++++++++++++++++++++++++++++++ org/testdata/keywords.org | 11 ++++++++++- org/testdata/keywords.pretty_org | 11 ++++++++++- 4 files changed, 63 insertions(+), 6 deletions(-) diff --git a/org/html_writer.go b/org/html_writer.go index f2e75a0..9dfe7ad 100644 --- a/org/html_writer.go +++ b/org/html_writer.go @@ -55,6 +55,7 @@ var listItemStatuses = map[string]string{ } var cleanHeadlineTitleForHTMLAnchorRegexp = regexp.MustCompile(`]*>`) // nested a tags are not valid HTML +var tocHeadlineMaxLvlRegexp = regexp.MustCompile(`headlines\s+(\d+)`) func NewHTMLWriter() *HTMLWriter { defaultConfig := New() @@ -100,7 +101,10 @@ func (w *HTMLWriter) Before(d *Document) { } w.WriteString(fmt.Sprintf(`

%s

`+"\n", title)) } - w.WriteOutline(d) + if w.document.GetOption("toc") != "nil" { + maxLvl, _ := strconv.Atoi(w.document.GetOption("toc")) + w.WriteOutline(d, maxLvl) + } } func (w *HTMLWriter) After(d *Document) { @@ -168,6 +172,11 @@ func (w *HTMLWriter) WriteDrawer(d Drawer) { func (w *HTMLWriter) WriteKeyword(k Keyword) { if k.Key == "HTML" { w.WriteString(k.Value + "\n") + } else if k.Key == "TOC" { + if m := tocHeadlineMaxLvlRegexp.FindStringSubmatch(k.Value); m != nil { + maxLvl, _ := strconv.Atoi(m[1]) + w.WriteOutline(w.document, maxLvl) + } } } @@ -207,9 +216,8 @@ func (w *HTMLWriter) WriteFootnotes(d *Document) { w.WriteString("\n\n") } -func (w *HTMLWriter) WriteOutline(d *Document) { - if w.document.GetOption("toc") != "nil" && len(d.Outline.Children) != 0 { - maxLvl, _ := strconv.Atoi(w.document.GetOption("toc")) +func (w *HTMLWriter) WriteOutline(d *Document, maxLvl int) { + if len(d.Outline.Children) != 0 { w.WriteString("