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"`)