diff --git a/block_test.go b/block_test.go index dc780e1..5cbff6d 100644 --- a/block_test.go +++ b/block_test.go @@ -371,6 +371,92 @@ func TestPrefixAutoHeaderIdExtensionWithPrefixAndSuffix(t *testing.T) { }) } +func TestPrefixHeaderLevelOffset(t *testing.T) { + var offsetTests = []struct { + offset int + tests []string + }{{ + offset: 0, + tests: []string{ + "# Header 1\n", + "

Header 1

\n", + + "## Header 2\n", + "

Header 2

\n", + + "### Header 3\n", + "

Header 3

\n", + + "#### Header 4\n", + "

Header 4

\n", + + "##### Header 5\n", + "
Header 5
\n", + + "###### Header 6\n", + "
Header 6
\n", + + "####### Header 7\n", + "
# Header 7
\n", + }, + }, { + offset: 1, + tests: []string{ + "# Header 1\n", + "

Header 1

\n", + + "## Header 2\n", + "

Header 2

\n", + + "### Header 3\n", + "

Header 3

\n", + + "#### Header 4\n", + "
Header 4
\n", + + "##### Header 5\n", + "
Header 5
\n", + + "###### Header 6\n", + "
Header 6
\n", + + "####### Header 7\n", + "
# Header 7
\n", + }, + }, { + offset: -1, + tests: []string{ + "# Header 1\n", + "

Header 1

\n", + + "## Header 2\n", + "

Header 2

\n", + + "### Header 3\n", + "

Header 3

\n", + + "#### Header 4\n", + "

Header 4

\n", + + "##### Header 5\n", + "

Header 5

\n", + + "###### Header 6\n", + "
Header 6
\n", + + "####### Header 7\n", + "
# Header 7
\n", + }, + }} + for _, offsetTest := range offsetTests { + offset := offsetTest.offset + tests := offsetTest.tests + doTestsParam(t, tests, TestParams{ + HTMLRendererParameters: HTMLRendererParameters{HeadingLevelOffset: offset}, + }) + } +} + func TestPrefixMultipleHeaderExtensions(t *testing.T) { var tests = []string{ "# Header\n\n# Header {#header}\n\n# Header 1", diff --git a/html.go b/html.go index dd4973f..6a3b7ce 100644 --- a/html.go +++ b/html.go @@ -87,6 +87,10 @@ type HTMLRendererParameters struct { HeadingIDPrefix string // If set, add this text to the back of each Heading ID, to ensure uniqueness. HeadingIDSuffix string + // Increase heading levels: if the offset is 1,

becomes

etc. + // Negative offset is also valid. + // Resulting levels are clipped between 1 and 6. + HeadingLevelOffset int Title string // Document title (used if CompletePage is set) CSS string // Optional CSS file URL (used if CompletePage is set) @@ -460,9 +464,10 @@ var ( ) func headingTagsFromLevel(level int) ([]byte, []byte) { - switch level { - case 1: + if level <= 1 { return h1Tag, h1CloseTag + } + switch level { case 2: return h2Tag, h2CloseTag case 3: @@ -471,9 +476,8 @@ func headingTagsFromLevel(level int) ([]byte, []byte) { return h4Tag, h4CloseTag case 5: return h5Tag, h5CloseTag - default: - return h6Tag, h6CloseTag } + return h6Tag, h6CloseTag } func (r *HTMLRenderer) outHRTag(w io.Writer) { @@ -651,7 +655,8 @@ func (r *HTMLRenderer) RenderNode(w io.Writer, node *Node, entering bool) WalkSt r.out(w, node.Literal) r.cr(w) case Heading: - openTag, closeTag := headingTagsFromLevel(node.Level) + headingLevel := r.HTMLRendererParameters.HeadingLevelOffset + node.Level + openTag, closeTag := headingTagsFromLevel(headingLevel) if entering { if node.IsTitleblock { attrs = append(attrs, `class="title"`)