diff --git a/block_test.go b/block_test.go
index 1c4f50a..2451cd2 100644
--- a/block_test.go
+++ b/block_test.go
@@ -17,16 +17,35 @@ import (
"testing"
)
+func runMarkdownBlockWithRenderer(input string, extensions int, renderer Renderer) string {
+ return string(Markdown([]byte(input), renderer, extensions))
+}
+
func runMarkdownBlock(input string, extensions int) string {
htmlFlags := 0
htmlFlags |= HTML_USE_XHTML
renderer := HtmlRenderer(htmlFlags, "", "")
- return string(Markdown([]byte(input), renderer, extensions))
+ return runMarkdownBlockWithRenderer(input, extensions, renderer)
+}
+
+func runnerWithRendererParameters(parameters HtmlRendererParameters) func(string, int) string {
+ return func(input string, extensions int) string {
+ htmlFlags := 0
+ htmlFlags |= HTML_USE_XHTML
+
+ renderer := HtmlRendererWithParameters(htmlFlags, "", "", parameters)
+
+ return runMarkdownBlockWithRenderer(input, extensions, renderer)
+ }
}
func doTestsBlock(t *testing.T, tests []string, extensions int) {
+ doTestsBlockWithRunner(t, tests, extensions, runMarkdownBlock)
+}
+
+func doTestsBlockWithRunner(t *testing.T, tests []string, extensions int, runner func(string, int) string) {
// catch and report panics
var candidate string
defer func() {
@@ -39,7 +58,7 @@ func doTestsBlock(t *testing.T, tests []string, extensions int) {
input := tests[i]
candidate = input
expected := tests[i+1]
- actual := runMarkdownBlock(candidate, extensions)
+ actual := runner(candidate, extensions)
if actual != expected {
t.Errorf("\nInput [%#v]\nExpected[%#v]\nActual [%#v]",
candidate, expected, actual)
@@ -237,6 +256,54 @@ func TestPrefixHeaderIdExtension(t *testing.T) {
doTestsBlock(t, tests, EXTENSION_HEADER_IDS)
}
+func TestPrefixHeaderIdExtensionWithPrefixAndSuffix(t *testing.T) {
+ var tests = []string{
+ "# header 1 {#someid}\n",
+ "
header 1
\n",
+
+ "## header 2 {#someid}\n",
+ "header 2
\n",
+
+ "### header 3 {#someid}\n",
+ "header 3
\n",
+
+ "#### header 4 {#someid}\n",
+ "header 4
\n",
+
+ "##### header 5 {#someid}\n",
+ "header 5
\n",
+
+ "###### header 6 {#someid}\n",
+ "header 6
\n",
+
+ "####### header 7 {#someid}\n",
+ "# header 7
\n",
+
+ "# header 1 # {#someid}\n",
+ "header 1
\n",
+
+ "## header 2 ## {#someid}\n",
+ "header 2
\n",
+
+ "* List\n# Header {#someid}\n* List\n",
+ "\nList
\n\nHeader
\n\nList
\n
\n",
+
+ "* List\n#Header {#someid}\n* List\n",
+ "\nList
\n\nHeader
\n\nList
\n
\n",
+
+ "* List\n * Nested list\n # Nested header {#someid}\n",
+ "\nList
\n\n\nNested list
\n\n" +
+ "Nested header
\n
\n
\n",
+ }
+
+ parameters := HtmlRendererParameters{
+ HeaderIDPrefix: "PRE:",
+ HeaderIDSuffix: ":POST",
+ }
+
+ doTestsBlockWithRunner(t, tests, EXTENSION_HEADER_IDS, runnerWithRendererParameters(parameters))
+}
+
func TestPrefixAutoHeaderIdExtension(t *testing.T) {
var tests = []string{
"# Header 1\n",
@@ -288,6 +355,63 @@ func TestPrefixAutoHeaderIdExtension(t *testing.T) {
doTestsBlock(t, tests, EXTENSION_AUTO_HEADER_IDS)
}
+func TestPrefixAutoHeaderIdExtensionWithPrefixAndSuffix(t *testing.T) {
+ var tests = []string{
+ "# Header 1\n",
+ "\n",
+
+ "# Header 1 \n",
+ "\n",
+
+ "## Header 2\n",
+ "\n",
+
+ "### Header 3\n",
+ "\n",
+
+ "#### Header 4\n",
+ "\n",
+
+ "##### Header 5\n",
+ "\n",
+
+ "###### Header 6\n",
+ "\n",
+
+ "####### Header 7\n",
+ "\n",
+
+ "Hello\n# Header 1\nGoodbye\n",
+ "Hello
\n\n\n\nGoodbye
\n",
+
+ "* List\n# Header\n* List\n",
+ "\n",
+
+ "* List\n#Header\n* List\n",
+ "\n",
+
+ "* List\n * Nested list\n # Nested header\n",
+ "\nList
\n\n\nNested list
\n\n" +
+ " \n
\n
\n",
+
+ "# Header\n\n# Header\n",
+ "\n\n\n",
+
+ "# Header 1\n\n# Header 1",
+ "\n\n\n",
+
+ "# Header\n\n# Header 1\n\n# Header\n\n# Header",
+ "\n\n\n\n\n\n\n",
+ }
+
+ parameters := HtmlRendererParameters{
+ HeaderIDPrefix: "PRE:",
+ HeaderIDSuffix: ":POST",
+ }
+
+ doTestsBlockWithRunner(t, tests, EXTENSION_AUTO_HEADER_IDS, runnerWithRendererParameters(parameters))
+}
+
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 a552508..cab8383 100644
--- a/html.go
+++ b/html.go
@@ -62,6 +62,11 @@ type HtmlRendererParameters struct {
// HTML_FOOTNOTE_RETURN_LINKS flag is enabled. If blank, the string
// [return] is used.
FootnoteReturnLinkContents string
+ // If set, add this text to the front of each Header ID, to ensure
+ // uniqueness.
+ HeaderIDPrefix string
+ // If set, add this text to the back of each Header ID, to ensure uniqueness.
+ HeaderIDSuffix string
}
// Html is a type that implements the Renderer interface for HTML output.
@@ -200,7 +205,17 @@ func (options *Html) Header(out *bytes.Buffer, text func() bool, level int, id s
}
if id != "" {
- out.WriteString(fmt.Sprintf("", level, options.ensureUniqueHeaderID(id)))
+ id = options.ensureUniqueHeaderID(id)
+
+ if options.parameters.HeaderIDPrefix != "" {
+ id = options.parameters.HeaderIDPrefix + id
+ }
+
+ if options.parameters.HeaderIDSuffix != "" {
+ id = id + options.parameters.HeaderIDSuffix
+ }
+
+ out.WriteString(fmt.Sprintf("", level, id))
} else {
out.WriteString(fmt.Sprintf("", level))
}