"),
verb("or here: \\\\
"),
para("Backtick: \\`
"),
para("Asterisk: \\*
"),
para("Underscore: \\_
"),
para("Left brace: \\{
"),
para("Right brace: \\}
"),
para("Left bracket: \\[
"),
para("Right bracket: \\]
"),
para("Left paren: \\(
"),
para("Right paren: \\)
"),
para("Greater-than: \\>
"),
para("Hash: \\#
"),
para("Period: \\.
"),
para("Bang: \\!
"),
para("Plus: \\+
"),
para("Minus: \\-
"),
para("These should get escaped, even though they're matching pairs for\n" +
"other Markdown constructs:"),
para("\*asterisks\*"),
para("\_underscores\_"),
para("`backticks`"),
para("This is a code span with a literal backslash-backtick " +
"sequence: \\`
"),
para("This is a tag with unescaped backticks " +
"bar."),
para("This is a tag with backslashes " +
"bar."))
assert_equal expected, doc
end
def test_blockquotes_with_code_blocks
input = File.read "#{MARKDOWN_TEST_PATH}/Blockquotes with code blocks.text"
doc = @parser.parse input
expected =
doc(
block(
para("Example:"),
verb("sub status {\n",
" print \"working\";\n",
"}\n"),
para("Or:"),
verb("sub status {\n",
" return \"working\";\n",
"}\n")))
assert_equal expected, doc
end
def test_code_blocks
input = File.read "#{MARKDOWN_TEST_PATH}/Code Blocks.text"
doc = @parser.parse input
expected =
doc(
verb("code block on the first line\n"),
para("Regular text."),
verb("code block indented by spaces\n"),
para("Regular text."),
verb("the lines in this block \n",
"all contain trailing spaces \n"),
para("Regular Text."),
verb("code block on the last line\n"))
assert_equal expected, doc
end
def test_code_spans
input = File.read "#{MARKDOWN_TEST_PATH}/Code Spans.text"
doc = @parser.parse input
expected = doc(
para(" content of attribute \">
"),
para("Fix for backticks within HTML tag: " +
"like this"),
para("Here's how you put `backticks`
in a code span."))
assert_equal expected, doc
end
def test_hard_wrapped_paragraphs_with_list_like_lines
input = File.read "#{MARKDOWN_TEST_PATH}/Hard-wrapped paragraphs with list-like lines.text"
doc = @parser.parse input
expected =
doc(
para("In Markdown 1.0.0 and earlier. Version\n" +
"8. This line turns into a list item.\n" +
"Because a hard-wrapped line in the\n" +
"middle of a paragraph looked like a\n" +
"list item."),
para("Here's one with a bullet.\n" +
"* criminey."))
assert_equal expected, doc
end
def test_horizontal_rules
input = File.read "#{MARKDOWN_TEST_PATH}/Horizontal rules.text"
doc = @parser.parse input
expected =
doc(
para("Dashes:"),
rule(1),
rule(1),
rule(1),
rule(1),
verb("---\n"),
rule(1),
rule(1),
rule(1),
rule(1),
verb("- - -\n"),
para("Asterisks:"),
rule(1),
rule(1),
rule(1),
rule(1),
verb("***\n"),
rule(1),
rule(1),
rule(1),
rule(1),
verb("* * *\n"),
para("Underscores:"),
rule(1),
rule(1),
rule(1),
rule(1),
verb("___\n"),
rule(1),
rule(1),
rule(1),
rule(1),
verb("_ _ _\n"))
assert_equal expected, doc
end
def test_inline_html_advanced
input = File.read "#{MARKDOWN_TEST_PATH}/Inline HTML (Advanced).text"
@parser.html = true
doc = @parser.parse input
expected =
doc(
para("Simple block on one line:"),
raw("foo"),
para("And nested without indentation:"),
raw(<<-RAW.chomp))
foo
bar
RAW
assert_equal expected, doc
end
def test_inline_html_simple
input = File.read "#{MARKDOWN_TEST_PATH}/Inline HTML (Simple).text"
@parser.html = true
doc = @parser.parse input
expected =
doc(
para("Here's a simple block:"),
raw("\n\tfoo\n"),
para("This should be a code block, though:"),
verb("\n",
"\tfoo\n",
"\n"),
para("As should this:"),
verb("foo\n"),
para("Now, nested:"),
raw("\n\t\n\t\t\n\t\t\tfoo\n" +
"\t\t\n\t\n"),
para("This should just be an HTML comment:"),
raw(""),
para("Multiline:"),
raw(""),
para("Code block:"),
verb("\n"),
para("Just plain comment, with trailing spaces on the line:"),
raw(""),
para("Code:"),
verb("
\n"),
para("Hr's:"),
raw("
"),
raw("
"),
raw("
"),
raw("
"),
raw("
"),
raw("
"),
raw("
"),
raw("
"),
raw("
"))
assert_equal expected, doc
end
def test_inline_html_comments
input = File.read "#{MARKDOWN_TEST_PATH}/Inline HTML comments.text"
doc = @parser.parse input
expected =
doc(
para("Paragraph one."),
raw(""),
raw(""),
para("Paragraph two."),
raw(""),
para("The end."))
assert_equal expected, doc
end
def test_links_inline_style
input = File.read "#{MARKDOWN_TEST_PATH}/Links, inline style.text"
doc = @parser.parse input
expected =
doc(
para("Just a {URL}[/url/]."),
para("{URL and title}[/url/]."),
para("{URL and title}[/url/]."),
para("{URL and title}[/url/]."),
para("{URL and title}[/url/]."),
para("{Empty}[]."))
assert_equal expected, doc
end
def test_links_reference_style
input = File.read "#{MARKDOWN_TEST_PATH}/Links, reference style.text"
doc = @parser.parse input
expected =
doc(
para("Foo {bar}[/url/]."),
para("Foo {bar}[/url/]."),
para("Foo {bar}[/url/]."),
para("With {embedded [brackets]}[/url/]."),
para("Indented {once}[/url]."),
para("Indented {twice}[/url]."),
para("Indented {thrice}[/url]."),
para("Indented [four][] times."),
verb("[four]: /url\n"),
rule(1),
para("{this}[foo] should work"),
para("So should {this}[foo]."),
para("And {this}[foo]."),
para("And {this}[foo]."),
para("And {this}[foo]."),
para("But not [that] []."),
para("Nor [that][]."),
para("Nor [that]."),
para("[Something in brackets like {this}[foo] should work]"),
para("[Same with {this}[foo].]"),
para("In this case, {this}[/somethingelse/] points to something else."),
para("Backslashing should suppress [this] and [this]."),
rule(1),
para("Here's one where the {link breaks}[/url/] across lines."),
para("Here's another where the {link breaks}[/url/] across lines, " +
"but with a line-ending space."))
assert_equal expected, doc
end
def test_links_shortcut_references
input = File.read "#{MARKDOWN_TEST_PATH}/Links, shortcut references.text"
doc = @parser.parse input
expected =
doc(
para("This is the {simple case}[/simple]."),
para("This one has a {line break}[/foo]."),
para("This one has a {line break}[/foo] with a line-ending space."),
para("{this}[/that] and the {other}[/other]"))
assert_equal expected, doc
end
def test_literal_quotes_in_titles
input = File.read "#{MARKDOWN_TEST_PATH}/Literal quotes in titles.text"
doc = @parser.parse input
# TODO support title attribute
expected =
doc(
para("Foo {bar}[/url/]."),
para("Foo {bar}[/url/]."))
assert_equal expected, doc
end
def test_markdown_documentation_basics
input = File.read "#{MARKDOWN_TEST_PATH}/Markdown Documentation - Basics.text"
doc = @parser.parse input
expected =
doc(
head(1, "Markdown: Basics"),
raw(<<-RAW.chomp),
RAW
head(2, "Getting the Gist of Markdown's Formatting Syntax"),
para("This page offers a brief overview of what it's like to use Markdown.\n" +
"The {syntax page}[/projects/markdown/syntax] provides complete, detailed documentation for\n" +
"every feature, but Markdown should be very easy to pick up simply by\n" +
"looking at a few examples of it in action. The examples on this page\n" +
"are written in a before/after style, showing example syntax and the\n" +
"HTML output produced by Markdown."),
para("It's also helpful to simply try Markdown out; the {Dingus}[/projects/markdown/dingus] is a\n" +
"web application that allows you type your own Markdown-formatted text\n" +
"and translate it to XHTML."),
para("Note: This document is itself written using Markdown; you\n" +
"can {see the source for it by adding '.text' to the URL}[/projects/markdown/basics.text]."),
head(2, "Paragraphs, Headers, Blockquotes"),
para("A paragraph is simply one or more consecutive lines of text, separated\n" +
"by one or more blank lines. (A blank line is any line that looks like a\n" +
"blank line -- a line containing nothing spaces or tabs is considered\n" +
"blank.) Normal paragraphs should not be intended with spaces or tabs."),
para("Markdown offers two styles of headers: _Setext_ and _atx_.\n" +
"Setext-style headers for
and
are created by\n" +
"\"underlining\" with equal signs (=
) and hyphens (-
), respectively.\n" +
"To create an atx-style header, you put 1-6 hash marks (#
) at the\n" +
"beginning of the line -- the number of hashes equals the resulting\n" +
"HTML header level."),
para("Blockquotes are indicated using email-style '>
' angle brackets."),
para("Markdown:"),
verb("A First Level Header\n",
"====================\n",
"\n",
"A Second Level Header\n",
"---------------------\n",
"\n",
"Now is the time for all good men to come to\n",
"the aid of their country. This is just a\n",
"regular paragraph.\n",
"\n",
"The quick brown fox jumped over the lazy\n",
"dog's back.\n",
"\n",
"### Header 3\n",
"\n",
"> This is a blockquote.\n",
"> \n",
"> This is the second paragraph in the blockquote.\n",
">\n",
"> ## This is an H2 in a blockquote\n"),
para("Output:"),
verb("A First Level Header
\n",
"\n",
"A Second Level Header
\n",
"\n",
"Now is the time for all good men to come to\n",
"the aid of their country. This is just a\n",
"regular paragraph.
\n",
"\n",
"The quick brown fox jumped over the lazy\n",
"dog's back.
\n",
"\n",
"Header 3
\n",
"\n",
"\n",
" This is a blockquote.
\n",
"\n",
" This is the second paragraph in the blockquote.
\n",
"\n",
" This is an H2 in a blockquote
\n",
"
\n"),
head(3, "Phrase Emphasis"),
para("Markdown uses asterisks and underscores to indicate spans of emphasis."),
para("Markdown:"),
verb("Some of these words *are emphasized*.\n",
"Some of these words _are emphasized also_.\n",
"\n",
"Use two asterisks for **strong emphasis**.\n",
"Or, if you prefer, __use two underscores instead__.\n"),
para("Output:"),
verb("Some of these words are emphasized.\n",
"Some of these words are emphasized also.
\n",
"\n",
"Use two asterisks for strong emphasis.\n",
"Or, if you prefer, use two underscores instead.
\n"),
head(2, "Lists"),
para("Unordered (bulleted) lists use asterisks, pluses, and hyphens (*
,\n" +
"+
, and -
) as list markers. These three markers are\n" +
"interchangeable; this:"),
verb("* Candy.\n",
"* Gum.\n",
"* Booze.\n"),
para("this:"),
verb("+ Candy.\n",
"+ Gum.\n",
"+ Booze.\n"),
para("and this:"),
verb("- Candy.\n",
"- Gum.\n",
"- Booze.\n"),
para("all produce the same output:"),
verb("\n",
"- Candy.
\n",
"- Gum.
\n",
"- Booze.
\n",
"
\n"),
para("Ordered (numbered) lists use regular numbers, followed by periods, as\n" +
"list markers:"),
verb("1. Red\n",
"2. Green\n",
"3. Blue\n"),
para("Output:"),
verb("\n",
"- Red
\n",
"- Green
\n",
"- Blue
\n",
"
\n"),
para("If you put blank lines between items, you'll get
tags for the\n" +
"list item text. You can create multi-paragraph list items by indenting\n" +
"the paragraphs by 4 spaces or 1 tab:"),
verb("* A list item.\n",
"\n",
" With multiple paragraphs.\n",
"\n",
"* Another item in the list.\n"),
para("Output:"),
verb("\n",
"A list item.
\n",
"With multiple paragraphs.
\n",
"Another item in the list.
\n",
"
\n"),
head(3, "Links"),
para("Markdown supports two styles for creating links: _inline_ and\n" +
"_reference_. With both styles, you use square brackets to delimit the\n" +
"text you want to turn into a link."),
para("Inline-style links use parentheses immediately after the link text.\n" +
"For example:"),
verb("This is an [example link](http://example.com/).\n"),
para("Output:"),
verb("This is an \n",
"example link.
\n"),
para("Optionally, you may include a title attribute in the parentheses:"),
verb("This is an [example link](http://example.com/ \"With a Title\").\n"),
para("Output:"),
verb("This is an \n",
"example link.
\n"),
para("Reference-style links allow you to refer to your links by names, which\n" +
"you define elsewhere in your document:"),
verb("I get 10 times more traffic from [Google][1] than from\n",
"[Yahoo][2] or [MSN][3].\n",
"\n",
"[1]: http://google.com/ \"Google\"\n",
"[2]: http://search.yahoo.com/ \"Yahoo Search\"\n",
"[3]: http://search.msn.com/ \"MSN Search\"\n"),
para("Output:"),
verb("I get 10 times more traffic from Google than from Yahoo or MSN.
\n"),
para("The title attribute is optional. Link names may contain letters,\n" +
"numbers and spaces, but are _not_ case sensitive:"),
verb("I start my morning with a cup of coffee and\n",
"[The New York Times][NY Times].\n",
"\n",
"[ny times]: http://www.nytimes.com/\n"),
para("Output:"),
verb("I start my morning with a cup of coffee and\n",
"The New York Times.
\n"),
head(3, "Images"),
para("Image syntax is very much like link syntax."),
para("Inline (titles are optional):"),
verb("![alt text](/path/to/img.jpg \"Title\")\n"),
para("Reference-style:"),
verb("![alt text][id]\n",
"\n",
"[id]: /path/to/img.jpg \"Title\"\n"),
para("Both of the above examples produce the same output:"),
verb("\n"),
head(3, "Code"),
para("In a regular paragraph, you can create code span by wrapping text in\n" +
"backtick quotes. Any ampersands (&
) and angle brackets (<
or\n" +
">
) will automatically be translated into HTML entities. This makes\n" +
"it easy to use Markdown to write about HTML example code:"),
verb(
"I strongly recommend against using any `