Skip to content
This repository has been archived by the owner on Nov 10, 2020. It is now read-only.

Commit

Permalink
Merge pull request #50 from xlab/f/smartypants
Browse files Browse the repository at this point in the history
Integrate smartypants.go from blackfriday, adjust tests.
  • Loading branch information
miekg committed Feb 27, 2016
2 parents 0400b2b + ff621c6 commit 4c1c004
Show file tree
Hide file tree
Showing 4 changed files with 531 additions and 15 deletions.
64 changes: 53 additions & 11 deletions html.go
Expand Up @@ -14,16 +14,21 @@ import (

// Html renderer configuration options.
const (
HTML_SKIP_HTML = 1 << iota // skip preformatted HTML blocks
HTML_SKIP_STYLE // skip embedded <style> elements
HTML_SKIP_IMAGES // skip embedded images
HTML_SKIP_LINKS // skip all links
HTML_SAFELINK // only link to trusted protocols
HTML_NOFOLLOW_LINKS // only link with rel="nofollow"
HTML_HREF_TARGET_BLANK // add a blank target
HTML_OMIT_CONTENTS // skip the main contents (for a standalone table of contents)
HTML_COMPLETE_PAGE // generate a complete HTML page
HTML_FOOTNOTE_RETURN_LINKS // generate a link at the end of a footnote to return to the source
HTML_SKIP_HTML = 1 << iota // skip preformatted HTML blocks
HTML_SKIP_STYLE // skip embedded <style> elements
HTML_SKIP_IMAGES // skip embedded images
HTML_SKIP_LINKS // skip all links
HTML_SAFELINK // only link to trusted protocols
HTML_NOFOLLOW_LINKS // only link with rel="nofollow"
HTML_HREF_TARGET_BLANK // add a blank target
HTML_OMIT_CONTENTS // skip the main contents (for a standalone table of contents)
HTML_COMPLETE_PAGE // generate a complete HTML page
HTML_USE_SMARTYPANTS // enable smart punctuation substitutions
HTML_SMARTYPANTS_FRACTIONS // enable smart fractions (with HTML_USE_SMARTYPANTS)
HTML_SMARTYPANTS_DASHES // enable smart dashes (with HTML_USE_SMARTYPANTS)
HTML_SMARTYPANTS_LATEX_DASHES // enable LaTeX-style dashes (with HTML_USE_SMARTYPANTS and HTML_SMARTYPANTS_DASHES)
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
)

var (
Expand Down Expand Up @@ -75,6 +80,8 @@ type html struct {

// (@good) example list group counter
group map[string]int

smartypants *smartypantsRenderer
}

type idx struct {
Expand Down Expand Up @@ -115,6 +122,8 @@ func HtmlRendererWithParameters(flags int, css, head string, renderParameters Ht

index: make(map[idx][]string),
group: make(map[string]int),

smartypants: smartypants(flags),
}
}

Expand Down Expand Up @@ -964,7 +973,40 @@ func (options *html) References(out *bytes.Buffer, citations map[string]*citatio
}

func (options *html) NormalText(out *bytes.Buffer, text []byte) {
attrEscape(out, text)
if options.flags&HTML_USE_SMARTYPANTS != 0 {
options.Smartypants(out, text)
} else {
attrEscape(out, text)
}
}

func (options *html) Smartypants(out *bytes.Buffer, text []byte) {
smrt := smartypantsData{false, false}

// first do normal entity escaping
var escaped bytes.Buffer
attrEscape(&escaped, text)
text = escaped.Bytes()

mark := 0
for i := 0; i < len(text); i++ {
if action := options.smartypants[text[i]]; action != nil {
if i > mark {
out.Write(text[mark:i])
}

previousChar := byte(0)
if i > 0 {
previousChar = text[i-1]
}
i += action(out, &smrt, previousChar, text[i:])
mark = i + 1
}
}

if mark < len(text) {
out.Write(text[mark:])
}
}

func (options *html) DocumentHeader(out *bytes.Buffer, first bool) {
Expand Down
85 changes: 82 additions & 3 deletions inline_test.go
Expand Up @@ -169,7 +169,6 @@ func TestEmphasis(t *testing.T) {

"*What is A\\* algorithm?*\n",
"<p><em>What is A* algorithm?</em></p>\n",

}
doTestsInline(t, tests)
}
Expand Down Expand Up @@ -1075,7 +1074,7 @@ func TestNestedFootnotes(t *testing.T) {
func TestInlineComments(t *testing.T) {
var tests = []string{
"Hello <!-- there ->\n",
"<p>Hello &lt;!-- there -&gt;</p>\n",
"<p>Hello &lt;!&mdash; there &ndash;&gt;</p>\n",

"Hello <!-- there -->\n",
"<p>Hello <!-- there --></p>\n",
Expand All @@ -1098,7 +1097,7 @@ func TestInlineComments(t *testing.T) {
"blahblah\n<!--- foo -->\nrhubarb\n",
"<p>blahblah\n<!--- foo -->\nrhubarb</p>\n",
}
doTestsInlineParam(t, tests, 0, 0, HtmlRendererParameters{})
doTestsInlineParam(t, tests, 0, HTML_USE_SMARTYPANTS|HTML_SMARTYPANTS_DASHES, HtmlRendererParameters{})
}

func TestCitationXML(t *testing.T) {
Expand Down Expand Up @@ -1163,3 +1162,83 @@ func TestShortReferenceXML(t *testing.T) {
}
doTestsInlineXML(t, tests)
}

func TestSmartDoubleQuotes(t *testing.T) {
var tests = []string{
"this should be normal \"quoted\" text.\n",
"<p>this should be normal &ldquo;quoted&rdquo; text.</p>\n",
"this \" single double\n",
"<p>this &ldquo; single double</p>\n",
"two pair of \"some\" quoted \"text\".\n",
"<p>two pair of &ldquo;some&rdquo; quoted &ldquo;text&rdquo;.</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 &laquo;quoted&raquo; text.</p>\n",
"this \" single double\n",
"<p>this &laquo; single double</p>\n",
"two pair of \"some\" quoted \"text\".\n",
"<p>two pair of &laquo;some&raquo; quoted &laquo;text&raquo;.</p>\n"}

doTestsInlineParam(t, tests, 0, HTML_USE_SMARTYPANTS|HTML_SMARTYPANTS_ANGLED_QUOTES, HtmlRendererParameters{})
}

func TestSmartFractions(t *testing.T) {
var tests = []string{
"1/2, 1/4 and 3/4; 1/4th and 3/4ths\n",
"<p>&frac12;, &frac14; and &frac34;; &frac14;th and &frac34;ths</p>\n",
"1/2/2015, 1/4/2015, 3/4/2015; 2015/1/2, 2015/1/4, 2015/3/4.\n",
"<p>1/2/2015, 1/4/2015, 3/4/2015; 2015/1/2, 2015/1/4, 2015/3/4.</p>\n"}

doTestsInlineParam(t, tests, 0, HTML_USE_SMARTYPANTS, HtmlRendererParameters{})

tests = []string{
"1/2, 2/3, 81/100 and 1000000/1048576.\n",
"<p><sup>1</sup>&frasl;<sub>2</sub>, <sup>2</sup>&frasl;<sub>3</sub>, <sup>81</sup>&frasl;<sub>100</sub> and <sup>1000000</sup>&frasl;<sub>1048576</sub>.</p>\n",
"1/2/2015, 1/4/2015, 3/4/2015; 2015/1/2, 2015/1/4, 2015/3/4.\n",
"<p>1/2/2015, 1/4/2015, 3/4/2015; 2015/1/2, 2015/1/4, 2015/3/4.</p>\n"}

doTestsInlineParam(t, tests, 0, HTML_USE_SMARTYPANTS|HTML_SMARTYPANTS_FRACTIONS, HtmlRendererParameters{})
}

func TestDisableSmartDashes(t *testing.T) {
doTestsInlineParam(t, []string{
"foo - bar\n",
"<p>foo - bar</p>\n",
"foo -- bar\n",
"<p>foo -- bar</p>\n",
"foo --- bar\n",
"<p>foo --- bar</p>\n",
}, 0, 0, HtmlRendererParameters{})
doTestsInlineParam(t, []string{
"foo - bar\n",
"<p>foo &ndash; bar</p>\n",
"foo -- bar\n",
"<p>foo &mdash; bar</p>\n",
"foo --- bar\n",
"<p>foo &mdash;&ndash; bar</p>\n",
}, 0, HTML_USE_SMARTYPANTS|HTML_SMARTYPANTS_DASHES, HtmlRendererParameters{})
doTestsInlineParam(t, []string{
"foo - bar\n",
"<p>foo - bar</p>\n",
"foo -- bar\n",
"<p>foo &ndash; bar</p>\n",
"foo --- bar\n",
"<p>foo &mdash; bar</p>\n",
}, 0, HTML_USE_SMARTYPANTS|HTML_SMARTYPANTS_LATEX_DASHES|HTML_SMARTYPANTS_DASHES,
HtmlRendererParameters{})
doTestsInlineParam(t, []string{
"foo - bar\n",
"<p>foo - bar</p>\n",
"foo -- bar\n",
"<p>foo -- bar</p>\n",
"foo --- bar\n",
"<p>foo --- bar</p>\n",
}, 0,
HTML_USE_SMARTYPANTS|HTML_SMARTYPANTS_LATEX_DASHES,
HtmlRendererParameters{})
}
6 changes: 5 additions & 1 deletion markdown.go
Expand Up @@ -43,7 +43,11 @@ const (
EXTENSION_BACKSLASH_LINE_BREAK // Translate trailing backslashes into line breaks
EXTENSION_RFC7328 // Parse RFC 7328 markdown. Depends on FOOTNOTES extension.

commonHtmlFlags = 0
commonHtmlFlags = 0 |
HTML_USE_SMARTYPANTS |
HTML_SMARTYPANTS_FRACTIONS |
HTML_SMARTYPANTS_DASHES |
HTML_SMARTYPANTS_LATEX_DASHES

commonExtensions = 0 |
EXTENSION_TABLES |
Expand Down

0 comments on commit 4c1c004

Please sign in to comment.