Merge pull request #95 from glacials/html-toplevel-hlevel
Allow customizing header level offset
This commit is contained in:
commit
fa3e6f91d9
2 changed files with 69 additions and 4 deletions
|
@ -21,6 +21,21 @@ type HTMLWriter struct {
|
||||||
ExtendingWriter Writer
|
ExtendingWriter Writer
|
||||||
HighlightCodeBlock func(source, lang string, inline bool, params map[string]string) string
|
HighlightCodeBlock func(source, lang string, inline bool, params map[string]string) string
|
||||||
PrettyRelativeLinks bool
|
PrettyRelativeLinks bool
|
||||||
|
// TopLevelHLevel determines what HTML heading to use for a
|
||||||
|
// level-1 Org headline, and by extension further headings.
|
||||||
|
//
|
||||||
|
// For example, a value of 1 means a top-level Org headline will be
|
||||||
|
// rendered as an <h1> element, a level-2 Org headline will be
|
||||||
|
// rendered as an <h2> element, and so on.
|
||||||
|
//
|
||||||
|
// A value of 2 (default) means a top-level Org headline will be
|
||||||
|
// rendered as an <h2> element, a level-2 Org headline will be
|
||||||
|
// rendered as an <h3> element, and so on.
|
||||||
|
//
|
||||||
|
// This setting and its default behavior match Org's
|
||||||
|
// :html-toplevel-hlevel export property and the associated
|
||||||
|
// org-html-toplevel-hlevel variable.
|
||||||
|
TopLevelHLevel int
|
||||||
|
|
||||||
strings.Builder
|
strings.Builder
|
||||||
document *Document
|
document *Document
|
||||||
|
@ -72,6 +87,7 @@ func NewHTMLWriter() *HTMLWriter {
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("<div class=\"highlight\">\n<pre>\n%s\n</pre>\n</div>", html.EscapeString(source))
|
return fmt.Sprintf("<div class=\"highlight\">\n<pre>\n%s\n</pre>\n</div>", html.EscapeString(source))
|
||||||
},
|
},
|
||||||
|
TopLevelHLevel: 2,
|
||||||
footnotes: &footnotes{
|
footnotes: &footnotes{
|
||||||
mapping: map[string]int{},
|
mapping: map[string]int{},
|
||||||
},
|
},
|
||||||
|
@ -272,8 +288,10 @@ func (w *HTMLWriter) WriteHeadline(h Headline) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
w.WriteString(fmt.Sprintf(`<div id="outline-container-%s" class="outline-%d">`, h.ID(), h.Lvl+1) + "\n")
|
level := (h.Lvl - 1) + w.TopLevelHLevel
|
||||||
w.WriteString(fmt.Sprintf(`<h%d id="%s">`, h.Lvl+1, h.ID()) + "\n")
|
|
||||||
|
w.WriteString(fmt.Sprintf(`<div id="outline-container-%s" class="outline-%d">`, h.ID(), level) + "\n")
|
||||||
|
w.WriteString(fmt.Sprintf(`<h%d id="%s">`, level, h.ID()) + "\n")
|
||||||
if w.document.GetOption("todo") != "nil" && h.Status != "" {
|
if w.document.GetOption("todo") != "nil" && 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")
|
||||||
}
|
}
|
||||||
|
@ -290,9 +308,9 @@ func (w *HTMLWriter) WriteHeadline(h Headline) {
|
||||||
w.WriteString("   ")
|
w.WriteString("   ")
|
||||||
w.WriteString(fmt.Sprintf(`<span class="tags">%s</span>`, strings.Join(tags, " ")))
|
w.WriteString(fmt.Sprintf(`<span class="tags">%s</span>`, strings.Join(tags, " ")))
|
||||||
}
|
}
|
||||||
w.WriteString(fmt.Sprintf("\n</h%d>\n", h.Lvl+1))
|
w.WriteString(fmt.Sprintf("\n</h%d>\n", level))
|
||||||
if content := w.WriteNodesAsString(h.Children...); content != "" {
|
if content := w.WriteNodesAsString(h.Children...); content != "" {
|
||||||
w.WriteString(fmt.Sprintf(`<div id="outline-text-%s" class="outline-text-%d">`, h.ID(), h.Lvl+1) + "\n" + content + "</div>\n")
|
w.WriteString(fmt.Sprintf(`<div id="outline-text-%s" class="outline-text-%d">`, h.ID(), level) + "\n" + content + "</div>\n")
|
||||||
}
|
}
|
||||||
w.WriteString("</div>\n")
|
w.WriteString("</div>\n")
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,3 +56,50 @@ func TestPrettyRelativeLinks(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var topLevelHLevelTests = map[struct {
|
||||||
|
TopLevelHLevel int
|
||||||
|
input string
|
||||||
|
}]string{
|
||||||
|
{1, "* Top-level headline"}: "<h1 id=\"headline-1\">\nTop-level headline\n</h1>",
|
||||||
|
{1, "** Second-level headline"}: "<h2 id=\"headline-1\">\nSecond-level headline\n</h2>",
|
||||||
|
{1, "*** Third-level headline"}: "<h3 id=\"headline-1\">\nThird-level headline\n</h3>",
|
||||||
|
{1, "**** Fourth-level headline"}: "<h4 id=\"headline-1\">\nFourth-level headline\n</h4>",
|
||||||
|
{1, "***** Fifth-level headline"}: "<h5 id=\"headline-1\">\nFifth-level headline\n</h5>",
|
||||||
|
{1, "****** Sixth-level headline"}: "<h6 id=\"headline-1\">\nSixth-level headline\n</h6>",
|
||||||
|
|
||||||
|
{2, "* Top-level headline"}: "<h2 id=\"headline-1\">\nTop-level headline\n</h2>",
|
||||||
|
{2, "** Second-level headline"}: "<h3 id=\"headline-1\">\nSecond-level headline\n</h3>",
|
||||||
|
{2, "*** Third-level headline"}: "<h4 id=\"headline-1\">\nThird-level headline\n</h4>",
|
||||||
|
{2, "**** Fourth-level headline"}: "<h5 id=\"headline-1\">\nFourth-level headline\n</h5>",
|
||||||
|
{2, "***** Fifth-level headline"}: "<h6 id=\"headline-1\">\nFifth-level headline\n</h6>",
|
||||||
|
|
||||||
|
{3, "* Top-level headline"}: "<h3 id=\"headline-1\">\nTop-level headline\n</h3>",
|
||||||
|
{3, "** Second-level headline"}: "<h4 id=\"headline-1\">\nSecond-level headline\n</h4>",
|
||||||
|
{3, "*** Third-level headline"}: "<h5 id=\"headline-1\">\nThird-level headline\n</h5>",
|
||||||
|
{3, "**** Fourth-level headline"}: "<h6 id=\"headline-1\">\nFourth-level headline\n</h6>",
|
||||||
|
|
||||||
|
{4, "* Top-level headline"}: "<h4 id=\"headline-1\">\nTop-level headline\n</h4>",
|
||||||
|
{4, "** Second-level headline"}: "<h5 id=\"headline-1\">\nSecond-level headline\n</h5>",
|
||||||
|
{4, "*** Third-level headline"}: "<h6 id=\"headline-1\">\nThird-level headline\n</h6>",
|
||||||
|
|
||||||
|
{5, "* Top-level headline"}: "<h5 id=\"headline-1\">\nTop-level headline\n</h5>",
|
||||||
|
{5, "** Second-level headline"}: "<h6 id=\"headline-1\">\nSecond-level headline\n</h6>",
|
||||||
|
|
||||||
|
{6, "* Top-level headline"}: "<h6 id=\"headline-1\">\nTop-level headline\n</h6>",
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTopLevelHLevel(t *testing.T) {
|
||||||
|
for org, expected := range topLevelHLevelTests {
|
||||||
|
t.Run(org.input, func(t *testing.T) {
|
||||||
|
writer := NewHTMLWriter()
|
||||||
|
writer.TopLevelHLevel = org.TopLevelHLevel
|
||||||
|
actual, err := New().Silent().Parse(strings.NewReader(org.input), "./topLevelHLevelTests.org").Write(writer)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("TopLevelHLevel=%d %s\n got error: %s", org.TopLevelHLevel, org.input, err)
|
||||||
|
} else if actual := strings.TrimSpace(actual); !strings.Contains(actual, expected) {
|
||||||
|
t.Errorf("TopLevelHLevel=%d %s:\n%s'", org.TopLevelHLevel, org.input, diff(actual, expected))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue