//
// Blackfriday Markdown Processor
// Available at http://github.com/russross/blackfriday
//
// Copyright © 2011 Russ Ross
simple inline test
\n", "*at the* beginning\n", "at the beginning
\n", "at the *end*\n", "at the end
\n", "*try two* in *one line*\n", "try two in one line
\n", "over *two\nlines* test\n", "over two\nlines test
\n", "odd *number of* markers* here\n", "odd number of markers* here
\n", "odd *number\nof* markers* here\n", "odd number\nof markers* here
\n", "simple _inline_ test\n", "simple inline test
\n", "_at the_ beginning\n", "at the beginning
\n", "at the _end_\n", "at the end
\n", "_try two_ in _one line_\n", "try two in one line
\n", "over _two\nlines_ test\n", "over two\nlines test
\n", "odd _number of_ markers_ here\n", "odd number of markers_ here
\n", "odd _number\nof_ markers_ here\n", "odd number\nof markers_ here
\n", "mix of *markers_\n", "mix of *markers_
\n", "*What is A\\* algorithm?*\n", "What is A* algorithm?
\n", "some para_graph with _emphasised_ text.\n", "some para_graph with emphasised text.
\n", "some paragraph with _emphasised_ te_xt.\n", "some paragraph with emphasised te_xt.
\n", "some paragraph with t_wo bi_ts of _emphasised_ text.\n", "some paragraph with two bits of emphasised text.
\n", "un*frigging*believable\n", "unfriggingbelievable
\n", } doTestsInline(t, tests) } func TestNoIntraEmphasis(t *testing.T) { tests := []string{ "some para_graph with _emphasised_ text.\n", "some para_graph with emphasised text.
\n", "un*frigging*believable\n", "un*frigging*believable
\n", } doTestsInlineParam(t, tests, Options{ Extensions: EXTENSION_NO_INTRA_EMPHASIS}, 0, HtmlRendererParameters{}) } func TestReferenceOverride(t *testing.T) { var tests = []string{ "test [ref1][]\n", "test ref1
\n", "test [my ref][ref1]\n", "test my ref
\n", "test [ref2][]\n\n[ref2]: http://www.leftalone.com/ (Ref left alone)\n", "test ref2
\n", "test [ref3][]\n\n[ref3]: http://www.leftalone.com/ (Ref left alone)\n", "test ref3
\n", "test [ref4][]\n\n[ref4]: http://zombo.com/ (You can do anything)\n", "test [ref4][]
\n", "test [!(*http.ServeMux).ServeHTTP][] complicated ref\n", "test !(*http.ServeMux).ServeHTTP complicated ref
\n", "test [ref5][]\n", "test Moo
\n", } doTestsInlineParam(t, tests, Options{ ReferenceOverride: func(reference string) (rv *Reference, overridden bool) { switch reference { case "ref1": // just an overriden reference exists without definition return &Reference{ Link: "http://www.ref1.com/", Title: "Reference 1"}, true case "ref2": // overridden exists and reference defined return &Reference{ Link: "http://www.overridden.com/", Title: "Reference Overridden"}, true case "ref3": // not overridden and reference defined return nil, false case "ref4": // overridden missing and defined return nil, true case "!(*http.ServeMux).ServeHTTP": return &Reference{ Link: "http://localhost:6060/pkg/net/http/#ServeMux.ServeHTTP", Title: "ServeHTTP docs"}, true case "ref5": return &Reference{ Link: "http://www.ref5.com/", Title: "Reference 5", Text: "Moo", }, true } return nil, false }}, 0, HtmlRendererParameters{}) } func TestStrong(t *testing.T) { var tests = []string{ "nothing inline\n", "nothing inline
\n", "simple **inline** test\n", "simple inline test
\n", "**at the** beginning\n", "at the beginning
\n", "at the **end**\n", "at the end
\n", "**try two** in **one line**\n", "try two in one line
\n", "over **two\nlines** test\n", "over two\nlines test
\n", "odd **number of** markers** here\n", "odd number of markers** here
\n", "odd **number\nof** markers** here\n", "odd number\nof markers** here
\n", "simple __inline__ test\n", "simple inline test
\n", "__at the__ beginning\n", "at the beginning
\n", "at the __end__\n", "at the end
\n", "__try two__ in __one line__\n", "try two in one line
\n", "over __two\nlines__ test\n", "over two\nlines test
\n", "odd __number of__ markers__ here\n", "odd number of markers__ here
\n", "odd __number\nof__ markers__ here\n", "odd number\nof markers__ here
\n", "mix of **markers__\n", "mix of **markers__
\n", "**`/usr`** : this folder is named `usr`\n", "/usr
: this folder is named usr
/usr
:
this folder is named usr
triple emphasis
\n", "***triple\nemphasis***\n", "triple\nemphasis
\n", "___triple emphasis___\n", "triple emphasis
\n", "***triple emphasis___\n", "***triple emphasis___
\n", "*__triple emphasis__*\n", "triple emphasis
\n", "__*triple emphasis*__\n", "triple emphasis
\n", "**improper *nesting** is* bad\n", "improper *nesting is* bad
\n", "*improper **nesting* is** bad\n", "*improper nesting* is bad
\n", } doTestsInline(t, tests) } func TestEmphasisLink(t *testing.T) { var tests = []string{ "[first](before) *text[second] (inside)text* [third](after)\n", "\n", "*incomplete [link] definition*\n", "incomplete [link] definition
\n", "*it's [emphasis*] (not link)\n", "it's [emphasis] (not link)
\n", "*it's [emphasis*] and *[asterisk]\n", "it's [emphasis] and *[asterisk]
\n", } doTestsInline(t, tests) } func TestStrikeThrough(t *testing.T) { var tests = []string{ "nothing inline\n", "nothing inline
\n", "simple ~~inline~~ test\n", "simple inline test
at the beginning
at the end
try two in one line
over two\nlines test
odd number of markers~~ here
odd number\nof markers~~ here
source code
source code with spaces
source code with spaces
not here
a `single marker
\n", "a single multi-tick marker with ``` no text\n", "a single multi-tick marker with ``` no text
\n", "markers with ` ` a space\n", "markers with a space
\n", "`source code` and a `stray\n", "source code
and a `stray
source *with* _awkward characters_ in it
split over\ntwo lines
multiple ticks
for the marker
multiple ticks `with` ticks inside
this line
\nhas a break
this line\ndoes not
\n", "this line\\\ndoes not\n", "this line\\\ndoes not
\n", "this line\\ \ndoes not\n", "this line\\\ndoes not
\n", "this has an \nextra space\n", "this has an
\nextra space
this line
\nhas a break
this line\ndoes not
\n", "this line\\\nhas a break\n", "this line
\nhas a break
this line\\\ndoes not
\n", "this has an \nextra space\n", "this has an
\nextra space
[foo]()
\n", "![foo](/bar/)\n", "\n", "![foo with a title](/bar/ \"title\")\n", "\n", "![foo with a title](/bar/\t\"title\")\n", "\n", "![foo with a title](/bar/ \"title\" )\n", "\n", "![foo with a title](/bar/ title with no quotes)\n", "\n", "![](img.jpg)\n", "\n", "[link](url)\n", "\n", "![foo]()\n", "![foo]()
\n", "[a link]\t(/with_a_tab/)\n", "\n", "[a link] (/with_spaces/)\n", "\n", "[text (with) [[nested] (brackets)]](/url/)\n", "text (with) [[nested] (brackets)]
\n", "[text (with) [broken nested] (brackets)]](/url/)\n", "[text (with) broken nested]](/url/)
\n", "[text\nwith a newline](/link/)\n", "\n", "[text in brackets] [followed](/by a link/)\n", "[text in brackets] followed
\n", "[link with\\] a closing bracket](/url/)\n", "\n", "[link with\\[ an opening bracket](/url/)\n", "\n", "[link with\\) a closing paren](/url/)\n", "\n", "[link with\\( an opening paren](/url/)\n", "\n", "[link]( with whitespace)\n", "\n", "[link]( with whitespace )\n", "\n", "[![image](someimage)](with image)\n", "\n", "[link](url \"one quote)\n", "\n", "[link](url 'one quote)\n", "\n", "[link]([disambiguation](http://en.wikipedia.org/wiki/Disambiguation_(disambiguation) is the
\n", "[disambiguation](http://en.wikipedia.org/wiki/Disambiguation_(disambiguation)) is the", "disambiguation is the
\n", "[disambiguation](http://en.wikipedia.org/wiki/Disambiguation_(disambiguation))", "\n", } doLinkTestsInline(t, tests) } func TestRelAttrLink(t *testing.T) { var nofollowTests = []string{ "[foo](http://bar.com/foo/)\n", "\n", "[foo](/bar/)\n", "\n", "[foo](/)\n", "\n", "[foo](./)\n", "\n", "[foo](../)\n", "\n", "[foo](../bar)\n", "\n", } doTestsInlineParam(t, nofollowTests, Options{}, HTML_SAFELINK|HTML_NOFOLLOW_LINKS, HtmlRendererParameters{}) var noreferrerTests = []string{ "[foo](http://bar.com/foo/)\n", "\n", "[foo](/bar/)\n", "\n", } doTestsInlineParam(t, noreferrerTests, Options{}, HTML_SAFELINK|HTML_NOREFERRER_LINKS, HtmlRendererParameters{}) var nofollownoreferrerTests = []string{ "[foo](http://bar.com/foo/)\n", "\n", "[foo](/bar/)\n", "\n", } doTestsInlineParam(t, nofollownoreferrerTests, Options{}, HTML_SAFELINK|HTML_NOFOLLOW_LINKS|HTML_NOREFERRER_LINKS, HtmlRendererParameters{}) } func TestHrefTargetBlank(t *testing.T) { var tests = []string{ // internal link "[foo](/bar/)\n", "\n", "[foo](/)\n", "\n", "[foo](./)\n", "\n", "[foo](./bar)\n", "\n", "[foo](../)\n", "\n", "[foo](../bar)\n", "\n", "[foo](http://example.com)\n", "\n", } doTestsInlineParam(t, tests, Options{}, HTML_SAFELINK|HTML_HREF_TARGET_BLANK, HtmlRendererParameters{}) } func TestSafeInlineLink(t *testing.T) { var tests = []string{ "[foo](/bar/)\n", "\n", "[foo](/)\n", "\n", "[foo](./)\n", "\n", "[foo](../)\n", "\n", "[foo](http://bar/)\n", "\n", "[foo](https://bar/)\n", "\n", "[foo](ftp://bar/)\n", "\n", "[foo](mailto://bar/)\n", "\n", // Not considered safe "[foo](baz://bar/)\n", "foo
\n", } doSafeTestsInline(t, tests) } func TestReferenceLink(t *testing.T) { var tests = []string{ "[link][ref]\n", "[link][ref]
\n", "[link][ref]\n [ref]: /url/ \"title\"\n", "\n", "[link][ref]\n [ref]: /url/\n", "\n", " [ref]: /url/\n", "", " [ref]: /url/\n[ref2]: /url/\n [ref3]: /url/\n", "", " [ref]: /url/\n[ref2]: /url/\n [ref3]: /url/\n [4spaces]: /url/\n", "[4spaces]: /url/\n
\n",
"[hmm](ref2)\n [ref]: /url/\n[ref2]: /url/\n [ref3]: /url/\n",
"\n",
"[ref]\n",
"[ref]
\n", "[ref]\n [ref]: /url/ \"title\"\n", "\n", "[ref]\n [ref]: ../url/ \"title\"\n", "\n", "[link][ref]\n [ref]: /url/", "\n", } doLinkTestsInline(t, tests) } func TestTags(t *testing.T) { var tests = []string{ "a tag\n", "a tag
\n", "tag\n", "tag
\n", "mismatch\n", "mismatch
\n", "aa
ahttp://foo.com/
\n", ">http://foo.com/\n", "\n\n\n", "> http://foo.com/\n", "
\n\n\n", "go to
go to http://foo.com/
\n", "a securea secure https://link.org
\n", "an emailan email some@one.com
\n", "an emailan email some@one.com
\n", "an emailan email some@one.com
\n", "an ftpan ftp ftp://old.com
\n", "an ftpan ftp ftp:old.com
\n", "a link witha link with " + "http://new.com?query=foo&bar
\n", "quotes mean a tagquotes mean a tag
quotes mean a tag
unless escaped " + "http://new.com?query="foo"&bar
\n", "even a > can be escapedeven a > can be escaped " + "http://new.com?q=>&etc
\n", "http://fancy.com\n", "\n", "This is a link\n", "\n", "http://www.fancy.com/A_B.pdf\n", "\n", "(http://www.fancy.com/A_B (\n", "\n", "(http://www.fancy.com/A_B (part two: http://www.fancy.com/A_B)).\n", "(http://www.fancy.com/A_B (part two: http://www.fancy.com/A_B)).
\n", "http://www.foo.comhttp://foo.com/viewtopic.php?f=18&t=297
\n", "http://foo.com/viewtopic.php?param="18"zz", "http://foo.com/viewtopic.php?param="18"zz
\n", "http://foo.com/viewtopic.php?param="18"", "http://foo.com/viewtopic.php?param="18"
\n", } doLinkTestsInline(t, tests) } var footnoteTests = []string{ "testing footnotes.[^a]\n\n[^a]: This is the note\n", `testing footnotes.1
testing long1 notes.
No longer in the footnote
Paragraph 1
Paragraph 2
some code
Paragraph 3
omg
what happens here
testing inline1 notes.
testing multiple1 types2 of notes3
the first deferred note
which happens to be a block
the footnote text.
may be multiple paragraphs.
empty footnote1
\nSome text.1
\nThis is exciting!1
testing footnotes.1
test footnotes the second.2
`, } func TestFootnotes(t *testing.T) { doTestsInlineParam(t, footnoteTests, Options{Extensions: EXTENSION_FOOTNOTES}, 0, HtmlRendererParameters{}) } func TestFootnotesWithParameters(t *testing.T) { tests := make([]string, len(footnoteTests)) prefix := "testPrefix" returnText := "ret" re := regexp.MustCompile(`(?ms)Paragraph.1
This uses footnote A.1
This uses footnote C.2
`, } doTestsInlineParam(t, tests, Options{Extensions: EXTENSION_FOOTNOTES}, 0, HtmlRendererParameters{}) } func TestInlineComments(t *testing.T) { var tests = []string{ "Hello \n", "Hello
\n", "Hello ", "Hello
\n", "Hello \n", "Hello
\n", "Hello \na", "Hello \na
\n", "* list \n", "comment
\n", "blahblah\n\nrhubarb\n", "blahblah\n\nrhubarb
\n", } doTestsInlineParam(t, tests, Options{}, HTML_USE_SMARTYPANTS|HTML_SMARTYPANTS_DASHES, HtmlRendererParameters{}) } func TestSmartDoubleQuotes(t *testing.T) { var tests = []string{ "this should be normal \"quoted\" text.\n", "this should be normal “quoted” text.
\n", "this \" single double\n", "this “ single double
\n", "two pair of \"some\" quoted \"text\".\n", "two pair of “some” quoted “text”.
\n"} doTestsInlineParam(t, tests, Options{}, HTML_USE_SMARTYPANTS, HtmlRendererParameters{}) } func TestSmartDoubleQuotesNbsp(t *testing.T) { var tests = []string{ "this should be normal \"quoted\" text.\n", "this should be normal “ quoted ” text.
\n", "this \" single double\n", "this “ single double
\n", "two pair of \"some\" quoted \"text\".\n", "two pair of “ some ” quoted “ text ”.
\n"} doTestsInlineParam(t, tests, Options{}, HTML_USE_SMARTYPANTS|HTML_SMARTYPANTS_QUOTES_NBSP, HtmlRendererParameters{}) } func TestSmartAngledDoubleQuotes(t *testing.T) { var tests = []string{ "this should be angled \"quoted\" text.\n", "this should be angled «quoted» text.
\n", "this \" single double\n", "this « single double
\n", "two pair of \"some\" quoted \"text\".\n", "two pair of «some» quoted «text».
\n"} doTestsInlineParam(t, tests, Options{}, HTML_USE_SMARTYPANTS|HTML_SMARTYPANTS_ANGLED_QUOTES, HtmlRendererParameters{}) } func TestSmartAngledDoubleQuotesNbsp(t *testing.T) { var tests = []string{ "this should be angled \"quoted\" text.\n", "this should be angled « quoted » text.
\n", "this \" single double\n", "this « single double
\n", "two pair of \"some\" quoted \"text\".\n", "two pair of « some » quoted « text ».
\n"} doTestsInlineParam(t, tests, Options{}, HTML_USE_SMARTYPANTS|HTML_SMARTYPANTS_ANGLED_QUOTES|HTML_SMARTYPANTS_QUOTES_NBSP, HtmlRendererParameters{}) } func TestSmartFractions(t *testing.T) { var tests = []string{ "1/2, 1/4 and 3/4; 1/4th and 3/4ths\n", "½, ¼ and ¾; ¼th and ¾ths
\n", "1/2/2015, 1/4/2015, 3/4/2015; 2015/1/2, 2015/1/4, 2015/3/4.\n", "1/2/2015, 1/4/2015, 3/4/2015; 2015/1/2, 2015/1/4, 2015/3/4.
\n"} doTestsInlineParam(t, tests, Options{}, HTML_USE_SMARTYPANTS, HtmlRendererParameters{}) tests = []string{ "1/2, 2/3, 81/100 and 1000000/1048576.\n", "1⁄2, 2⁄3, 81⁄100 and 1000000⁄1048576.
\n", "1/2/2015, 1/4/2015, 3/4/2015; 2015/1/2, 2015/1/4, 2015/3/4.\n", "1/2/2015, 1/4/2015, 3/4/2015; 2015/1/2, 2015/1/4, 2015/3/4.
\n"} doTestsInlineParam(t, tests, Options{}, HTML_USE_SMARTYPANTS|HTML_SMARTYPANTS_FRACTIONS, HtmlRendererParameters{}) } func TestDisableSmartDashes(t *testing.T) { doTestsInlineParam(t, []string{ "foo - bar\n", "foo - bar
\n", "foo -- bar\n", "foo -- bar
\n", "foo --- bar\n", "foo --- bar
\n", }, Options{}, 0, HtmlRendererParameters{}) doTestsInlineParam(t, []string{ "foo - bar\n", "foo – bar
\n", "foo -- bar\n", "foo — bar
\n", "foo --- bar\n", "foo —– bar
\n", }, Options{}, HTML_USE_SMARTYPANTS|HTML_SMARTYPANTS_DASHES, HtmlRendererParameters{}) doTestsInlineParam(t, []string{ "foo - bar\n", "foo - bar
\n", "foo -- bar\n", "foo – bar
\n", "foo --- bar\n", "foo — bar
\n", }, Options{}, HTML_USE_SMARTYPANTS|HTML_SMARTYPANTS_LATEX_DASHES|HTML_SMARTYPANTS_DASHES, HtmlRendererParameters{}) doTestsInlineParam(t, []string{ "foo - bar\n", "foo - bar
\n", "foo -- bar\n", "foo -- bar
\n", "foo --- bar\n", "foo --- bar
\n", }, Options{}, HTML_USE_SMARTYPANTS|HTML_SMARTYPANTS_LATEX_DASHES, HtmlRendererParameters{}) } func BenchmarkSmartDoubleQuotes(b *testing.B) { for i := 0; i < b.N; i++ { runMarkdownInline("this should be normal \"quoted\" text.\n", Options{}, HTML_USE_SMARTYPANTS, HtmlRendererParameters{}) } }