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

Commit ff621c6

Browse files
committed
Integrate smartypants.go from blackfriday, adjust tests.
1 parent 849458a commit ff621c6

File tree

4 files changed

+531
-15
lines changed

4 files changed

+531
-15
lines changed

html.go

Lines changed: 53 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,21 @@ import (
1414

1515
// Html renderer configuration options.
1616
const (
17-
HTML_SKIP_HTML = 1 << iota // skip preformatted HTML blocks
18-
HTML_SKIP_STYLE // skip embedded <style> elements
19-
HTML_SKIP_IMAGES // skip embedded images
20-
HTML_SKIP_LINKS // skip all links
21-
HTML_SAFELINK // only link to trusted protocols
22-
HTML_NOFOLLOW_LINKS // only link with rel="nofollow"
23-
HTML_HREF_TARGET_BLANK // add a blank target
24-
HTML_OMIT_CONTENTS // skip the main contents (for a standalone table of contents)
25-
HTML_COMPLETE_PAGE // generate a complete HTML page
26-
HTML_FOOTNOTE_RETURN_LINKS // generate a link at the end of a footnote to return to the source
17+
HTML_SKIP_HTML = 1 << iota // skip preformatted HTML blocks
18+
HTML_SKIP_STYLE // skip embedded <style> elements
19+
HTML_SKIP_IMAGES // skip embedded images
20+
HTML_SKIP_LINKS // skip all links
21+
HTML_SAFELINK // only link to trusted protocols
22+
HTML_NOFOLLOW_LINKS // only link with rel="nofollow"
23+
HTML_HREF_TARGET_BLANK // add a blank target
24+
HTML_OMIT_CONTENTS // skip the main contents (for a standalone table of contents)
25+
HTML_COMPLETE_PAGE // generate a complete HTML page
26+
HTML_USE_SMARTYPANTS // enable smart punctuation substitutions
27+
HTML_SMARTYPANTS_FRACTIONS // enable smart fractions (with HTML_USE_SMARTYPANTS)
28+
HTML_SMARTYPANTS_DASHES // enable smart dashes (with HTML_USE_SMARTYPANTS)
29+
HTML_SMARTYPANTS_LATEX_DASHES // enable LaTeX-style dashes (with HTML_USE_SMARTYPANTS and HTML_SMARTYPANTS_DASHES)
30+
HTML_SMARTYPANTS_ANGLED_QUOTES // enable angled double quotes (with HTML_USE_SMARTYPANTS) for double quotes rendering
31+
HTML_FOOTNOTE_RETURN_LINKS // generate a link at the end of a footnote to return to the source
2732
)
2833

2934
var (
@@ -75,6 +80,8 @@ type html struct {
7580

7681
// (@good) example list group counter
7782
group map[string]int
83+
84+
smartypants *smartypantsRenderer
7885
}
7986

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

116123
index: make(map[idx][]string),
117124
group: make(map[string]int),
125+
126+
smartypants: smartypants(flags),
118127
}
119128
}
120129

@@ -958,7 +967,40 @@ func (options *html) References(out *bytes.Buffer, citations map[string]*citatio
958967
}
959968

960969
func (options *html) NormalText(out *bytes.Buffer, text []byte) {
961-
attrEscape(out, text)
970+
if options.flags&HTML_USE_SMARTYPANTS != 0 {
971+
options.Smartypants(out, text)
972+
} else {
973+
attrEscape(out, text)
974+
}
975+
}
976+
977+
func (options *html) Smartypants(out *bytes.Buffer, text []byte) {
978+
smrt := smartypantsData{false, false}
979+
980+
// first do normal entity escaping
981+
var escaped bytes.Buffer
982+
attrEscape(&escaped, text)
983+
text = escaped.Bytes()
984+
985+
mark := 0
986+
for i := 0; i < len(text); i++ {
987+
if action := options.smartypants[text[i]]; action != nil {
988+
if i > mark {
989+
out.Write(text[mark:i])
990+
}
991+
992+
previousChar := byte(0)
993+
if i > 0 {
994+
previousChar = text[i-1]
995+
}
996+
i += action(out, &smrt, previousChar, text[i:])
997+
mark = i + 1
998+
}
999+
}
1000+
1001+
if mark < len(text) {
1002+
out.Write(text[mark:])
1003+
}
9621004
}
9631005

9641006
func (options *html) DocumentHeader(out *bytes.Buffer, first bool) {

inline_test.go

Lines changed: 82 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,6 @@ func TestEmphasis(t *testing.T) {
169169

170170
"*What is A\\* algorithm?*\n",
171171
"<p><em>What is A* algorithm?</em></p>\n",
172-
173172
}
174173
doTestsInline(t, tests)
175174
}
@@ -1075,7 +1074,7 @@ func TestNestedFootnotes(t *testing.T) {
10751074
func TestInlineComments(t *testing.T) {
10761075
var tests = []string{
10771076
"Hello <!-- there ->\n",
1078-
"<p>Hello &lt;!-- there -&gt;</p>\n",
1077+
"<p>Hello &lt;!&mdash; there &ndash;&gt;</p>\n",
10791078

10801079
"Hello <!-- there -->\n",
10811080
"<p>Hello <!-- there --></p>\n",
@@ -1098,7 +1097,7 @@ func TestInlineComments(t *testing.T) {
10981097
"blahblah\n<!--- foo -->\nrhubarb\n",
10991098
"<p>blahblah\n<!--- foo -->\nrhubarb</p>\n",
11001099
}
1101-
doTestsInlineParam(t, tests, 0, 0, HtmlRendererParameters{})
1100+
doTestsInlineParam(t, tests, 0, HTML_USE_SMARTYPANTS|HTML_SMARTYPANTS_DASHES, HtmlRendererParameters{})
11021101
}
11031102

11041103
func TestCitationXML(t *testing.T) {
@@ -1163,3 +1162,83 @@ func TestShortReferenceXML(t *testing.T) {
11631162
}
11641163
doTestsInlineXML(t, tests)
11651164
}
1165+
1166+
func TestSmartDoubleQuotes(t *testing.T) {
1167+
var tests = []string{
1168+
"this should be normal \"quoted\" text.\n",
1169+
"<p>this should be normal &ldquo;quoted&rdquo; text.</p>\n",
1170+
"this \" single double\n",
1171+
"<p>this &ldquo; single double</p>\n",
1172+
"two pair of \"some\" quoted \"text\".\n",
1173+
"<p>two pair of &ldquo;some&rdquo; quoted &ldquo;text&rdquo;.</p>\n"}
1174+
1175+
doTestsInlineParam(t, tests, 0, HTML_USE_SMARTYPANTS, HtmlRendererParameters{})
1176+
}
1177+
1178+
func TestSmartAngledDoubleQuotes(t *testing.T) {
1179+
var tests = []string{
1180+
"this should be angled \"quoted\" text.\n",
1181+
"<p>this should be angled &laquo;quoted&raquo; text.</p>\n",
1182+
"this \" single double\n",
1183+
"<p>this &laquo; single double</p>\n",
1184+
"two pair of \"some\" quoted \"text\".\n",
1185+
"<p>two pair of &laquo;some&raquo; quoted &laquo;text&raquo;.</p>\n"}
1186+
1187+
doTestsInlineParam(t, tests, 0, HTML_USE_SMARTYPANTS|HTML_SMARTYPANTS_ANGLED_QUOTES, HtmlRendererParameters{})
1188+
}
1189+
1190+
func TestSmartFractions(t *testing.T) {
1191+
var tests = []string{
1192+
"1/2, 1/4 and 3/4; 1/4th and 3/4ths\n",
1193+
"<p>&frac12;, &frac14; and &frac34;; &frac14;th and &frac34;ths</p>\n",
1194+
"1/2/2015, 1/4/2015, 3/4/2015; 2015/1/2, 2015/1/4, 2015/3/4.\n",
1195+
"<p>1/2/2015, 1/4/2015, 3/4/2015; 2015/1/2, 2015/1/4, 2015/3/4.</p>\n"}
1196+
1197+
doTestsInlineParam(t, tests, 0, HTML_USE_SMARTYPANTS, HtmlRendererParameters{})
1198+
1199+
tests = []string{
1200+
"1/2, 2/3, 81/100 and 1000000/1048576.\n",
1201+
"<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",
1202+
"1/2/2015, 1/4/2015, 3/4/2015; 2015/1/2, 2015/1/4, 2015/3/4.\n",
1203+
"<p>1/2/2015, 1/4/2015, 3/4/2015; 2015/1/2, 2015/1/4, 2015/3/4.</p>\n"}
1204+
1205+
doTestsInlineParam(t, tests, 0, HTML_USE_SMARTYPANTS|HTML_SMARTYPANTS_FRACTIONS, HtmlRendererParameters{})
1206+
}
1207+
1208+
func TestDisableSmartDashes(t *testing.T) {
1209+
doTestsInlineParam(t, []string{
1210+
"foo - bar\n",
1211+
"<p>foo - bar</p>\n",
1212+
"foo -- bar\n",
1213+
"<p>foo -- bar</p>\n",
1214+
"foo --- bar\n",
1215+
"<p>foo --- bar</p>\n",
1216+
}, 0, 0, HtmlRendererParameters{})
1217+
doTestsInlineParam(t, []string{
1218+
"foo - bar\n",
1219+
"<p>foo &ndash; bar</p>\n",
1220+
"foo -- bar\n",
1221+
"<p>foo &mdash; bar</p>\n",
1222+
"foo --- bar\n",
1223+
"<p>foo &mdash;&ndash; bar</p>\n",
1224+
}, 0, HTML_USE_SMARTYPANTS|HTML_SMARTYPANTS_DASHES, HtmlRendererParameters{})
1225+
doTestsInlineParam(t, []string{
1226+
"foo - bar\n",
1227+
"<p>foo - bar</p>\n",
1228+
"foo -- bar\n",
1229+
"<p>foo &ndash; bar</p>\n",
1230+
"foo --- bar\n",
1231+
"<p>foo &mdash; bar</p>\n",
1232+
}, 0, HTML_USE_SMARTYPANTS|HTML_SMARTYPANTS_LATEX_DASHES|HTML_SMARTYPANTS_DASHES,
1233+
HtmlRendererParameters{})
1234+
doTestsInlineParam(t, []string{
1235+
"foo - bar\n",
1236+
"<p>foo - bar</p>\n",
1237+
"foo -- bar\n",
1238+
"<p>foo -- bar</p>\n",
1239+
"foo --- bar\n",
1240+
"<p>foo --- bar</p>\n",
1241+
}, 0,
1242+
HTML_USE_SMARTYPANTS|HTML_SMARTYPANTS_LATEX_DASHES,
1243+
HtmlRendererParameters{})
1244+
}

markdown.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,11 @@ const (
4343
EXTENSION_BACKSLASH_LINE_BREAK // Translate trailing backslashes into line breaks
4444
EXTENSION_RFC7328 // Parse RFC 7328 markdown. Depends on FOOTNOTES extension.
4545

46-
commonHtmlFlags = 0
46+
commonHtmlFlags = 0 |
47+
HTML_USE_SMARTYPANTS |
48+
HTML_SMARTYPANTS_FRACTIONS |
49+
HTML_SMARTYPANTS_DASHES |
50+
HTML_SMARTYPANTS_LATEX_DASHES
4751

4852
commonExtensions = 0 |
4953
EXTENSION_TABLES |

0 commit comments

Comments
 (0)