Add support for angled, double quotes The flag `HTML_SMARTYPANTS_ANGLED_QUOTES` combined with `HTML_USE_SMARTYPANTS` configures rendering of double quotes as angled left and right quotes (« »). The SmartyPants documentation mentions a special syntax for these, `<<>>`, a syntax neither pretty nor user friendly. Typical use cases would be either or, or combined, but never in the same document. As an example would be a person from Norway; he has a blog in both English and Norwegian (his native tounge); he would then configure Blackfriday to use angled quotes for the Norwegian section, but keep them as reqular double quotes for the English. If the flag `HTML_SMARTYPANTS_ANGLED_QUOTES` is not provided, everything works as before this commit.
bep bjorn.erik.pedersen@gmail.com
Wed, 05 Nov 2014 23:18:32 +0100
3 files changed,
52 insertions(+),
6 deletions(-)
M
html.go
→
html.go
@@ -39,6 +39,7 @@ HTML_USE_XHTML // generate XHTML output instead of HTML
HTML_USE_SMARTYPANTS // enable smart punctuation substitutions HTML_SMARTYPANTS_FRACTIONS // enable smart fractions (with HTML_USE_SMARTYPANTS) HTML_SMARTYPANTS_LATEX_DASHES // enable LaTeX-style dashes (with HTML_USE_SMARTYPANTS) + HTML_SMARTYPANTS_ANGLED_QUOTES // enable angled double quotes (with HTML_USE_SMARTYPANTS) for double quotes rendering HTML_FOOTNOTE_RETURN_LINKS // generate a link at the end of a footnote to return to the source )
M
inline_test.go
→
inline_test.go
@@ -798,3 +798,27 @@ }
doTestsInlineParam(t, tests, EXTENSION_FOOTNOTES, HTML_FOOTNOTE_RETURN_LINKS, params) } + +func TestSmartDoubleQuotes(t *testing.T) { + var tests = []string{ + "this should be normal \"quoted\" text.\n", + "<p>this should be normal “quoted” text.</p>\n", + "this \" single double\n", + "<p>this “ single double</p>\n", + "two pair of \"some\" quoted \"text\".\n", + "<p>two pair of “some” quoted “text”.</p>\n"} + + doTestsInlineParam(t, tests, 0, HTML_USE_SMARTYPANTS, HtmlRendererParameters{}) +} + +func TestSmartAngledDoubleQuotes(t *testing.T) { + var tests = []string{ + "this should be angled \"quoted\" text.\n", + "<p>this should be angled «quoted» text.</p>\n", + "this \" single double\n", + "<p>this « single double</p>\n", + "two pair of \"some\" quoted \"text\".\n", + "<p>two pair of «some» quoted «text».</p>\n"} + + doTestsInlineParam(t, tests, 0, HTML_USE_SMARTYPANTS|HTML_SMARTYPANTS_ANGLED_QUOTES, HtmlRendererParameters{}) +}
M
smartypants.go
→
smartypants.go
@@ -205,13 +205,13 @@ out.WriteByte(text[0])
return 0 } -func smartAmp(out *bytes.Buffer, smrt *smartypantsData, previousChar byte, text []byte) int { +func smartAmpVariant(out *bytes.Buffer, smrt *smartypantsData, previousChar byte, text []byte, quote byte) int { if bytes.HasPrefix(text, []byte(""")) { nextChar := byte(0) if len(text) >= 7 { nextChar = text[6] } - if smartQuoteHelper(out, previousChar, nextChar, 'd', &smrt.inDoubleQuote) { + if smartQuoteHelper(out, previousChar, nextChar, quote, &smrt.inDoubleQuote) { return 5 } }@@ -222,6 +222,14 @@ }
out.WriteByte('&') return 0 +} + +func smartAmp(out *bytes.Buffer, smrt *smartypantsData, previousChar byte, text []byte) int { + return smartAmpVariant(out, smrt, previousChar, text, 'd') +} + +func smartAmpAngledQuote(out *bytes.Buffer, smrt *smartypantsData, previousChar byte, text []byte) int { + return smartAmpVariant(out, smrt, previousChar, text, 'a') } func smartPeriod(out *bytes.Buffer, smrt *smartypantsData, previousChar byte, text []byte) int {@@ -323,18 +331,26 @@ out.WriteByte(text[0])
return 0 } -func smartDoubleQuote(out *bytes.Buffer, smrt *smartypantsData, previousChar byte, text []byte) int { +func smartDoubleQuoteVariant(out *bytes.Buffer, smrt *smartypantsData, previousChar byte, text []byte, quote byte) int { nextChar := byte(0) if len(text) > 1 { nextChar = text[1] } - if !smartQuoteHelper(out, previousChar, nextChar, 'd', &smrt.inDoubleQuote) { + if !smartQuoteHelper(out, previousChar, nextChar, quote, &smrt.inDoubleQuote) { out.WriteString(""") } return 0 } +func smartDoubleQuote(out *bytes.Buffer, smrt *smartypantsData, previousChar byte, text []byte) int { + return smartDoubleQuoteVariant(out, smrt, previousChar, text, 'd') +} + +func smartAngledDoubleQuote(out *bytes.Buffer, smrt *smartypantsData, previousChar byte, text []byte) int { + return smartDoubleQuoteVariant(out, smrt, previousChar, text, 'a') +} + func smartLeftAngle(out *bytes.Buffer, smrt *smartypantsData, previousChar byte, text []byte) int { i := 0@@ -352,8 +368,13 @@ type smartypantsRenderer [256]smartCallback
func smartypants(flags int) *smartypantsRenderer { r := new(smartypantsRenderer) - r['"'] = smartDoubleQuote - r['&'] = smartAmp + if flags&HTML_SMARTYPANTS_ANGLED_QUOTES == 0 { + r['"'] = smartDoubleQuote + r['&'] = smartAmp + } else { + r['"'] = smartAngledDoubleQuote + r['&'] = smartAmpAngledQuote + } r['\''] = smartSingleQuote r['('] = smartParens if flags&HTML_SMARTYPANTS_LATEX_DASHES == 0 {