From f27413219e4183af2da1a8d7e443cc1b732dd4b6 Mon Sep 17 00:00:00 2001 From: Robin Ward <robin.ward@gmail.com> Date: Wed, 11 Sep 2013 15:52:37 -0400 Subject: [PATCH] Support for MDTest --- .../discourse/components/markdown.js | 5 +- .../discourse/dialects/bbcode_dialect.js | 5 - .../dialects/bold_italics_dialect.js | 6 + .../javascripts/discourse/dialects/dialect.js | 86 +- .../discourse/dialects/github_code_dialect.js | 10 +- .../javascripts/discourse/dialects/html.js | 8 + .../discourse/dialects/mention_dialect.js | 1 - .../discourse/dialects/newline_dialect.js | 2 +- .../discourse/dialects/onebox_dialect.js | 1 - .../discourse/dialects/quote_dialect.js | 3 +- lib/pretty_text.rb | 43 +- spec/components/pretty_text_spec.rb | 2 +- spec/models/post_analyzer_spec.rb | 2 +- spec/models/post_spec.rb | 2 +- test/javascripts/components/bbcode_test.js | 5 + test/javascripts/components/markdown_test.js | 34 +- .../fixtures/Amps and angle encoding.text | 21 + .../fixtures/Amps and angle encoding.xhtml | 22 + .../mdtest/fixtures/Auto links.text | 13 + .../mdtest/fixtures/Auto links.xhtml | 18 + .../mdtest/fixtures/Backslash escapes.text | 120 +++ .../mdtest/fixtures/Backslash escapes.xhtml | 125 +++ .../Blockquotes with code blocks.text | 11 + .../Blockquotes with code blocks.xhtml | 20 + .../mdtest/fixtures/Code Blocks.text | 14 + .../mdtest/fixtures/Code Blocks.xhtml | 17 + .../mdtest/fixtures/Code Spans.text | 5 + .../mdtest/fixtures/Code Spans.xhtml | 12 + ...apped paragraphs with list-like lines.text | 8 + ...pped paragraphs with list-like lines.xhtml | 8 + .../mdtest/fixtures/Horizontal rules.text | 67 ++ .../mdtest/fixtures/Horizontal rules.xhtml | 71 ++ test/javascripts/mdtest/fixtures/Images.text | 26 + test/javascripts/mdtest/fixtures/Images.xhtml | 21 + .../fixtures/Inline HTML (Advanced).text | 30 + .../fixtures/Inline HTML (Advanced).xhtml | 36 + .../mdtest/fixtures/Inline HTML (Simple).text | 54 + .../fixtures/Inline HTML (Simple).xhtml | 63 ++ .../mdtest/fixtures/Inline HTML comments.text | 13 + .../fixtures/Inline HTML comments.xhtml | 13 + .../mdtest/fixtures/Links, inline style.text | 24 + .../mdtest/fixtures/Links, inline style.xhtml | 28 + .../fixtures/Links, reference style.text | 71 ++ .../fixtures/Links, reference style.xhtml | 52 + .../fixtures/Links, shortcut references.text | 20 + .../fixtures/Links, shortcut references.xhtml | 9 + .../fixtures/Literal quotes in titles.text | 7 + .../fixtures/Literal quotes in titles.xhtml | 3 + .../Markdown Documentation - Basics.text | 306 ++++++ .../Markdown Documentation - Basics.xhtml | 319 ++++++ .../Markdown Documentation - Syntax.text | 888 ++++++++++++++++ .../Markdown Documentation - Syntax.xhtml | 949 ++++++++++++++++++ .../mdtest/fixtures/Nested blockquotes.text | 5 + .../mdtest/fixtures/Nested blockquotes.xhtml | 9 + .../fixtures/Ordered and unordered lists.text | 131 +++ .../Ordered and unordered lists.xhtml | 148 +++ .../fixtures/Strong and em together.text | 7 + .../fixtures/Strong and em together.xhtml | 7 + test/javascripts/mdtest/fixtures/Tabs.text | 21 + test/javascripts/mdtest/fixtures/Tabs.xhtml | 25 + .../javascripts/mdtest/fixtures/Tidyness.text | 5 + .../mdtest/fixtures/Tidyness.xhtml | 8 + test/javascripts/mdtest/mdtest.js.erb | 53 + vendor/assets/javascripts/better_markdown.js | 95 +- 64 files changed, 4082 insertions(+), 131 deletions(-) create mode 100644 app/assets/javascripts/discourse/dialects/html.js create mode 100755 test/javascripts/mdtest/fixtures/Amps and angle encoding.text create mode 100755 test/javascripts/mdtest/fixtures/Amps and angle encoding.xhtml create mode 100755 test/javascripts/mdtest/fixtures/Auto links.text create mode 100755 test/javascripts/mdtest/fixtures/Auto links.xhtml create mode 100755 test/javascripts/mdtest/fixtures/Backslash escapes.text create mode 100755 test/javascripts/mdtest/fixtures/Backslash escapes.xhtml create mode 100755 test/javascripts/mdtest/fixtures/Blockquotes with code blocks.text create mode 100755 test/javascripts/mdtest/fixtures/Blockquotes with code blocks.xhtml create mode 100755 test/javascripts/mdtest/fixtures/Code Blocks.text create mode 100755 test/javascripts/mdtest/fixtures/Code Blocks.xhtml create mode 100755 test/javascripts/mdtest/fixtures/Code Spans.text create mode 100755 test/javascripts/mdtest/fixtures/Code Spans.xhtml create mode 100755 test/javascripts/mdtest/fixtures/Hard-wrapped paragraphs with list-like lines.text create mode 100755 test/javascripts/mdtest/fixtures/Hard-wrapped paragraphs with list-like lines.xhtml create mode 100755 test/javascripts/mdtest/fixtures/Horizontal rules.text create mode 100755 test/javascripts/mdtest/fixtures/Horizontal rules.xhtml create mode 100755 test/javascripts/mdtest/fixtures/Images.text create mode 100755 test/javascripts/mdtest/fixtures/Images.xhtml create mode 100755 test/javascripts/mdtest/fixtures/Inline HTML (Advanced).text create mode 100755 test/javascripts/mdtest/fixtures/Inline HTML (Advanced).xhtml create mode 100755 test/javascripts/mdtest/fixtures/Inline HTML (Simple).text create mode 100755 test/javascripts/mdtest/fixtures/Inline HTML (Simple).xhtml create mode 100755 test/javascripts/mdtest/fixtures/Inline HTML comments.text create mode 100755 test/javascripts/mdtest/fixtures/Inline HTML comments.xhtml create mode 100755 test/javascripts/mdtest/fixtures/Links, inline style.text create mode 100755 test/javascripts/mdtest/fixtures/Links, inline style.xhtml create mode 100755 test/javascripts/mdtest/fixtures/Links, reference style.text create mode 100755 test/javascripts/mdtest/fixtures/Links, reference style.xhtml create mode 100755 test/javascripts/mdtest/fixtures/Links, shortcut references.text create mode 100755 test/javascripts/mdtest/fixtures/Links, shortcut references.xhtml create mode 100755 test/javascripts/mdtest/fixtures/Literal quotes in titles.text create mode 100755 test/javascripts/mdtest/fixtures/Literal quotes in titles.xhtml create mode 100755 test/javascripts/mdtest/fixtures/Markdown Documentation - Basics.text create mode 100755 test/javascripts/mdtest/fixtures/Markdown Documentation - Basics.xhtml create mode 100755 test/javascripts/mdtest/fixtures/Markdown Documentation - Syntax.text create mode 100755 test/javascripts/mdtest/fixtures/Markdown Documentation - Syntax.xhtml create mode 100755 test/javascripts/mdtest/fixtures/Nested blockquotes.text create mode 100755 test/javascripts/mdtest/fixtures/Nested blockquotes.xhtml create mode 100755 test/javascripts/mdtest/fixtures/Ordered and unordered lists.text create mode 100755 test/javascripts/mdtest/fixtures/Ordered and unordered lists.xhtml create mode 100755 test/javascripts/mdtest/fixtures/Strong and em together.text create mode 100755 test/javascripts/mdtest/fixtures/Strong and em together.xhtml create mode 100755 test/javascripts/mdtest/fixtures/Tabs.text create mode 100755 test/javascripts/mdtest/fixtures/Tabs.xhtml create mode 100755 test/javascripts/mdtest/fixtures/Tidyness.text create mode 100755 test/javascripts/mdtest/fixtures/Tidyness.xhtml create mode 100644 test/javascripts/mdtest/mdtest.js.erb diff --git a/app/assets/javascripts/discourse/components/markdown.js b/app/assets/javascripts/discourse/components/markdown.js index fdd387fbb..d702d7df2 100644 --- a/app/assets/javascripts/discourse/components/markdown.js +++ b/app/assets/javascripts/discourse/components/markdown.js @@ -125,6 +125,7 @@ Discourse.Markdown = { if (Discourse.Markdown.validClasses[val]) { return val; } }, + /** Sanitize text using the sanitizer @@ -152,10 +153,6 @@ Discourse.Markdown = { text = Discourse.Dialect.cook(text, opts); if (!text) return ""; - if (opts.sanitize) { - text = Discourse.Markdown.sanitize(text); - } - return text; } }; diff --git a/app/assets/javascripts/discourse/dialects/bbcode_dialect.js b/app/assets/javascripts/discourse/dialects/bbcode_dialect.js index 4ae3157a2..00fc0f55b 100644 --- a/app/assets/javascripts/discourse/dialects/bbcode_dialect.js +++ b/app/assets/javascripts/discourse/dialects/bbcode_dialect.js @@ -103,8 +103,3 @@ Discourse.Dialect.replaceBlock({ } }); -Discourse.Markdown.whiteListClass("bbcode-b", "bbcode-i", "bbcode-u", "bbcode-s", "spoiler"); - -for(var i=1; i<=40; i++) { - Discourse.Markdown.whiteListClass("bbcode-size-" + i); -} \ No newline at end of file diff --git a/app/assets/javascripts/discourse/dialects/bold_italics_dialect.js b/app/assets/javascripts/discourse/dialects/bold_italics_dialect.js index 40bf4098e..3c35b3b77 100644 --- a/app/assets/javascripts/discourse/dialects/bold_italics_dialect.js +++ b/app/assets/javascripts/discourse/dialects/bold_italics_dialect.js @@ -10,6 +10,12 @@ Discourse.Dialect.inlineBetween({ emitter: function(contents) { return ['strong', ['em'].concat(contents)]; } }); +Discourse.Dialect.inlineBetween({ + between: '___', + wordBoundary: true, + emitter: function(contents) { return ['strong', ['em'].concat(contents)]; } +}); + // Builds a common markdown replacer var replaceMarkdown = function(match, tag) { Discourse.Dialect.inlineBetween({ diff --git a/app/assets/javascripts/discourse/dialects/dialect.js b/app/assets/javascripts/discourse/dialects/dialect.js index 58bb55f7a..68d3d0ac4 100644 --- a/app/assets/javascripts/discourse/dialects/dialect.js +++ b/app/assets/javascripts/discourse/dialects/dialect.js @@ -31,19 +31,31 @@ function initializeDialects() { @returns {Array} the parsed tree **/ function parseTree(tree, path, insideCounts) { + if (tree instanceof Array) { Discourse.Dialect.trigger('parseNode', {node: tree, path: path, dialect: dialect, insideCounts: insideCounts || {}}); + path = path || []; insideCounts = insideCounts || {}; path.push(tree); - tree.slice(1).forEach(function (n) { - var tagName = n[0]; + + for (var i=1; i<tree.length; i++) { + var n = tree[i], + tagName = n[0]; + insideCounts[tagName] = (insideCounts[tagName] || 0) + 1; - parseTree(n, path, insideCounts); + + if (n && n.length === 2 && n[0] === "p" && /^<!--([\s\S]*)-->$/m.exec(n[1])) { + // Remove paragraphs around comment-only nodes. + tree[i] = n[1]; + } else { + parseTree(n, path, insideCounts); + } + insideCounts[tagName] = insideCounts[tagName] - 1; - }); + } path.pop(); } return tree; @@ -207,6 +219,19 @@ Discourse.Dialect = { }; }, + /** + Registers a block for processing. This is more complicated than using one of + the other helpers such as `replaceBlock` so consider using them first! + + @method registerBlock + @param {String} the name of the block handler + @param {Function} the handler + + **/ + registerBlock: function(name, handler) { + dialect.block[name] = handler; + }, + /** Replaces a block of text between a start and stop. As opposed to inline, these might span multiple lines. @@ -233,9 +258,11 @@ Discourse.Dialect = { **/ replaceBlock: function(args) { - dialect.block[args.start.toString()] = function(block, next) { + this.registerBlock(args.start.toString(), function(block, next) { + args.start.lastIndex = 0; var m = (args.start).exec(block); + if (!m) { return; } var startPos = block.indexOf(m[0]), @@ -261,16 +288,33 @@ Discourse.Dialect = { } lineNumber++; + + + var blockClosed = false; + if (next.length > 0) { + for (var i=0; i<next.length; i++) { + if (next[i].indexOf(args.stop) >= 0) { + blockClosed = true; + break; + } + } + } + + if (!blockClosed) { + if (m[2]) { next.shift(); } + return; + } + while (next.length > 0) { var b = next.shift(), blockLine = b.lineNumber, - diff = ((typeof blockLine === "undefined") ? lineNumber : blockLine) - lineNumber; - - var endFound = b.indexOf(args.stop), + diff = ((typeof blockLine === "undefined") ? lineNumber : blockLine) - lineNumber, + endFound = b.indexOf(args.stop), leadingContents = b.slice(0, endFound), trailingContents = b.slice(endFound+args.stop.length); - for (var i=1; i<diff; i++) { + if (endFound >= 0) { blockClosed = true; } + for (var j=1; j<diff; j++) { blockContents.push(""); } lineNumber = blockLine + b.split("\n").length - 1; @@ -287,10 +331,15 @@ Discourse.Dialect = { } } - var test = args.emitter.call(this, blockContents, m, dialect.options); - result.push(test); + + + + var emitterResult = args.emitter.call(this, blockContents, m, dialect.options); + if (emitterResult) { + result.push(emitterResult); + } return result; - }; + }); }, /** @@ -318,11 +367,21 @@ Discourse.Dialect = { postProcessText: function(emitter) { Discourse.Dialect.on("parseNode", function(event) { var node = event.node; + if (node.length < 2) { return; } + if (node[0] === '__RAW') { + return; + } + for (var j=1; j<node.length; j++) { var textContent = node[j]; if (typeof textContent === "string") { + + if (dialect.options.sanitize) { + textContent = Discourse.Markdown.sanitize(textContent); + } + var result = emitter(textContent, event); if (result) { if (result instanceof Array) { @@ -330,7 +389,8 @@ Discourse.Dialect = { } else { node[j] = result; } - + } else { + node[j] = textContent; } } } diff --git a/app/assets/javascripts/discourse/dialects/github_code_dialect.js b/app/assets/javascripts/discourse/dialects/github_code_dialect.js index b4d809cfd..725b14a57 100644 --- a/app/assets/javascripts/discourse/dialects/github_code_dialect.js +++ b/app/assets/javascripts/discourse/dialects/github_code_dialect.js @@ -16,14 +16,6 @@ Discourse.Dialect.replaceBlock({ // Ensure that content in a code block is fully escaped. This way it's not white listed // and we can use HTML and Javascript examples. Discourse.Dialect.postProcessTag('code', function (contents) { - return Handlebars.Utils.escapeExpression(contents); + return Handlebars.Utils.escapeExpression(contents.replace(/^ +| +$/g,'')); }); -Discourse.Markdown.whiteListClass( - "lang-auto", "1c", "actionscript", "apache", "applescript", "avrasm", "axapta", "bash", "brainfuck", - "clojure", "cmake", "coffeescript", "cpp", "cs", "css", "d", "delphi", "diff", "xml", "django", "dos", - "erlang-repl", "erlang", "glsl", "go", "handlebars", "haskell", "http", "ini", "java", "javascript", - "json", "lisp", "lua", "markdown", "matlab", "mel", "nginx", "objectivec", "parser3", "perl", "php", - "profile", "python", "r", "rib", "rsl", "ruby", "rust", "scala", "smalltalk", "sql", "tex", "text", - "vala", "vbscript", "vhdl" -); diff --git a/app/assets/javascripts/discourse/dialects/html.js b/app/assets/javascripts/discourse/dialects/html.js new file mode 100644 index 000000000..9213fa36c --- /dev/null +++ b/app/assets/javascripts/discourse/dialects/html.js @@ -0,0 +1,8 @@ +/** + If a row begins with HTML tags, don't parse it. +**/ +Discourse.Dialect.registerBlock('html', function(block, next) { + if (block.match(/^<[^>]+\>/)) { + return [ block.toString() ]; + } +}); \ No newline at end of file diff --git a/app/assets/javascripts/discourse/dialects/mention_dialect.js b/app/assets/javascripts/discourse/dialects/mention_dialect.js index 669d5e980..55687257b 100644 --- a/app/assets/javascripts/discourse/dialects/mention_dialect.js +++ b/app/assets/javascripts/discourse/dialects/mention_dialect.js @@ -20,4 +20,3 @@ Discourse.Dialect.inlineRegexp({ } }); -Discourse.Markdown.whiteListClass('mention'); \ No newline at end of file diff --git a/app/assets/javascripts/discourse/dialects/newline_dialect.js b/app/assets/javascripts/discourse/dialects/newline_dialect.js index 1d51d4b9c..22c90f65c 100644 --- a/app/assets/javascripts/discourse/dialects/newline_dialect.js +++ b/app/assets/javascripts/discourse/dialects/newline_dialect.js @@ -29,4 +29,4 @@ Discourse.Dialect.postProcessText(function (text, event) { } } -}); \ No newline at end of file +}); diff --git a/app/assets/javascripts/discourse/dialects/onebox_dialect.js b/app/assets/javascripts/discourse/dialects/onebox_dialect.js index c7d981f7e..86f571d18 100644 --- a/app/assets/javascripts/discourse/dialects/onebox_dialect.js +++ b/app/assets/javascripts/discourse/dialects/onebox_dialect.js @@ -77,4 +77,3 @@ Discourse.Dialect.on("parseNode", function(event) { } }); -Discourse.Markdown.whiteListClass("onebox", "onebox-result", "onebox-result-body", "source", "clearfix", "thumbnail", "info"); \ No newline at end of file diff --git a/app/assets/javascripts/discourse/dialects/quote_dialect.js b/app/assets/javascripts/discourse/dialects/quote_dialect.js index ee2540433..9db791278 100644 --- a/app/assets/javascripts/discourse/dialects/quote_dialect.js +++ b/app/assets/javascripts/discourse/dialects/quote_dialect.js @@ -44,7 +44,7 @@ Discourse.Dialect.replaceBlock({ return ['p', ['aside', params, ['div', {'class': 'title'}, ['div', {'class': 'quote-controls'}], - avatarImg ? avatarImg : "", + avatarImg ? ['__RAW', avatarImg] : "", I18n.t('user.said', {username: username}) ], contents @@ -69,4 +69,3 @@ Discourse.Dialect.on("parseNode", function(event) { }); -Discourse.Markdown.whiteListClass("quote", "title", "quote-controls", "avatar"); \ No newline at end of file diff --git a/lib/pretty_text.rb b/lib/pretty_text.rb index 7ccd57325..c1619d8f9 100644 --- a/lib/pretty_text.rb +++ b/lib/pretty_text.rb @@ -5,47 +5,6 @@ require_dependency 'post' module PrettyText - def self.whitelist - { - elements: %w[ - a abbr aside b bdo blockquote br caption cite code col colgroup dd div del dfn dl - dt em hr figcaption figure h1 h2 h3 h4 h5 h6 hgroup i img ins kbd li mark - ol p pre q rp rt ruby s samp small span strike strong sub sup table tbody td - tfoot th thead time tr u ul var wbr - ], - - attributes: { - :all => ['dir', 'lang', 'title', 'class'], - 'aside' => ['data-post', 'data-full', 'data-topic'], - 'a' => ['href'], - 'blockquote' => ['cite'], - 'col' => ['span', 'width'], - 'colgroup' => ['span', 'width'], - 'del' => ['cite', 'datetime'], - 'img' => ['align', 'alt', 'height', 'src', 'width'], - 'ins' => ['cite', 'datetime'], - 'ol' => ['start', 'reversed', 'type'], - 'q' => ['cite'], - 'span' => ['style'], - 'table' => ['summary', 'width', 'style', 'cellpadding', 'cellspacing'], - 'td' => ['abbr', 'axis', 'colspan', 'rowspan', 'width', 'style'], - 'th' => ['abbr', 'axis', 'colspan', 'rowspan', 'scope', 'width', 'style'], - 'time' => ['datetime', 'pubdate'], - 'ul' => ['type'] - }, - - protocols: { - 'a' => {'href' => ['ftp', 'http', 'https', 'mailto', :relative]}, - 'blockquote' => {'cite' => ['http', 'https', :relative]}, - 'del' => {'cite' => ['http', 'https', :relative]}, - 'img' => {'src' => ['http', 'https', :relative]}, - 'ins' => {'cite' => ['http', 'https', :relative]}, - 'q' => {'cite' => ['http', 'https', :relative]} - } - } - end - - class Helpers def t(key, opts) @@ -226,7 +185,7 @@ module PrettyText cloned = opts.dup # we have a minor inconsistency cloned[:topicId] = opts[:topic_id] - sanitized = Sanitize.clean(markdown(text.dup, cloned), PrettyText.whitelist) + sanitized = markdown(text.dup, cloned) if SiteSetting.add_rel_nofollow_to_user_content sanitized = add_rel_nofollow_to_user_content(sanitized) end diff --git a/spec/components/pretty_text_spec.rb b/spec/components/pretty_text_spec.rb index 8625496b6..d85e24562 100644 --- a/spec/components/pretty_text_spec.rb +++ b/spec/components/pretty_text_spec.rb @@ -32,7 +32,7 @@ describe PrettyText do end it "should sanitize the html" do - PrettyText.cook("<script>alert(42)</script>").should match_html "<p></p>" + PrettyText.cook("<script>alert(42)</script>").should match_html "" end it 'should allow for @mentions to have punctuation' do diff --git a/spec/models/post_analyzer_spec.rb b/spec/models/post_analyzer_spec.rb index 97671fb04..d8f69462b 100644 --- a/spec/models/post_analyzer_spec.rb +++ b/spec/models/post_analyzer_spec.rb @@ -184,7 +184,7 @@ describe PostAnalyzer do end it "ignores code" do - post_analyzer = PostAnalyzer.new("@Jake <code>@Finn</code>", default_topic_id) + post_analyzer = PostAnalyzer.new("@Jake `@Finn`", default_topic_id) post_analyzer.raw_mentions.should == ['jake'] end diff --git a/spec/models/post_spec.rb b/spec/models/post_spec.rb index 847ca356a..7ae8e5cb1 100644 --- a/spec/models/post_spec.rb +++ b/spec/models/post_spec.rb @@ -376,7 +376,7 @@ describe Post do end it "ignores code" do - post = Fabricate.build(:post, post_args.merge(raw: "@Jake <code>@Finn</code>")) + post = Fabricate.build(:post, post_args.merge(raw: "@Jake `@Finn`")) post.raw_mentions.should == ['jake'] end diff --git a/test/javascripts/components/bbcode_test.js b/test/javascripts/components/bbcode_test.js index 1fb59dca1..a3b44951b 100644 --- a/test/javascripts/components/bbcode_test.js +++ b/test/javascripts/components/bbcode_test.js @@ -22,6 +22,11 @@ test('basic bbcode', function() { "allows embedding of tags"); }); +test('invalid bbcode', function() { + var cooked = Discourse.Markdown.cook("[code]I am not closed\n\nThis text exists.", {lookupAvatar: false}); + equal(cooked, "<p>[code]I am not closed</p>\n\n<p>This text exists.</p>", "does not raise an error with an open bbcode tag."); +}); + test('lists', function() { format("[ul][li]option one[/li][/ul]", "<ul><li>option one</li></ul>", "creates an ul"); format("[ol][li]option one[/li][/ol]", "<ol><li>option one</li></ol>", "creates an ol"); diff --git a/test/javascripts/components/markdown_test.js b/test/javascripts/components/markdown_test.js index 4010b05fd..5d22b45bc 100644 --- a/test/javascripts/components/markdown_test.js +++ b/test/javascripts/components/markdown_test.js @@ -8,6 +8,12 @@ module("Discourse.Markdown", { var cooked = function(input, expected, text) { var result = Discourse.Markdown.cook(input, {mentionLookup: false, sanitize: true}); + + if (result !== expected) { + console.log(JSON.stringify(result)); + console.log(JSON.stringify(expected)); + } + equal(result, expected, text); }; @@ -31,7 +37,7 @@ test("basic cooking", function() { test("Traditional Line Breaks", function() { var input = "1\n2\n3"; - cooked(input, "<p>1<br>2<br>3</p>", "automatically handles trivial newlines"); + cooked(input, "<p>1<br/>2<br/>3</p>", "automatically handles trivial newlines"); var traditionalOutput = "<p>1\n2\n3</p>"; @@ -46,7 +52,7 @@ test("Traditional Line Breaks", function() { test("Line Breaks", function() { cooked("[] first choice\n[] second choice", - "<p>[] first choice<br>[] second choice</p>", + "<p>[] first choice<br/>[] second choice</p>", "it handles new lines correctly with [] options"); }); @@ -89,10 +95,10 @@ test("Links", function() { "autolinks a URL with parentheses (like Wikipedia)"); cooked("Here's a tweet:\nhttps://twitter.com/evil_trout/status/345954894420787200", - "<p>Here's a tweet:<br><a href=\"https://twitter.com/evil_trout/status/345954894420787200\" class=\"onebox\">https://twitter.com/evil_trout/status/345954894420787200</a></p>", + "<p>Here's a tweet:<br/><a href=\"https://twitter.com/evil_trout/status/345954894420787200\" class=\"onebox\" target=\"_blank\">https://twitter.com/evil_trout/status/345954894420787200</a></p>", "It doesn't strip the new line."); - cooked("1. View @eviltrout's profile here: http://meta.discourse.org/users/eviltrout/activity<br>next line.", + cooked("1. View @eviltrout's profile here: http://meta.discourse.org/users/eviltrout/activity<br/>next line.", "<ol><li>View <span class=\"mention\">@eviltrout</span>'s profile here: <a href=\"http://meta.discourse.org/users/eviltrout/activity\">http://meta.discourse.org/users/eviltrout/activity</a><br>next line.</li></ol>", "allows autolinking within a list without inserting a paragraph."); @@ -105,7 +111,7 @@ test("Links", function() { 'allows multiple links on one line'); cooked("* [Evil Trout][1]\n [1]: http://eviltrout.com", - "<ul><li><a href=\"http://eviltrout.com\">Evil Trout</a><br></li></ul>", + "<ul><li><a href=\"http://eviltrout.com\">Evil Trout</a></li></ul>", "allows markdown link references in a list"); }); @@ -121,9 +127,9 @@ test("simple quotes", function() { "it allows nesting of blockquotes with spaces"); cooked("- hello\n\n > world\n > eviltrout", - "<ul><li>hello</li></ul>\n\n<blockquote><p>world<br>eviltrout</p></blockquote>", + "<ul><li>hello</li></ul>\n\n<blockquote><p>world<br/>eviltrout</p></blockquote>", "it allows quotes within a list."); - cooked(" > indent 1\n > indent 2", "<blockquote><p>indent 1<br>indent 2</p></blockquote>", "allow multiple spaces to indent"); + cooked(" > indent 1\n > indent 2", "<blockquote><p>indent 1<br/>indent 2</p></blockquote>", "allow multiple spaces to indent"); }); @@ -136,7 +142,7 @@ test("Quotes", function() { "works with multiple lines"); cookedOptions("1[quote=\"bob, post:1\"]my quote[/quote]2", - { topicId: 2, lookupAvatar: function(name) { return "" + name; } }, + { topicId: 2, lookupAvatar: function(name) { return "" + name; }, sanitize: true }, "<p>1</p>\n\n<p><aside class=\"quote\" data-post=\"1\"><div class=\"title\"><div class=\"quote-controls\"></div>bob" + "bob said:</div><blockquote><p>my quote</p></blockquote></aside></p>\n\n<p>2</p>", "handles quotes properly"); @@ -160,7 +166,7 @@ test("Mentions", function() { cooked("robin@email.host", "<p>robin@email.host</p>", "won't add mention class to an email address"); cooked("hanzo55@yahoo.com", "<p>hanzo55@yahoo.com</p>", "won't be affected by email addresses that have a number before the @ symbol"); cooked("@EvilTrout yo", "<p><span class=\"mention\">@EvilTrout</span> yo</p>", "it handles mentions at the beginning of a string"); - cooked("yo\n@EvilTrout", "<p>yo<br><span class=\"mention\">@EvilTrout</span></p>", "it handles mentions at the beginning of a new line"); + cooked("yo\n@EvilTrout", "<p>yo<br/><span class=\"mention\">@EvilTrout</span></p>", "it handles mentions at the beginning of a new line"); cooked("`evil` @EvilTrout `trout`", "<p><code>evil</code> <span class=\"mention\">@EvilTrout</span> <code>trout</code></p>", "deals correctly with multiple <code> blocks"); @@ -171,7 +177,7 @@ test("Mentions", function() { "handles mentions in simple quotes"); cooked("> foo bar baz @eviltrout ohmagerd\nlook at this", - "<blockquote><p>foo bar baz <span class=\"mention\">@eviltrout</span> ohmagerd<br>look at this</p></blockquote>", + "<blockquote><p>foo bar baz <span class=\"mention\">@eviltrout</span> ohmagerd<br/>look at this</p></blockquote>", "does mentions properly with trailing text within a simple quote"); cooked("`code` is okay before @mention", @@ -224,7 +230,7 @@ test("Oneboxing", function() { cooked("http://en.wikipedia.org/wiki/Homicide:_Life_on_the_Street", "<p><a href=\"http://en.wikipedia.org/wiki/Homicide:_Life_on_the_Street\" class=\"onebox\"" + - ">http://en.wikipedia.org/wiki/Homicide:_Life_on_the_Street</a></p>", + " target=\"_blank\">http://en.wikipedia.org/wiki/Homicide:_Life_on_the_Street</a></p>", "works with links that have underscores in them"); }); @@ -248,7 +254,7 @@ test("Code Blocks", function() { "it maintains new lines inside a code block."); cooked("hello\nworld\n```json\nline 1\n\nline 2\n\n\nline3\n```", - "<p>hello<br>world<br></p>\n\n<p><pre><code class=\"json\">line 1\n\nline 2\n\n\nline3</code></pre></p>", + "<p>hello<br/>world<br/></p>\n\n<p><pre><code class=\"json\">line 1\n\nline 2\n\n\nline3</code></pre></p>", "it maintains new lines inside a code block with leading content."); cooked("```text\n<header>hello</header>\n```", @@ -287,7 +293,7 @@ test("sanitize", function() { cooked("hello<script>alert(42)</script>", "<p>hello</p>", "it sanitizes while cooking"); cooked("<a href='http://disneyland.disney.go.com/'>disney</a> <a href='http://reddit.com'>reddit</a>", - "<p><a href=\"http://disneyland.disney.go.com/\">disney</a> <a href=\"http://reddit.com\">reddit</a></p>", + "<a href=\"http://disneyland.disney.go.com/\">disney</a> <a href=\"http://reddit.com\">reddit</a>", "we can embed proper links"); }); @@ -295,7 +301,7 @@ test("sanitize", function() { test("URLs in BBCode tags", function() { cooked("[img]http://eviltrout.com/eviltrout.png[/img][img]http://samsaffron.com/samsaffron.png[/img]", - "<p><img src=\"http://eviltrout.com/eviltrout.png\"><img src=\"http://samsaffron.com/samsaffron.png\"></p>", + "<p><img src=\"http://eviltrout.com/eviltrout.png\"/><img src=\"http://samsaffron.com/samsaffron.png\"/></p>", "images are properly parsed"); cooked("[url]http://discourse.org[/url]", diff --git a/test/javascripts/mdtest/fixtures/Amps and angle encoding.text b/test/javascripts/mdtest/fixtures/Amps and angle encoding.text new file mode 100755 index 000000000..0e9527f93 --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Amps and angle encoding.text @@ -0,0 +1,21 @@ +AT&T has an ampersand in their name. + +AT&T is another way to write it. + +This & that. + +4 < 5. + +6 > 5. + +Here's a [link] [1] with an ampersand in the URL. + +Here's a link with an amersand in the link text: [AT&T] [2]. + +Here's an inline [link](/script?foo=1&bar=2). + +Here's an inline [link](</script?foo=1&bar=2>). + + +[1]: http://example.com/?foo=1&bar=2 +[2]: http://att.com/ "AT&T" \ No newline at end of file diff --git a/test/javascripts/mdtest/fixtures/Amps and angle encoding.xhtml b/test/javascripts/mdtest/fixtures/Amps and angle encoding.xhtml new file mode 100755 index 000000000..c458eb035 --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Amps and angle encoding.xhtml @@ -0,0 +1,22 @@ +<!-- + Changed for Discourse: + + - Our HTML sanitizer escapes > as > even though Markdown doesn't specify that. +--> +<p>AT&T has an ampersand in their name.</p> + +<p>AT&T is another way to write it.</p> + +<p>This & that.</p> + +<p>4 < 5.</p> + +<p>6 > 5.</p> + +<p>Here's a <a href="http://example.com/?foo=1&bar=2">link</a> with an ampersand in the URL.</p> + +<p>Here's a link with an amersand in the link text: <a href="http://att.com/" title="AT&T">AT&T</a>.</p> + +<p>Here's an inline <a href="/script?foo=1&bar=2">link</a>.</p> + +<p>Here's an inline <a href="/script?foo=1&bar=2">link</a>.</p> diff --git a/test/javascripts/mdtest/fixtures/Auto links.text b/test/javascripts/mdtest/fixtures/Auto links.text new file mode 100755 index 000000000..abbc48869 --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Auto links.text @@ -0,0 +1,13 @@ +Link: <http://example.com/>. + +With an ampersand: <http://example.com/?foo=1&bar=2> + +* In a list? +* <http://example.com/> +* It should. + +> Blockquoted: <http://example.com/> + +Auto-links should not occur here: `<http://example.com/>` + + or here: <http://example.com/> \ No newline at end of file diff --git a/test/javascripts/mdtest/fixtures/Auto links.xhtml b/test/javascripts/mdtest/fixtures/Auto links.xhtml new file mode 100755 index 000000000..f8df9852c --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Auto links.xhtml @@ -0,0 +1,18 @@ +<p>Link: <a href="http://example.com/">http://example.com/</a>.</p> + +<p>With an ampersand: <a href="http://example.com/?foo=1&bar=2">http://example.com/?foo=1&bar=2</a></p> + +<ul> +<li>In a list?</li> +<li><a href="http://example.com/">http://example.com/</a></li> +<li>It should.</li> +</ul> + +<blockquote> + <p>Blockquoted: <a href="http://example.com/">http://example.com/</a></p> +</blockquote> + +<p>Auto-links should not occur here: <code><http://example.com/></code></p> + +<pre><code>or here: <http://example.com/> +</code></pre> diff --git a/test/javascripts/mdtest/fixtures/Backslash escapes.text b/test/javascripts/mdtest/fixtures/Backslash escapes.text new file mode 100755 index 000000000..5b014cb33 --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Backslash escapes.text @@ -0,0 +1,120 @@ +These should all get escaped: + +Backslash: \\ + +Backtick: \` + +Asterisk: \* + +Underscore: \_ + +Left brace: \{ + +Right brace: \} + +Left bracket: \[ + +Right bracket: \] + +Left paren: \( + +Right paren: \) + +Greater-than: \> + +Hash: \# + +Period: \. + +Bang: \! + +Plus: \+ + +Minus: \- + + + +These should not, because they occur within a code block: + + Backslash: \\ + + Backtick: \` + + Asterisk: \* + + Underscore: \_ + + Left brace: \{ + + Right brace: \} + + Left bracket: \[ + + Right bracket: \] + + Left paren: \( + + Right paren: \) + + Greater-than: \> + + Hash: \# + + Period: \. + + Bang: \! + + Plus: \+ + + Minus: \- + + +Nor should these, which occur in code spans: + +Backslash: `\\` + +Backtick: `` \` `` + +Asterisk: `\*` + +Underscore: `\_` + +Left brace: `\{` + +Right brace: `\}` + +Left bracket: `\[` + +Right bracket: `\]` + +Left paren: `\(` + +Right paren: `\)` + +Greater-than: `\>` + +Hash: `\#` + +Period: `\.` + +Bang: `\!` + +Plus: `\+` + +Minus: `\-` + + +These should get escaped, even though they're matching pairs for +other Markdown constructs: + +\*asterisks\* + +\_underscores\_ + +\`backticks\` + +This is a code span with a literal backslash-backtick sequence: `` \` `` + +This is a tag with unescaped backticks <span attr='`ticks`'>bar</span>. + +This is a tag with backslashes <span attr='\\backslashes\\'>bar</span>. diff --git a/test/javascripts/mdtest/fixtures/Backslash escapes.xhtml b/test/javascripts/mdtest/fixtures/Backslash escapes.xhtml new file mode 100755 index 000000000..6c54bdc68 --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Backslash escapes.xhtml @@ -0,0 +1,125 @@ +<!-- + Changed for Discourse: + + - Our HTML sanitizer escapes quotes " as " + - Our sanitizer has not whitelisted attr attributes in `span`s + - Our sanitizer replaces backticks with ` in code blocks +--> +<p>These should all get escaped:</p> + +<p>Backslash: \</p> + +<p>Backtick: `</p> + +<p>Asterisk: *</p> + +<p>Underscore: _</p> + +<p>Left brace: {</p> + +<p>Right brace: }</p> + +<p>Left bracket: [</p> + +<p>Right bracket: ]</p> + +<p>Left paren: (</p> + +<p>Right paren: )</p> + +<p>Greater-than: ></p> + +<p>Hash: #</p> + +<p>Period: .</p> + +<p>Bang: !</p> + +<p>Plus: +</p> + +<p>Minus: -</p> + +<p>These should not, because they occur within a code block:</p> + +<pre><code>Backslash: \\ + +Backtick: \` + +Asterisk: \* + +Underscore: \_ + +Left brace: \{ + +Right brace: \} + +Left bracket: \[ + +Right bracket: \] + +Left paren: \( + +Right paren: \) + +Greater-than: \> + +Hash: \# + +Period: \. + +Bang: \! + +Plus: \+ + +Minus: \- +</code></pre> + +<p>Nor should these, which occur in code spans:</p> + +<p>Backslash: <code>\\</code></p> + +<p>Backtick: <code>\`</code></p> + +<p>Asterisk: <code>\*</code></p> + +<p>Underscore: <code>\_</code></p> + +<p>Left brace: <code>\{</code></p> + +<p>Right brace: <code>\}</code></p> + +<p>Left bracket: <code>\[</code></p> + +<p>Right bracket: <code>\]</code></p> + +<p>Left paren: <code>\(</code></p> + +<p>Right paren: <code>\)</code></p> + +<p>Greater-than: <code>\></code></p> + +<p>Hash: <code>\#</code></p> + +<p>Period: <code>\.</code></p> + +<p>Bang: <code>\!</code></p> + +<p>Plus: <code>\+</code></p> + +<p>Minus: <code>\-</code></p> + + +<p>These should get escaped, even though they're matching pairs for +other Markdown constructs:</p> + +<p>*asterisks*</p> + +<p>_underscores_</p> + +<p>`backticks`</p> + +<p>This is a code span with a literal backslash-backtick sequence: <code>\`</code></p> + +<p>This is a tag with unescaped backticks <span>bar</span>.</p> + +<p>This is a tag with backslashes <span>bar</span>.</p> diff --git a/test/javascripts/mdtest/fixtures/Blockquotes with code blocks.text b/test/javascripts/mdtest/fixtures/Blockquotes with code blocks.text new file mode 100755 index 000000000..c31d17104 --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Blockquotes with code blocks.text @@ -0,0 +1,11 @@ +> Example: +> +> sub status { +> print "working"; +> } +> +> Or: +> +> sub status { +> return "working"; +> } diff --git a/test/javascripts/mdtest/fixtures/Blockquotes with code blocks.xhtml b/test/javascripts/mdtest/fixtures/Blockquotes with code blocks.xhtml new file mode 100755 index 000000000..2f9c92bef --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Blockquotes with code blocks.xhtml @@ -0,0 +1,20 @@ +<!-- + Changed for Discourse: + + - Our HTML sanitizer escapes quotes " as " +--> +<blockquote> + <p>Example:</p> + +<pre><code>sub status { + print "working"; +} +</code></pre> + + <p>Or:</p> + +<pre><code>sub status { + return "working"; +} +</code></pre> +</blockquote> diff --git a/test/javascripts/mdtest/fixtures/Code Blocks.text b/test/javascripts/mdtest/fixtures/Code Blocks.text new file mode 100755 index 000000000..b54b09285 --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Code Blocks.text @@ -0,0 +1,14 @@ + code block on the first line + +Regular text. + + code block indented by spaces + +Regular text. + + the lines in this block + all contain trailing spaces + +Regular Text. + + code block on the last line \ No newline at end of file diff --git a/test/javascripts/mdtest/fixtures/Code Blocks.xhtml b/test/javascripts/mdtest/fixtures/Code Blocks.xhtml new file mode 100755 index 000000000..f6461051a --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Code Blocks.xhtml @@ -0,0 +1,17 @@ +<pre><code>code block on the first line +</code></pre> + +<p>Regular text.</p> + +<pre><code>code block indented by spaces +</code></pre> + +<p>Regular text.</p> + +<pre><code>the lines in this block +all contain trailing spaces</code></pre> + +<p>Regular Text.</p> + +<pre><code>code block on the last line +</code></pre> diff --git a/test/javascripts/mdtest/fixtures/Code Spans.text b/test/javascripts/mdtest/fixtures/Code Spans.text new file mode 100755 index 000000000..5c229c7ad --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Code Spans.text @@ -0,0 +1,5 @@ +`<test a="` content of attribute `">` + +Fix for backticks within HTML tag: <span attr='`ticks`'>like this</span> + +Here's how you put `` `backticks` `` in a code span. \ No newline at end of file diff --git a/test/javascripts/mdtest/fixtures/Code Spans.xhtml b/test/javascripts/mdtest/fixtures/Code Spans.xhtml new file mode 100755 index 000000000..b28505047 --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Code Spans.xhtml @@ -0,0 +1,12 @@ +<!-- + Changed for Discourse: + + - Our HTML sanitizer escapes quotes " as " + - Our sanitizer has not whitelisted attr attributes in `span`s + - Our sanitizer replaces backticks with ` +--> +<p><code><test a="</code> content of attribute <code>"></code></p> + +<p>Fix for backticks within HTML tag: <span>like this</span></p> + +<p>Here's how you put <code>`backticks`</code> in a code span.</p> diff --git a/test/javascripts/mdtest/fixtures/Hard-wrapped paragraphs with list-like lines.text b/test/javascripts/mdtest/fixtures/Hard-wrapped paragraphs with list-like lines.text new file mode 100755 index 000000000..f8a5b27bf --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Hard-wrapped paragraphs with list-like lines.text @@ -0,0 +1,8 @@ +In Markdown 1.0.0 and earlier. Version +8. This line turns into a list item. +Because a hard-wrapped line in the +middle of a paragraph looked like a +list item. + +Here's one with a bullet. +* criminey. diff --git a/test/javascripts/mdtest/fixtures/Hard-wrapped paragraphs with list-like lines.xhtml b/test/javascripts/mdtest/fixtures/Hard-wrapped paragraphs with list-like lines.xhtml new file mode 100755 index 000000000..e21ac79a2 --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Hard-wrapped paragraphs with list-like lines.xhtml @@ -0,0 +1,8 @@ +<p>In Markdown 1.0.0 and earlier. Version +8. This line turns into a list item. +Because a hard-wrapped line in the +middle of a paragraph looked like a +list item.</p> + +<p>Here's one with a bullet. +* criminey.</p> diff --git a/test/javascripts/mdtest/fixtures/Horizontal rules.text b/test/javascripts/mdtest/fixtures/Horizontal rules.text new file mode 100755 index 000000000..1594bda27 --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Horizontal rules.text @@ -0,0 +1,67 @@ +Dashes: + +--- + + --- + + --- + + --- + + --- + +- - - + + - - - + + - - - + + - - - + + - - - + + +Asterisks: + +*** + + *** + + *** + + *** + + *** + +* * * + + * * * + + * * * + + * * * + + * * * + + +Underscores: + +___ + + ___ + + ___ + + ___ + + ___ + +_ _ _ + + _ _ _ + + _ _ _ + + _ _ _ + + _ _ _ diff --git a/test/javascripts/mdtest/fixtures/Horizontal rules.xhtml b/test/javascripts/mdtest/fixtures/Horizontal rules.xhtml new file mode 100755 index 000000000..2dc2ab656 --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Horizontal rules.xhtml @@ -0,0 +1,71 @@ +<p>Dashes:</p> + +<hr /> + +<hr /> + +<hr /> + +<hr /> + +<pre><code>--- +</code></pre> + +<hr /> + +<hr /> + +<hr /> + +<hr /> + +<pre><code>- - - +</code></pre> + +<p>Asterisks:</p> + +<hr /> + +<hr /> + +<hr /> + +<hr /> + +<pre><code>*** +</code></pre> + +<hr /> + +<hr /> + +<hr /> + +<hr /> + +<pre><code>* * * +</code></pre> + +<p>Underscores:</p> + +<hr /> + +<hr /> + +<hr /> + +<hr /> + +<pre><code>___ +</code></pre> + +<hr /> + +<hr /> + +<hr /> + +<hr /> + +<pre><code>_ _ _ +</code></pre> diff --git a/test/javascripts/mdtest/fixtures/Images.text b/test/javascripts/mdtest/fixtures/Images.text new file mode 100755 index 000000000..570759091 --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Images.text @@ -0,0 +1,26 @@ + + + + +Inline within a paragraph: [alt text](/url/). + + + + + + + +. + +![Empty]() + +.jpg) + + +![alt text][foo] + + [foo]: /url/ + +![alt text][bar] + + [bar]: /url/ "Title here" \ No newline at end of file diff --git a/test/javascripts/mdtest/fixtures/Images.xhtml b/test/javascripts/mdtest/fixtures/Images.xhtml new file mode 100755 index 000000000..925bc1476 --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Images.xhtml @@ -0,0 +1,21 @@ +<p><img src="/path/to/img.jpg" alt="Alt text" /></p> + +<p><img src="/path/to/img.jpg" alt="Alt text" title="Optional title" /></p> + +<p>Inline within a paragraph: <a href="/url/">alt text</a>.</p> + +<p><img src="/url/" alt="alt text" title="title preceded by two spaces" /></p> + +<p><img src="/url/" alt="alt text" title="title has spaces afterward" /></p> + +<p><img src="/url/" alt="alt text" /></p> + +<p><img src="/url/" alt="alt text" title="with a title" />.</p> + +<p><img src="" alt="Empty" /></p> + +<p><img src="http://example.com/(parens).jpg" alt="this is a stupid URL" /></p> + +<p><img src="/url/" alt="alt text" /></p> + +<p><img src="/url/" alt="alt text" title="Title here" /></p> diff --git a/test/javascripts/mdtest/fixtures/Inline HTML (Advanced).text b/test/javascripts/mdtest/fixtures/Inline HTML (Advanced).text new file mode 100755 index 000000000..0c59e8951 --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Inline HTML (Advanced).text @@ -0,0 +1,30 @@ +Simple block on one line: + +<div>foo</div> + +And nested without indentation: + +<div> +<div> +<div> +foo +</div> +<div style=">"></div> +</div> +<div>bar</div> +</div> + +And with attributes: + +<div> + <div id="foo"> + </div> +</div> + +This was broken in 1.0.2b7: + +<div class="inlinepage"> +<div class="toggleableend"> +foo +</div> +</div> diff --git a/test/javascripts/mdtest/fixtures/Inline HTML (Advanced).xhtml b/test/javascripts/mdtest/fixtures/Inline HTML (Advanced).xhtml new file mode 100755 index 000000000..1914c2a43 --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Inline HTML (Advanced).xhtml @@ -0,0 +1,36 @@ +<!-- + Changed for Discourse: + + - Our HTML sanitizer removes the style tag + - It removes id and classes. +--> +<p>Simple block on one line:</p> + +<div>foo</div> + +<p>And nested without indentation:</p> + +<div> +<div> +<div> +foo +</div> +<div></div> +</div> +<div>bar</div> +</div> + +<p>And with attributes:</p> + +<div> + <div> + </div> +</div> + +<p>This was broken in 1.0.2b7:</p> + +<div> +<div> +foo +</div> +</div> diff --git a/test/javascripts/mdtest/fixtures/Inline HTML (Simple).text b/test/javascripts/mdtest/fixtures/Inline HTML (Simple).text new file mode 100755 index 000000000..d3e1d4efc --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Inline HTML (Simple).text @@ -0,0 +1,54 @@ +Here's a simple block: + +<div> + foo +</div> + +This should be a code block, though: + + <div> + foo + </div> + +As should this: + + <div>foo</div> + +Now, nested: + +<div> + <div> + <div> + foo + </div> + </div> +</div> + +This should just be an HTML comment: + +<!-- Comment --> + +Multiline: + +<!-- +Blah +Blah +--> + +Code block: + + <!-- Comment --> + +Just plain comment, with trailing spaces on the line: + +<!-- foo --> + +Code: + + <hr /> + +Hr's: + +<hr> + +<hr class="foo" id="bar"> diff --git a/test/javascripts/mdtest/fixtures/Inline HTML (Simple).xhtml b/test/javascripts/mdtest/fixtures/Inline HTML (Simple).xhtml new file mode 100755 index 000000000..f872b9048 --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Inline HTML (Simple).xhtml @@ -0,0 +1,63 @@ +<!-- + Changed for Discourse: + + - It removes id and classes. +--> +<p>Here's a simple block:</p> + +<div> + foo +</div> + +<p>This should be a code block, though:</p> + +<pre><code><div> + foo +</div> +</code></pre> + +<p>As should this:</p> + +<pre><code><div>foo</div> +</code></pre> + +<p>Now, nested:</p> + +<div> + <div> + <div> + foo + </div> + </div> +</div> + +<p>This should just be an HTML comment:</p> + +<!-- Comment --> + +<p>Multiline:</p> + +<!-- +Blah +Blah +--> + +<p>Code block:</p> + +<pre><code><!-- Comment --> +</code></pre> + +<p>Just plain comment, with trailing spaces on the line:</p> + +<!-- foo --> + +<p>Code:</p> + +<pre><code><hr /> +</code></pre> + +<p>Hr's:</p> + +<hr> + +<hr> diff --git a/test/javascripts/mdtest/fixtures/Inline HTML comments.text b/test/javascripts/mdtest/fixtures/Inline HTML comments.text new file mode 100755 index 000000000..41d830d03 --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Inline HTML comments.text @@ -0,0 +1,13 @@ +Paragraph one. + +<!-- This is a simple comment --> + +<!-- + This is another comment. +--> + +Paragraph two. + +<!-- one comment block -- -- with two comments --> + +The end. diff --git a/test/javascripts/mdtest/fixtures/Inline HTML comments.xhtml b/test/javascripts/mdtest/fixtures/Inline HTML comments.xhtml new file mode 100755 index 000000000..3f167a161 --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Inline HTML comments.xhtml @@ -0,0 +1,13 @@ +<p>Paragraph one.</p> + +<!-- This is a simple comment --> + +<!-- + This is another comment. +--> + +<p>Paragraph two.</p> + +<!-- one comment block -- -- with two comments --> + +<p>The end.</p> diff --git a/test/javascripts/mdtest/fixtures/Links, inline style.text b/test/javascripts/mdtest/fixtures/Links, inline style.text new file mode 100755 index 000000000..aba965835 --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Links, inline style.text @@ -0,0 +1,24 @@ +Just a [URL](/url/). + +[URL and title](/url/ "title"). + +[URL and title](/url/ "title preceded by two spaces"). + +[URL and title](/url/ "title preceded by a tab"). + +[URL and title](/url/ "title has spaces afterward" ). + +[URL wrapped in angle brackets](</url/>). + +[URL w/ angle brackets + title](</url/> "Here's the title"). + +[Empty](). + +[With parens in the URL](http://en.wikipedia.org/wiki/WIMP_(computing)) + +(With outer parens and [parens in url](/foo(bar))) + + +[With parens in the URL](/foo(bar) "and a title") + +(With outer parens and [parens in url](/foo(bar) "and a title")) diff --git a/test/javascripts/mdtest/fixtures/Links, inline style.xhtml b/test/javascripts/mdtest/fixtures/Links, inline style.xhtml new file mode 100755 index 000000000..5802fe612 --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Links, inline style.xhtml @@ -0,0 +1,28 @@ +<!-- + Changed for Discourse: + + - Our HTML sanitizer puts ' in attributes +--> +<p>Just a <a href="/url/">URL</a>.</p> + +<p><a href="/url/" title="title">URL and title</a>.</p> + +<p><a href="/url/" title="title preceded by two spaces">URL and title</a>.</p> + +<p><a href="/url/" title="title preceded by a tab">URL and title</a>.</p> + +<p><a href="/url/" title="title has spaces afterward">URL and title</a>.</p> + +<p><a href="/url/">URL wrapped in angle brackets</a>.</p> + +<p><a href="/url/" title="Here's the title">URL w/ angle brackets + title</a>.</p> + +<p><a href="">Empty</a>.</p> + +<p><a href="http://en.wikipedia.org/wiki/WIMP_(computing)">With parens in the URL</a></p> + +<p>(With outer parens and <a href="/foo(bar)">parens in url</a>)</p> + +<p><a href="/foo(bar)" title="and a title">With parens in the URL</a></p> + +<p>(With outer parens and <a href="/foo(bar)" title="and a title">parens in url</a>)</p> diff --git a/test/javascripts/mdtest/fixtures/Links, reference style.text b/test/javascripts/mdtest/fixtures/Links, reference style.text new file mode 100755 index 000000000..341ec88e3 --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Links, reference style.text @@ -0,0 +1,71 @@ +Foo [bar] [1]. + +Foo [bar][1]. + +Foo [bar] +[1]. + +[1]: /url/ "Title" + + +With [embedded [brackets]] [b]. + + +Indented [once][]. + +Indented [twice][]. + +Indented [thrice][]. + +Indented [four][] times. + + [once]: /url + + [twice]: /url + + [thrice]: /url + + [four]: /url + + +[b]: /url/ + +* * * + +[this] [this] should work + +So should [this][this]. + +And [this] []. + +And [this][]. + +And [this]. + +But not [that] []. + +Nor [that][]. + +Nor [that]. + +[Something in brackets like [this][] should work] + +[Same with [this].] + +In this case, [this](/somethingelse/) points to something else. + +Backslashing should suppress \[this] and [this\]. + +[this]: foo + + +* * * + +Here's one where the [link +breaks] across lines. + +Here's another where the [link +breaks] across lines, but with a line-ending space. + + +[link breaks]: /url/ diff --git a/test/javascripts/mdtest/fixtures/Links, reference style.xhtml b/test/javascripts/mdtest/fixtures/Links, reference style.xhtml new file mode 100755 index 000000000..8e70c32f4 --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Links, reference style.xhtml @@ -0,0 +1,52 @@ +<p>Foo <a href="/url/" title="Title">bar</a>.</p> + +<p>Foo <a href="/url/" title="Title">bar</a>.</p> + +<p>Foo <a href="/url/" title="Title">bar</a>.</p> + +<p>With <a href="/url/">embedded [brackets]</a>.</p> + +<p>Indented <a href="/url">once</a>.</p> + +<p>Indented <a href="/url">twice</a>.</p> + +<p>Indented <a href="/url">thrice</a>.</p> + +<p>Indented [four][] times.</p> + +<pre><code>[four]: /url +</code></pre> + +<hr /> + +<p><a href="foo">this</a> should work</p> + +<p>So should <a href="foo">this</a>.</p> + +<p>And <a href="foo">this</a>.</p> + +<p>And <a href="foo">this</a>.</p> + +<p>And <a href="foo">this</a>.</p> + +<p>But not [that] [].</p> + +<p>Nor [that][].</p> + +<p>Nor [that].</p> + +<p>[Something in brackets like <a href="foo">this</a> should work]</p> + +<p>[Same with <a href="foo">this</a>.]</p> + +<p>In this case, <a href="/somethingelse/">this</a> points to something else.</p> + +<p>Backslashing should suppress [this] and [this].</p> + +<hr /> + +<p>Here's one where the <a href="/url/">link +breaks</a> across lines.</p> + +<p>Here's another where the <a href="/url/">link +breaks</a> across lines, but with a line-ending space.</p> diff --git a/test/javascripts/mdtest/fixtures/Links, shortcut references.text b/test/javascripts/mdtest/fixtures/Links, shortcut references.text new file mode 100755 index 000000000..8c44c98fe --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Links, shortcut references.text @@ -0,0 +1,20 @@ +This is the [simple case]. + +[simple case]: /simple + + + +This one has a [line +break]. + +This one has a [line +break] with a line-ending space. + +[line break]: /foo + + +[this] [that] and the [other] + +[this]: /this +[that]: /that +[other]: /other diff --git a/test/javascripts/mdtest/fixtures/Links, shortcut references.xhtml b/test/javascripts/mdtest/fixtures/Links, shortcut references.xhtml new file mode 100755 index 000000000..bf81e939f --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Links, shortcut references.xhtml @@ -0,0 +1,9 @@ +<p>This is the <a href="/simple">simple case</a>.</p> + +<p>This one has a <a href="/foo">line +break</a>.</p> + +<p>This one has a <a href="/foo">line +break</a> with a line-ending space.</p> + +<p><a href="/that">this</a> and the <a href="/other">other</a></p> diff --git a/test/javascripts/mdtest/fixtures/Literal quotes in titles.text b/test/javascripts/mdtest/fixtures/Literal quotes in titles.text new file mode 100755 index 000000000..29d0e4235 --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Literal quotes in titles.text @@ -0,0 +1,7 @@ +Foo [bar][]. + +Foo [bar](/url/ "Title with "quotes" inside"). + + + [bar]: /url/ "Title with "quotes" inside" + diff --git a/test/javascripts/mdtest/fixtures/Literal quotes in titles.xhtml b/test/javascripts/mdtest/fixtures/Literal quotes in titles.xhtml new file mode 100755 index 000000000..611c1ac61 --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Literal quotes in titles.xhtml @@ -0,0 +1,3 @@ +<p>Foo <a href="/url/" title="Title with "quotes" inside">bar</a>.</p> + +<p>Foo <a href="/url/" title="Title with "quotes" inside">bar</a>.</p> diff --git a/test/javascripts/mdtest/fixtures/Markdown Documentation - Basics.text b/test/javascripts/mdtest/fixtures/Markdown Documentation - Basics.text new file mode 100755 index 000000000..01ce740d5 --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Markdown Documentation - Basics.text @@ -0,0 +1,306 @@ +Markdown: Basics +================ + +<ul id="ProjectSubmenu"> + <li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li> + <li><a class="selected" title="Markdown Basics">Basics</a></li> + <li><a href="/projects/markdown/syntax" title="Markdown Syntax Documentation">Syntax</a></li> + <li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li> + <li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li> +</ul> + + +Getting the Gist of Markdown's Formatting Syntax +------------------------------------------------ + +This page offers a brief overview of what it's like to use Markdown. +The [syntax page] [s] provides complete, detailed documentation for +every feature, but Markdown should be very easy to pick up simply by +looking at a few examples of it in action. The examples on this page +are written in a before/after style, showing example syntax and the +HTML output produced by Markdown. + +It's also helpful to simply try Markdown out; the [Dingus] [d] is a +web application that allows you type your own Markdown-formatted text +and translate it to XHTML. + +**Note:** This document is itself written using Markdown; you +can [see the source for it by adding '.text' to the URL] [src]. + + [s]: /projects/markdown/syntax "Markdown Syntax" + [d]: /projects/markdown/dingus "Markdown Dingus" + [src]: /projects/markdown/basics.text + + +## Paragraphs, Headers, Blockquotes ## + +A paragraph is simply one or more consecutive lines of text, separated +by one or more blank lines. (A blank line is any line that looks like a +blank line -- a line containing nothing spaces or tabs is considered +blank.) Normal paragraphs should not be intended with spaces or tabs. + +Markdown offers two styles of headers: *Setext* and *atx*. +Setext-style headers for `<h1>` and `<h2>` are created by +"underlining" with equal signs (`=`) and hyphens (`-`), respectively. +To create an atx-style header, you put 1-6 hash marks (`#`) at the +beginning of the line -- the number of hashes equals the resulting +HTML header level. + +Blockquotes are indicated using email-style '`>`' angle brackets. + +Markdown: + + A First Level Header + ==================== + + A Second Level Header + --------------------- + + Now is the time for all good men to come to + the aid of their country. This is just a + regular paragraph. + + The quick brown fox jumped over the lazy + dog's back. + + ### Header 3 + + > This is a blockquote. + > + > This is the second paragraph in the blockquote. + > + > ## This is an H2 in a blockquote + + +Output: + + <h1>A First Level Header</h1> + + <h2>A Second Level Header</h2> + + <p>Now is the time for all good men to come to + the aid of their country. This is just a + regular paragraph.</p> + + <p>The quick brown fox jumped over the lazy + dog's back.</p> + + <h3>Header 3</h3> + + <blockquote> + <p>This is a blockquote.</p> + + <p>This is the second paragraph in the blockquote.</p> + + <h2>This is an H2 in a blockquote</h2> + </blockquote> + + + +### Phrase Emphasis ### + +Markdown uses asterisks and underscores to indicate spans of emphasis. + +Markdown: + + Some of these words *are emphasized*. + Some of these words _are emphasized also_. + + Use two asterisks for **strong emphasis**. + Or, if you prefer, __use two underscores instead__. + +Output: + + <p>Some of these words <em>are emphasized</em>. + Some of these words <em>are emphasized also</em>.</p> + + <p>Use two asterisks for <strong>strong emphasis</strong>. + Or, if you prefer, <strong>use two underscores instead</strong>.</p> + + + +## Lists ## + +Unordered (bulleted) lists use asterisks, pluses, and hyphens (`*`, +`+`, and `-`) as list markers. These three markers are +interchangable; this: + + * Candy. + * Gum. + * Booze. + +this: + + + Candy. + + Gum. + + Booze. + +and this: + + - Candy. + - Gum. + - Booze. + +all produce the same output: + + <ul> + <li>Candy.</li> + <li>Gum.</li> + <li>Booze.</li> + </ul> + +Ordered (numbered) lists use regular numbers, followed by periods, as +list markers: + + 1. Red + 2. Green + 3. Blue + +Output: + + <ol> + <li>Red</li> + <li>Green</li> + <li>Blue</li> + </ol> + +If you put blank lines between items, you'll get `<p>` tags for the +list item text. You can create multi-paragraph list items by indenting +the paragraphs by 4 spaces or 1 tab: + + * A list item. + + With multiple paragraphs. + + * Another item in the list. + +Output: + + <ul> + <li><p>A list item.</p> + <p>With multiple paragraphs.</p></li> + <li><p>Another item in the list.</p></li> + </ul> + + + +### Links ### + +Markdown supports two styles for creating links: *inline* and +*reference*. With both styles, you use square brackets to delimit the +text you want to turn into a link. + +Inline-style links use parentheses immediately after the link text. +For example: + + This is an [example link](http://example.com/). + +Output: + + <p>This is an <a href="http://example.com/"> + example link</a>.</p> + +Optionally, you may include a title attribute in the parentheses: + + This is an [example link](http://example.com/ "With a Title"). + +Output: + + <p>This is an <a href="http://example.com/" title="With a Title"> + example link</a>.</p> + +Reference-style links allow you to refer to your links by names, which +you define elsewhere in your document: + + I get 10 times more traffic from [Google][1] than from + [Yahoo][2] or [MSN][3]. + + [1]: http://google.com/ "Google" + [2]: http://search.yahoo.com/ "Yahoo Search" + [3]: http://search.msn.com/ "MSN Search" + +Output: + + <p>I get 10 times more traffic from <a href="http://google.com/" + title="Google">Google</a> than from <a href="http://search.yahoo.com/" + title="Yahoo Search">Yahoo</a> or <a href="http://search.msn.com/" + title="MSN Search">MSN</a>.</p> + +The title attribute is optional. Link names may contain letters, +numbers and spaces, but are *not* case sensitive: + + I start my morning with a cup of coffee and + [The New York Times][NY Times]. + + [ny times]: http://www.nytimes.com/ + +Output: + + <p>I start my morning with a cup of coffee and + <a href="http://www.nytimes.com/">The New York Times</a>.</p> + + +### Images ### + +Image syntax is very much like link syntax. + +Inline (titles are optional): + +  + +Reference-style: + + ![alt text][id] + + [id]: /path/to/img.jpg "Title" + +Both of the above examples produce the same output: + + <img src="/path/to/img.jpg" alt="alt text" title="Title" /> + + + +### Code ### + +In a regular paragraph, you can create code span by wrapping text in +backtick quotes. Any ampersands (`&`) and angle brackets (`<` or +`>`) will automatically be translated into HTML entities. This makes +it easy to use Markdown to write about HTML example code: + + I strongly recommend against using any `<blink>` tags. + + I wish SmartyPants used named entities like `&mdash;` + instead of decimal-encoded entites like `&#8212;`. + +Output: + + <p>I strongly recommend against using any + <code><blink></code> tags.</p> + + <p>I wish SmartyPants used named entities like + <code>&mdash;</code> instead of decimal-encoded + entites like <code>&#8212;</code>.</p> + + +To specify an entire block of pre-formatted code, indent every line of +the block by 4 spaces or 1 tab. Just like with code spans, `&`, `<`, +and `>` characters will be escaped automatically. + +Markdown: + + If you want your page to validate under XHTML 1.0 Strict, + you've got to put paragraph tags in your blockquotes: + + <blockquote> + <p>For example.</p> + </blockquote> + +Output: + + <p>If you want your page to validate under XHTML 1.0 Strict, + you've got to put paragraph tags in your blockquotes:</p> + + <pre><code><blockquote> + <p>For example.</p> + </blockquote> + </code></pre> diff --git a/test/javascripts/mdtest/fixtures/Markdown Documentation - Basics.xhtml b/test/javascripts/mdtest/fixtures/Markdown Documentation - Basics.xhtml new file mode 100755 index 000000000..2b85112ab --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Markdown Documentation - Basics.xhtml @@ -0,0 +1,319 @@ +<!-- + Changed for Discourse: + + - Sanitized elements and entities +--> +<h1>Markdown: Basics</h1> + +<ul> + <li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li> + <li><a title="Markdown Basics">Basics</a></li> + <li><a href="/projects/markdown/syntax" title="Markdown Syntax Documentation">Syntax</a></li> + <li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li> + <li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li> +</ul> + +<h2>Getting the Gist of Markdown's Formatting Syntax</h2> + +<p>This page offers a brief overview of what it's like to use Markdown. +The <a href="/projects/markdown/syntax" title="Markdown Syntax">syntax page</a> provides complete, detailed documentation for +every feature, but Markdown should be very easy to pick up simply by +looking at a few examples of it in action. The examples on this page +are written in a before/after style, showing example syntax and the +HTML output produced by Markdown.</p> + +<p>It's also helpful to simply try Markdown out; the <a href="/projects/markdown/dingus" title="Markdown Dingus">Dingus</a> is a +web application that allows you type your own Markdown-formatted text +and translate it to XHTML.</p> + +<p><strong>Note:</strong> This document is itself written using Markdown; you +can <a href="/projects/markdown/basics.text">see the source for it by adding '.text' to the URL</a>.</p> + +<h2>Paragraphs, Headers, Blockquotes</h2> + +<p>A paragraph is simply one or more consecutive lines of text, separated +by one or more blank lines. (A blank line is any line that looks like a +blank line -- a line containing nothing spaces or tabs is considered +blank.) Normal paragraphs should not be intended with spaces or tabs.</p> + +<p>Markdown offers two styles of headers: <em>Setext</em> and <em>atx</em>. +Setext-style headers for <code><h1></code> and <code><h2></code> are created by +"underlining" with equal signs (<code>=</code>) and hyphens (<code>-</code>), respectively. +To create an atx-style header, you put 1-6 hash marks (<code>#</code>) at the +beginning of the line -- the number of hashes equals the resulting +HTML header level.</p> + +<p>Blockquotes are indicated using email-style '<code>></code>' angle brackets.</p> + +<p>Markdown:</p> + +<pre><code>A First Level Header +==================== + +A Second Level Header +--------------------- + +Now is the time for all good men to come to +the aid of their country. This is just a +regular paragraph. + +The quick brown fox jumped over the lazy +dog's back. + +### Header 3 + +> This is a blockquote. +> +> This is the second paragraph in the blockquote. +> +> ## This is an H2 in a blockquote +</code></pre> + +<p>Output:</p> + +<pre><code><h1>A First Level Header</h1> + +<h2>A Second Level Header</h2> + +<p>Now is the time for all good men to come to +the aid of their country. This is just a +regular paragraph.</p> + +<p>The quick brown fox jumped over the lazy +dog's back.</p> + +<h3>Header 3</h3> + +<blockquote> + <p>This is a blockquote.</p> + + <p>This is the second paragraph in the blockquote.</p> + + <h2>This is an H2 in a blockquote</h2> +</blockquote> +</code></pre> + +<h3>Phrase Emphasis</h3> + +<p>Markdown uses asterisks and underscores to indicate spans of emphasis.</p> + +<p>Markdown:</p> + +<pre><code>Some of these words *are emphasized*. +Some of these words _are emphasized also_. + +Use two asterisks for **strong emphasis**. +Or, if you prefer, __use two underscores instead__. +</code></pre> + +<p>Output:</p> + +<pre><code><p>Some of these words <em>are emphasized</em>. +Some of these words <em>are emphasized also</em>.</p> + +<p>Use two asterisks for <strong>strong emphasis</strong>. +Or, if you prefer, <strong>use two underscores instead</strong>.</p> +</code></pre> + +<h2>Lists</h2> + +<p>Unordered (bulleted) lists use asterisks, pluses, and hyphens (<code>*</code>, +<code>+</code>, and <code>-</code>) as list markers. These three markers are +interchangable; this:</p> + +<pre><code>* Candy. +* Gum. +* Booze. +</code></pre> + +<p>this:</p> + +<pre><code>+ Candy. ++ Gum. ++ Booze. +</code></pre> + +<p>and this:</p> + +<pre><code>- Candy. +- Gum. +- Booze. +</code></pre> + +<p>all produce the same output:</p> + +<pre><code><ul> +<li>Candy.</li> +<li>Gum.</li> +<li>Booze.</li> +</ul> +</code></pre> + +<p>Ordered (numbered) lists use regular numbers, followed by periods, as +list markers:</p> + +<pre><code>1. Red +2. Green +3. Blue +</code></pre> + +<p>Output:</p> + +<pre><code><ol> +<li>Red</li> +<li>Green</li> +<li>Blue</li> +</ol> +</code></pre> + +<p>If you put blank lines between items, you'll get <code><p></code> tags for the +list item text. You can create multi-paragraph list items by indenting +the paragraphs by 4 spaces or 1 tab:</p> + +<pre><code>* A list item. + + With multiple paragraphs. + +* Another item in the list. +</code></pre> + +<p>Output:</p> + +<pre><code><ul> +<li><p>A list item.</p> +<p>With multiple paragraphs.</p></li> +<li><p>Another item in the list.</p></li> +</ul> +</code></pre> + +<h3>Links</h3> + +<p>Markdown supports two styles for creating links: <em>inline</em> and +<em>reference</em>. With both styles, you use square brackets to delimit the +text you want to turn into a link.</p> + +<p>Inline-style links use parentheses immediately after the link text. +For example:</p> + +<pre><code>This is an [example link](http://example.com/). +</code></pre> + +<p>Output:</p> + +<pre><code><p>This is an <a href="http://example.com/"> +example link</a>.</p> +</code></pre> + +<p>Optionally, you may include a title attribute in the parentheses:</p> + +<pre><code>This is an [example link](http://example.com/ "With a Title"). +</code></pre> + +<p>Output:</p> + +<pre><code><p>This is an <a href="http://example.com/" title="With a Title"> +example link</a>.</p> +</code></pre> + +<p>Reference-style links allow you to refer to your links by names, which +you define elsewhere in your document:</p> + +<pre><code>I get 10 times more traffic from [Google][1] than from +[Yahoo][2] or [MSN][3]. + +[1]: http://google.com/ "Google" +[2]: http://search.yahoo.com/ "Yahoo Search" +[3]: http://search.msn.com/ "MSN Search" +</code></pre> + +<p>Output:</p> + +<pre><code><p>I get 10 times more traffic from <a href="http://google.com/" +title="Google">Google</a> than from <a href="http://search.yahoo.com/" +title="Yahoo Search">Yahoo</a> or <a href="http://search.msn.com/" +title="MSN Search">MSN</a>.</p> +</code></pre> + +<p>The title attribute is optional. Link names may contain letters, +numbers and spaces, but are <em>not</em> case sensitive:</p> + +<pre><code>I start my morning with a cup of coffee and +[The New York Times][NY Times]. + +[ny times]: http://www.nytimes.com/ +</code></pre> + +<p>Output:</p> + +<pre><code><p>I start my morning with a cup of coffee and +<a href="http://www.nytimes.com/">The New York Times</a>.</p> +</code></pre> + +<h3>Images</h3> + +<p>Image syntax is very much like link syntax.</p> + +<p>Inline (titles are optional):</p> + +<pre><code> +</code></pre> + +<p>Reference-style:</p> + +<pre><code>![alt text][id] + +[id]: /path/to/img.jpg "Title" +</code></pre> + +<p>Both of the above examples produce the same output:</p> + +<pre><code><img src="/path/to/img.jpg" alt="alt text" title="Title" /> +</code></pre> + +<h3>Code</h3> + +<p>In a regular paragraph, you can create code span by wrapping text in +backtick quotes. Any ampersands (<code>&</code>) and angle brackets (<code><</code> or +<code>></code>) will automatically be translated into HTML entities. This makes +it easy to use Markdown to write about HTML example code:</p> + +<pre><code>I strongly recommend against using any `<blink>` tags. + +I wish SmartyPants used named entities like `&amp;mdash;` +instead of decimal-encoded entites like `&amp;#8212;`. +</code></pre> + +<p>Output:</p> + +<pre><code><p>I strongly recommend against using any +<code>&lt;blink&gt;</code> tags.</p> + +<p>I wish SmartyPants used named entities like +<code>&amp;mdash;</code> instead of decimal-encoded +entites like <code>&amp;#8212;</code>.</p> +</code></pre> + +<p>To specify an entire block of pre-formatted code, indent every line of +the block by 4 spaces or 1 tab. Just like with code spans, <code>&</code>, <code><</code>, +and <code>></code> characters will be escaped automatically.</p> + +<p>Markdown:</p> + +<pre><code>If you want your page to validate under XHTML 1.0 Strict, +you've got to put paragraph tags in your blockquotes: + + <blockquote> + <p>For example.</p> + </blockquote> +</code></pre> + +<p>Output:</p> + +<pre><code><p>If you want your page to validate under XHTML 1.0 Strict, +you've got to put paragraph tags in your blockquotes:</p> + +<pre><code>&lt;blockquote&gt; + &lt;p&gt;For example.&lt;/p&gt; +&lt;/blockquote&gt; +</code></pre> +</code></pre> diff --git a/test/javascripts/mdtest/fixtures/Markdown Documentation - Syntax.text b/test/javascripts/mdtest/fixtures/Markdown Documentation - Syntax.text new file mode 100755 index 000000000..cb70921d1 --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Markdown Documentation - Syntax.text @@ -0,0 +1,888 @@ +Markdown: Syntax +================ + +<ul id="ProjectSubmenu"> + <li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li> + <li><a href="/projects/markdown/basics" title="Markdown Basics">Basics</a></li> + <li><a class="selected" title="Markdown Syntax Documentation">Syntax</a></li> + <li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li> + <li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li> +</ul> + + +* [Overview](#overview) + * [Philosophy](#philosophy) + * [Inline HTML](#html) + * [Automatic Escaping for Special Characters](#autoescape) +* [Block Elements](#block) + * [Paragraphs and Line Breaks](#p) + * [Headers](#header) + * [Blockquotes](#blockquote) + * [Lists](#list) + * [Code Blocks](#precode) + * [Horizontal Rules](#hr) +* [Span Elements](#span) + * [Links](#link) + * [Emphasis](#em) + * [Code](#code) + * [Images](#img) +* [Miscellaneous](#misc) + * [Backslash Escapes](#backslash) + * [Automatic Links](#autolink) + + +**Note:** This document is itself written using Markdown; you +can [see the source for it by adding '.text' to the URL][src]. + + [src]: /projects/markdown/syntax.text + +* * * + +<h2 id="overview">Overview</h2> + +<h3 id="philosophy">Philosophy</h3> + +Markdown is intended to be as easy-to-read and easy-to-write as is feasible. + +Readability, however, is emphasized above all else. A Markdown-formatted +document should be publishable as-is, as plain text, without looking +like it's been marked up with tags or formatting instructions. While +Markdown's syntax has been influenced by several existing text-to-HTML +filters -- including [Setext] [1], [atx] [2], [Textile] [3], [reStructuredText] [4], +[Grutatext] [5], and [EtText] [6] -- the single biggest source of +inspiration for Markdown's syntax is the format of plain text email. + + [1]: http://docutils.sourceforge.net/mirror/setext.html + [2]: http://www.aaronsw.com/2002/atx/ + [3]: http://textism.com/tools/textile/ + [4]: http://docutils.sourceforge.net/rst.html + [5]: http://www.triptico.com/software/grutatxt.html + [6]: http://ettext.taint.org/doc/ + +To this end, Markdown's syntax is comprised entirely of punctuation +characters, which punctuation characters have been carefully chosen so +as to look like what they mean. E.g., asterisks around a word actually +look like \*emphasis\*. Markdown lists look like, well, lists. Even +blockquotes look like quoted passages of text, assuming you've ever +used email. + + + +<h3 id="html">Inline HTML</h3> + +Markdown's syntax is intended for one purpose: to be used as a +format for *writing* for the web. + +Markdown is not a replacement for HTML, or even close to it. Its +syntax is very small, corresponding only to a very small subset of +HTML tags. The idea is *not* to create a syntax that makes it easier +to insert HTML tags. In my opinion, HTML tags are already easy to +insert. The idea for Markdown is to make it easy to read, write, and +edit prose. HTML is a *publishing* format; Markdown is a *writing* +format. Thus, Markdown's formatting syntax only addresses issues that +can be conveyed in plain text. + +For any markup that is not covered by Markdown's syntax, you simply +use HTML itself. There's no need to preface it or delimit it to +indicate that you're switching from Markdown to HTML; you just use +the tags. + +The only restrictions are that block-level HTML elements -- e.g. `<div>`, +`<table>`, `<pre>`, `<p>`, etc. -- must be separated from surrounding +content by blank lines, and the start and end tags of the block should +not be indented with tabs or spaces. Markdown is smart enough not +to add extra (unwanted) `<p>` tags around HTML block-level tags. + +For example, to add an HTML table to a Markdown article: + + This is a regular paragraph. + + <table> + <tr> + <td>Foo</td> + </tr> + </table> + + This is another regular paragraph. + +Note that Markdown formatting syntax is not processed within block-level +HTML tags. E.g., you can't use Markdown-style `*emphasis*` inside an +HTML block. + +Span-level HTML tags -- e.g. `<span>`, `<cite>`, or `<del>` -- can be +used anywhere in a Markdown paragraph, list item, or header. If you +want, you can even use HTML tags instead of Markdown formatting; e.g. if +you'd prefer to use HTML `<a>` or `<img>` tags instead of Markdown's +link or image syntax, go right ahead. + +Unlike block-level HTML tags, Markdown syntax *is* processed within +span-level tags. + + +<h3 id="autoescape">Automatic Escaping for Special Characters</h3> + +In HTML, there are two characters that demand special treatment: `<` +and `&`. Left angle brackets are used to start tags; ampersands are +used to denote HTML entities. If you want to use them as literal +characters, you must escape them as entities, e.g. `<`, and +`&`. + +Ampersands in particular are bedeviling for web writers. If you want to +write about 'AT&T', you need to write '`AT&T`'. You even need to +escape ampersands within URLs. Thus, if you want to link to: + + http://images.google.com/images?num=30&q=larry+bird + +you need to encode the URL as: + + http://images.google.com/images?num=30&q=larry+bird + +in your anchor tag `href` attribute. Needless to say, this is easy to +forget, and is probably the single most common source of HTML validation +errors in otherwise well-marked-up web sites. + +Markdown allows you to use these characters naturally, taking care of +all the necessary escaping for you. If you use an ampersand as part of +an HTML entity, it remains unchanged; otherwise it will be translated +into `&`. + +So, if you want to include a copyright symbol in your article, you can write: + + © + +and Markdown will leave it alone. But if you write: + + AT&T + +Markdown will translate it to: + + AT&T + +Similarly, because Markdown supports [inline HTML](#html), if you use +angle brackets as delimiters for HTML tags, Markdown will treat them as +such. But if you write: + + 4 < 5 + +Markdown will translate it to: + + 4 < 5 + +However, inside Markdown code spans and blocks, angle brackets and +ampersands are *always* encoded automatically. This makes it easy to use +Markdown to write about HTML code. (As opposed to raw HTML, which is a +terrible format for writing about HTML syntax, because every single `<` +and `&` in your example code needs to be escaped.) + + +* * * + + +<h2 id="block">Block Elements</h2> + + +<h3 id="p">Paragraphs and Line Breaks</h3> + +A paragraph is simply one or more consecutive lines of text, separated +by one or more blank lines. (A blank line is any line that looks like a +blank line -- a line containing nothing but spaces or tabs is considered +blank.) Normal paragraphs should not be intended with spaces or tabs. + +The implication of the "one or more consecutive lines of text" rule is +that Markdown supports "hard-wrapped" text paragraphs. This differs +significantly from most other text-to-HTML formatters (including Movable +Type's "Convert Line Breaks" option) which translate every line break +character in a paragraph into a `<br />` tag. + +When you *do* want to insert a `<br />` break tag using Markdown, you +end a line with two or more spaces, then type return. + +Yes, this takes a tad more effort to create a `<br />`, but a simplistic +"every line break is a `<br />`" rule wouldn't work for Markdown. +Markdown's email-style [blockquoting][bq] and multi-paragraph [list items][l] +work best -- and look better -- when you format them with hard breaks. + + [bq]: #blockquote + [l]: #list + + + +<h3 id="header">Headers</h3> + +Markdown supports two styles of headers, [Setext] [1] and [atx] [2]. + +Setext-style headers are "underlined" using equal signs (for first-level +headers) and dashes (for second-level headers). For example: + + This is an H1 + ============= + + This is an H2 + ------------- + +Any number of underlining `=`'s or `-`'s will work. + +Atx-style headers use 1-6 hash characters at the start of the line, +corresponding to header levels 1-6. For example: + + # This is an H1 + + ## This is an H2 + + ###### This is an H6 + +Optionally, you may "close" atx-style headers. This is purely +cosmetic -- you can use this if you think it looks better. The +closing hashes don't even need to match the number of hashes +used to open the header. (The number of opening hashes +determines the header level.) : + + # This is an H1 # + + ## This is an H2 ## + + ### This is an H3 ###### + + +<h3 id="blockquote">Blockquotes</h3> + +Markdown uses email-style `>` characters for blockquoting. If you're +familiar with quoting passages of text in an email message, then you +know how to create a blockquote in Markdown. It looks best if you hard +wrap the text and put a `>` before every line: + + > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, + > consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. + > Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. + > + > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse + > id sem consectetuer libero luctus adipiscing. + +Markdown allows you to be lazy and only put the `>` before the first +line of a hard-wrapped paragraph: + + > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, + consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. + Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. + + > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse + id sem consectetuer libero luctus adipiscing. + +Blockquotes can be nested (i.e. a blockquote-in-a-blockquote) by +adding additional levels of `>`: + + > This is the first level of quoting. + > + > > This is nested blockquote. + > + > Back to the first level. + +Blockquotes can contain other Markdown elements, including headers, lists, +and code blocks: + + > ## This is a header. + > + > 1. This is the first list item. + > 2. This is the second list item. + > + > Here's some example code: + > + > return shell_exec("echo $input | $markdown_script"); + +Any decent text editor should make email-style quoting easy. For +example, with BBEdit, you can make a selection and choose Increase +Quote Level from the Text menu. + + +<h3 id="list">Lists</h3> + +Markdown supports ordered (numbered) and unordered (bulleted) lists. + +Unordered lists use asterisks, pluses, and hyphens -- interchangably +-- as list markers: + + * Red + * Green + * Blue + +is equivalent to: + + + Red + + Green + + Blue + +and: + + - Red + - Green + - Blue + +Ordered lists use numbers followed by periods: + + 1. Bird + 2. McHale + 3. Parish + +It's important to note that the actual numbers you use to mark the +list have no effect on the HTML output Markdown produces. The HTML +Markdown produces from the above list is: + + <ol> + <li>Bird</li> + <li>McHale</li> + <li>Parish</li> + </ol> + +If you instead wrote the list in Markdown like this: + + 1. Bird + 1. McHale + 1. Parish + +or even: + + 3. Bird + 1. McHale + 8. Parish + +you'd get the exact same HTML output. The point is, if you want to, +you can use ordinal numbers in your ordered Markdown lists, so that +the numbers in your source match the numbers in your published HTML. +But if you want to be lazy, you don't have to. + +If you do use lazy list numbering, however, you should still start the +list with the number 1. At some point in the future, Markdown may support +starting ordered lists at an arbitrary number. + +List markers typically start at the left margin, but may be indented by +up to three spaces. List markers must be followed by one or more spaces +or a tab. + +To make lists look nice, you can wrap items with hanging indents: + + * Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, + viverra nec, fringilla in, laoreet vitae, risus. + * Donec sit amet nisl. Aliquam semper ipsum sit amet velit. + Suspendisse id sem consectetuer libero luctus adipiscing. + +But if you want to be lazy, you don't have to: + + * Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, + viverra nec, fringilla in, laoreet vitae, risus. + * Donec sit amet nisl. Aliquam semper ipsum sit amet velit. + Suspendisse id sem consectetuer libero luctus adipiscing. + +If list items are separated by blank lines, Markdown will wrap the +items in `<p>` tags in the HTML output. For example, this input: + + * Bird + * Magic + +will turn into: + + <ul> + <li>Bird</li> + <li>Magic</li> + </ul> + +But this: + + * Bird + + * Magic + +will turn into: + + <ul> + <li><p>Bird</p></li> + <li><p>Magic</p></li> + </ul> + +List items may consist of multiple paragraphs. Each subsequent +paragraph in a list item must be intended by either 4 spaces +or one tab: + + 1. This is a list item with two paragraphs. Lorem ipsum dolor + sit amet, consectetuer adipiscing elit. Aliquam hendrerit + mi posuere lectus. + + Vestibulum enim wisi, viverra nec, fringilla in, laoreet + vitae, risus. Donec sit amet nisl. Aliquam semper ipsum + sit amet velit. + + 2. Suspendisse id sem consectetuer libero luctus adipiscing. + +It looks nice if you indent every line of the subsequent +paragraphs, but here again, Markdown will allow you to be +lazy: + + * This is a list item with two paragraphs. + + This is the second paragraph in the list item. You're + only required to indent the first line. Lorem ipsum dolor + sit amet, consectetuer adipiscing elit. + + * Another item in the same list. + +To put a blockquote within a list item, the blockquote's `>` +delimiters need to be indented: + + * A list item with a blockquote: + + > This is a blockquote + > inside a list item. + +To put a code block within a list item, the code block needs +to be indented *twice* -- 8 spaces or two tabs: + + * A list item with a code block: + + <code goes here> + + +It's worth noting that it's possible to trigger an ordered list by +accident, by writing something like this: + + 1986. What a great season. + +In other words, a *number-period-space* sequence at the beginning of a +line. To avoid this, you can backslash-escape the period: + + 1986\. What a great season. + + + +<h3 id="precode">Code Blocks</h3> + +Pre-formatted code blocks are used for writing about programming or +markup source code. Rather than forming normal paragraphs, the lines +of a code block are interpreted literally. Markdown wraps a code block +in both `<pre>` and `<code>` tags. + +To produce a code block in Markdown, simply indent every line of the +block by at least 4 spaces or 1 tab. For example, given this input: + + This is a normal paragraph: + + This is a code block. + +Markdown will generate: + + <p>This is a normal paragraph:</p> + + <pre><code>This is a code block. + </code></pre> + +One level of indentation -- 4 spaces or 1 tab -- is removed from each +line of the code block. For example, this: + + Here is an example of AppleScript: + + tell application "Foo" + beep + end tell + +will turn into: + + <p>Here is an example of AppleScript:</p> + + <pre><code>tell application "Foo" + beep + end tell + </code></pre> + +A code block continues until it reaches a line that is not indented +(or the end of the article). + +Within a code block, ampersands (`&`) and angle brackets (`<` and `>`) +are automatically converted into HTML entities. This makes it very +easy to include example HTML source code using Markdown -- just paste +it and indent it, and Markdown will handle the hassle of encoding the +ampersands and angle brackets. For example, this: + + <div class="footer"> + © 2004 Foo Corporation + </div> + +will turn into: + + <pre><code><div class="footer"> + &copy; 2004 Foo Corporation + </div> + </code></pre> + +Regular Markdown syntax is not processed within code blocks. E.g., +asterisks are just literal asterisks within a code block. This means +it's also easy to use Markdown to write about Markdown's own syntax. + + + +<h3 id="hr">Horizontal Rules</h3> + +You can produce a horizontal rule tag (`<hr />`) by placing three or +more hyphens, asterisks, or underscores on a line by themselves. If you +wish, you may use spaces between the hyphens or asterisks. Each of the +following lines will produce a horizontal rule: + + * * * + + *** + + ***** + + - - - + + --------------------------------------- + + _ _ _ + + +* * * + +<h2 id="span">Span Elements</h2> + +<h3 id="link">Links</h3> + +Markdown supports two style of links: *inline* and *reference*. + +In both styles, the link text is delimited by [square brackets]. + +To create an inline link, use a set of regular parentheses immediately +after the link text's closing square bracket. Inside the parentheses, +put the URL where you want the link to point, along with an *optional* +title for the link, surrounded in quotes. For example: + + This is [an example](http://example.com/ "Title") inline link. + + [This link](http://example.net/) has no title attribute. + +Will produce: + + <p>This is <a href="http://example.com/" title="Title"> + an example</a> inline link.</p> + + <p><a href="http://example.net/">This link</a> has no + title attribute.</p> + +If you're referring to a local resource on the same server, you can +use relative paths: + + See my [About](/about/) page for details. + +Reference-style links use a second set of square brackets, inside +which you place a label of your choosing to identify the link: + + This is [an example][id] reference-style link. + +You can optionally use a space to separate the sets of brackets: + + This is [an example] [id] reference-style link. + +Then, anywhere in the document, you define your link label like this, +on a line by itself: + + [id]: http://example.com/ "Optional Title Here" + +That is: + +* Square brackets containing the link identifier (optionally + indented from the left margin using up to three spaces); +* followed by a colon; +* followed by one or more spaces (or tabs); +* followed by the URL for the link; +* optionally followed by a title attribute for the link, enclosed + in double or single quotes. + +The link URL may, optionally, be surrounded by angle brackets: + + [id]: <http://example.com/> "Optional Title Here" + +You can put the title attribute on the next line and use extra spaces +or tabs for padding, which tends to look better with longer URLs: + + [id]: http://example.com/longish/path/to/resource/here + "Optional Title Here" + +Link definitions are only used for creating links during Markdown +processing, and are stripped from your document in the HTML output. + +Link definition names may constist of letters, numbers, spaces, and punctuation -- but they are *not* case sensitive. E.g. these two links: + + [link text][a] + [link text][A] + +are equivalent. + +The *implicit link name* shortcut allows you to omit the name of the +link, in which case the link text itself is used as the name. +Just use an empty set of square brackets -- e.g., to link the word +"Google" to the google.com web site, you could simply write: + + [Google][] + +And then define the link: + + [Google]: http://google.com/ + +Because link names may contain spaces, this shortcut even works for +multiple words in the link text: + + Visit [Daring Fireball][] for more information. + +And then define the link: + + [Daring Fireball]: http://daringfireball.net/ + +Link definitions can be placed anywhere in your Markdown document. I +tend to put them immediately after each paragraph in which they're +used, but if you want, you can put them all at the end of your +document, sort of like footnotes. + +Here's an example of reference links in action: + + I get 10 times more traffic from [Google] [1] than from + [Yahoo] [2] or [MSN] [3]. + + [1]: http://google.com/ "Google" + [2]: http://search.yahoo.com/ "Yahoo Search" + [3]: http://search.msn.com/ "MSN Search" + +Using the implicit link name shortcut, you could instead write: + + I get 10 times more traffic from [Google][] than from + [Yahoo][] or [MSN][]. + + [google]: http://google.com/ "Google" + [yahoo]: http://search.yahoo.com/ "Yahoo Search" + [msn]: http://search.msn.com/ "MSN Search" + +Both of the above examples will produce the following HTML output: + + <p>I get 10 times more traffic from <a href="http://google.com/" + title="Google">Google</a> than from + <a href="http://search.yahoo.com/" title="Yahoo Search">Yahoo</a> + or <a href="http://search.msn.com/" title="MSN Search">MSN</a>.</p> + +For comparison, here is the same paragraph written using +Markdown's inline link style: + + I get 10 times more traffic from [Google](http://google.com/ "Google") + than from [Yahoo](http://search.yahoo.com/ "Yahoo Search") or + [MSN](http://search.msn.com/ "MSN Search"). + +The point of reference-style links is not that they're easier to +write. The point is that with reference-style links, your document +source is vastly more readable. Compare the above examples: using +reference-style links, the paragraph itself is only 81 characters +long; with inline-style links, it's 176 characters; and as raw HTML, +it's 234 characters. In the raw HTML, there's more markup than there +is text. + +With Markdown's reference-style links, a source document much more +closely resembles the final output, as rendered in a browser. By +allowing you to move the markup-related metadata out of the paragraph, +you can add links without interrupting the narrative flow of your +prose. + + +<h3 id="em">Emphasis</h3> + +Markdown treats asterisks (`*`) and underscores (`_`) as indicators of +emphasis. Text wrapped with one `*` or `_` will be wrapped with an +HTML `<em>` tag; double `*`'s or `_`'s will be wrapped with an HTML +`<strong>` tag. E.g., this input: + + *single asterisks* + + _single underscores_ + + **double asterisks** + + __double underscores__ + +will produce: + + <em>single asterisks</em> + + <em>single underscores</em> + + <strong>double asterisks</strong> + + <strong>double underscores</strong> + +You can use whichever style you prefer; the lone restriction is that +the same character must be used to open and close an emphasis span. + +Emphasis can be used in the middle of a word: + + un*fucking*believable + +But if you surround an `*` or `_` with spaces, it'll be treated as a +literal asterisk or underscore. + +To produce a literal asterisk or underscore at a position where it +would otherwise be used as an emphasis delimiter, you can backslash +escape it: + + \*this text is surrounded by literal asterisks\* + + + +<h3 id="code">Code</h3> + +To indicate a span of code, wrap it with backtick quotes (`` ` ``). +Unlike a pre-formatted code block, a code span indicates code within a +normal paragraph. For example: + + Use the `printf()` function. + +will produce: + + <p>Use the <code>printf()</code> function.</p> + +To include a literal backtick character within a code span, you can use +multiple backticks as the opening and closing delimiters: + + ``There is a literal backtick (`) here.`` + +which will produce this: + + <p><code>There is a literal backtick (`) here.</code></p> + +The backtick delimiters surrounding a code span may include spaces -- +one after the opening, one before the closing. This allows you to place +literal backtick characters at the beginning or end of a code span: + + A single backtick in a code span: `` ` `` + + A backtick-delimited string in a code span: `` `foo` `` + +will produce: + + <p>A single backtick in a code span: <code>`</code></p> + + <p>A backtick-delimited string in a code span: <code>`foo`</code></p> + +With a code span, ampersands and angle brackets are encoded as HTML +entities automatically, which makes it easy to include example HTML +tags. Markdown will turn this: + + Please don't use any `<blink>` tags. + +into: + + <p>Please don't use any <code><blink></code> tags.</p> + +You can write this: + + `—` is the decimal-encoded equivalent of `—`. + +to produce: + + <p><code>&#8212;</code> is the decimal-encoded + equivalent of <code>&mdash;</code>.</p> + + + +<h3 id="img">Images</h3> + +Admittedly, it's fairly difficult to devise a "natural" syntax for +placing images into a plain text document format. + +Markdown uses an image syntax that is intended to resemble the syntax +for links, allowing for two styles: *inline* and *reference*. + +Inline image syntax looks like this: + +  + +  + +That is: + +* An exclamation mark: `!`; +* followed by a set of square brackets, containing the `alt` + attribute text for the image; +* followed by a set of parentheses, containing the URL or path to + the image, and an optional `title` attribute enclosed in double + or single quotes. + +Reference-style image syntax looks like this: + + ![Alt text][id] + +Where "id" is the name of a defined image reference. Image references +are defined using syntax identical to link references: + + [id]: url/to/image "Optional title attribute" + +As of this writing, Markdown has no syntax for specifying the +dimensions of an image; if this is important to you, you can simply +use regular HTML `<img>` tags. + + +* * * + + +<h2 id="misc">Miscellaneous</h2> + +<h3 id="autolink">Automatic Links</h3> + +Markdown supports a shortcut style for creating "automatic" links for URLs and email addresses: simply surround the URL or email address with angle brackets. What this means is that if you want to show the actual text of a URL or email address, and also have it be a clickable link, you can do this: + + <http://example.com/> + +Markdown will turn this into: + + <a href="http://example.com/">http://example.com/</a> + +Automatic links for email addresses work similarly, except that +Markdown will also perform a bit of randomized decimal and hex +entity-encoding to help obscure your address from address-harvesting +spambots. For example, Markdown will turn this: + + <address@example.com> + +into something like this: + + <a href="mailto:addre + ss@example.co + m">address@exa + mple.com</a> + +which will render in a browser as a clickable link to "address@example.com". + +(This sort of entity-encoding trick will indeed fool many, if not +most, address-harvesting bots, but it definitely won't fool all of +them. It's better than nothing, but an address published in this way +will probably eventually start receiving spam.) + + + +<h3 id="backslash">Backslash Escapes</h3> + +Markdown allows you to use backslash escapes to generate literal +characters which would otherwise have special meaning in Markdown's +formatting syntax. For example, if you wanted to surround a word with +literal asterisks (instead of an HTML `<em>` tag), you can backslashes +before the asterisks, like this: + + \*literal asterisks\* + +Markdown provides backslash escapes for the following characters: + + \ backslash + ` backtick + * asterisk + _ underscore + {} curly braces + [] square brackets + () parentheses + # hash mark + + plus sign + - minus sign (hyphen) + . dot + ! exclamation mark + diff --git a/test/javascripts/mdtest/fixtures/Markdown Documentation - Syntax.xhtml b/test/javascripts/mdtest/fixtures/Markdown Documentation - Syntax.xhtml new file mode 100755 index 000000000..fb7b76935 --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Markdown Documentation - Syntax.xhtml @@ -0,0 +1,949 @@ +<!-- + Changed for Discourse: + + - Sanitized elements and entities +--> +<h1>Markdown: Syntax</h1> + +<ul> + <li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li> + <li><a href="/projects/markdown/basics" title="Markdown Basics">Basics</a></li> + <li><a title="Markdown Syntax Documentation">Syntax</a></li> + <li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li> + <li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li> +</ul> + +<ul> +<li><a href="#overview">Overview</a> +<ul> +<li><a href="#philosophy">Philosophy</a></li> +<li><a href="#html">Inline HTML</a></li> +<li><a href="#autoescape">Automatic Escaping for Special Characters</a></li> +</ul></li> +<li><a href="#block">Block Elements</a> +<ul> +<li><a href="#p">Paragraphs and Line Breaks</a></li> +<li><a href="#header">Headers</a></li> +<li><a href="#blockquote">Blockquotes</a></li> +<li><a href="#list">Lists</a></li> +<li><a href="#precode">Code Blocks</a></li> +<li><a href="#hr">Horizontal Rules</a></li> +</ul></li> +<li><a href="#span">Span Elements</a> +<ul> +<li><a href="#link">Links</a></li> +<li><a href="#em">Emphasis</a></li> +<li><a href="#code">Code</a></li> +<li><a href="#img">Images</a></li> +</ul></li> +<li><a href="#misc">Miscellaneous</a> +<ul> +<li><a href="#backslash">Backslash Escapes</a></li> +<li><a href="#autolink">Automatic Links</a></li> +</ul></li> +</ul> + +<p><strong>Note:</strong> This document is itself written using Markdown; you +can <a href="/projects/markdown/syntax.text">see the source for it by adding '.text' to the URL</a>.</p> + +<hr /> + +<h2>Overview</h2> + +<h3>Philosophy</h3> + +<p>Markdown is intended to be as easy-to-read and easy-to-write as is feasible.</p> + +<p>Readability, however, is emphasized above all else. A Markdown-formatted +document should be publishable as-is, as plain text, without looking +like it's been marked up with tags or formatting instructions. While +Markdown's syntax has been influenced by several existing text-to-HTML +filters -- including <a href="http://docutils.sourceforge.net/mirror/setext.html">Setext</a>, <a href="http://www.aaronsw.com/2002/atx/">atx</a>, <a href="http://textism.com/tools/textile/">Textile</a>, <a href="http://docutils.sourceforge.net/rst.html">reStructuredText</a>, +<a href="http://www.triptico.com/software/grutatxt.html">Grutatext</a>, and <a href="http://ettext.taint.org/doc/">EtText</a> -- the single biggest source of +inspiration for Markdown's syntax is the format of plain text email.</p> + +<p>To this end, Markdown's syntax is comprised entirely of punctuation +characters, which punctuation characters have been carefully chosen so +as to look like what they mean. E.g., asterisks around a word actually +look like *emphasis*. Markdown lists look like, well, lists. Even +blockquotes look like quoted passages of text, assuming you've ever +used email.</p> + +<h3>Inline HTML</h3> + +<p>Markdown's syntax is intended for one purpose: to be used as a +format for <em>writing</em> for the web.</p> + +<p>Markdown is not a replacement for HTML, or even close to it. Its +syntax is very small, corresponding only to a very small subset of +HTML tags. The idea is <em>not</em> to create a syntax that makes it easier +to insert HTML tags. In my opinion, HTML tags are already easy to +insert. The idea for Markdown is to make it easy to read, write, and +edit prose. HTML is a <em>publishing</em> format; Markdown is a <em>writing</em> +format. Thus, Markdown's formatting syntax only addresses issues that +can be conveyed in plain text.</p> + +<p>For any markup that is not covered by Markdown's syntax, you simply +use HTML itself. There's no need to preface it or delimit it to +indicate that you're switching from Markdown to HTML; you just use +the tags.</p> + +<p>The only restrictions are that block-level HTML elements -- e.g. <code><div></code>, +<code><table></code>, <code><pre></code>, <code><p></code>, etc. -- must be separated from surrounding +content by blank lines, and the start and end tags of the block should +not be indented with tabs or spaces. Markdown is smart enough not +to add extra (unwanted) <code><p></code> tags around HTML block-level tags.</p> + +<p>For example, to add an HTML table to a Markdown article:</p> + +<pre><code>This is a regular paragraph. + +<table> + <tr> + <td>Foo</td> + </tr> +</table> + +This is another regular paragraph. +</code></pre> + +<p>Note that Markdown formatting syntax is not processed within block-level +HTML tags. E.g., you can't use Markdown-style <code>*emphasis*</code> inside an +HTML block.</p> + +<p>Span-level HTML tags -- e.g. <code><span></code>, <code><cite></code>, or <code><del></code> -- can be +used anywhere in a Markdown paragraph, list item, or header. If you +want, you can even use HTML tags instead of Markdown formatting; e.g. if +you'd prefer to use HTML <code><a></code> or <code><img></code> tags instead of Markdown's +link or image syntax, go right ahead.</p> + +<p>Unlike block-level HTML tags, Markdown syntax <em>is</em> processed within +span-level tags.</p> + +<h3>Automatic Escaping for Special Characters</h3> + +<p>In HTML, there are two characters that demand special treatment: <code><</code> +and <code>&</code>. Left angle brackets are used to start tags; ampersands are +used to denote HTML entities. If you want to use them as literal +characters, you must escape them as entities, e.g. <code>&lt;</code>, and +<code>&amp;</code>.</p> + +<p>Ampersands in particular are bedeviling for web writers. If you want to +write about 'AT&T', you need to write '<code>AT&amp;T</code>'. You even need to +escape ampersands within URLs. Thus, if you want to link to:</p> + +<pre><code>http://images.google.com/images?num=30&q=larry+bird +</code></pre> + +<p>you need to encode the URL as:</p> + +<pre><code>http://images.google.com/images?num=30&amp;q=larry+bird +</code></pre> + +<p>in your anchor tag <code>href</code> attribute. Needless to say, this is easy to +forget, and is probably the single most common source of HTML validation +errors in otherwise well-marked-up web sites.</p> + +<p>Markdown allows you to use these characters naturally, taking care of +all the necessary escaping for you. If you use an ampersand as part of +an HTML entity, it remains unchanged; otherwise it will be translated +into <code>&amp;</code>.</p> + +<p>So, if you want to include a copyright symbol in your article, you can write:</p> + +<pre><code>&copy; +</code></pre> + +<p>and Markdown will leave it alone. But if you write:</p> + +<pre><code>AT&T +</code></pre> + +<p>Markdown will translate it to:</p> + +<pre><code>AT&amp;T +</code></pre> + +<p>Similarly, because Markdown supports <a href="#html">inline HTML</a>, if you use +angle brackets as delimiters for HTML tags, Markdown will treat them as +such. But if you write:</p> + +<pre><code>4 < 5 +</code></pre> + +<p>Markdown will translate it to:</p> + +<pre><code>4 &lt; 5 +</code></pre> + +<p>However, inside Markdown code spans and blocks, angle brackets and +ampersands are <em>always</em> encoded automatically. This makes it easy to use +Markdown to write about HTML code. (As opposed to raw HTML, which is a +terrible format for writing about HTML syntax, because every single <code><</code> +and <code>&</code> in your example code needs to be escaped.)</p> + +<hr /> + +<h2>Block Elements</h2> + +<h3>Paragraphs and Line Breaks</h3> + +<p>A paragraph is simply one or more consecutive lines of text, separated +by one or more blank lines. (A blank line is any line that looks like a +blank line -- a line containing nothing but spaces or tabs is considered +blank.) Normal paragraphs should not be intended with spaces or tabs.</p> + +<p>The implication of the "one or more consecutive lines of text" rule is +that Markdown supports "hard-wrapped" text paragraphs. This differs +significantly from most other text-to-HTML formatters (including Movable +Type's "Convert Line Breaks" option) which translate every line break +character in a paragraph into a <code><br /></code> tag.</p> + +<p>When you <em>do</em> want to insert a <code><br /></code> break tag using Markdown, you +end a line with two or more spaces, then type return.</p> + +<p>Yes, this takes a tad more effort to create a <code><br /></code>, but a simplistic +"every line break is a <code><br /></code>" rule wouldn't work for Markdown. +Markdown's email-style <a href="#blockquote">blockquoting</a> and multi-paragraph <a href="#list">list items</a> +work best -- and look better -- when you format them with hard breaks.</p> + +<h3>Headers</h3> + +<p>Markdown supports two styles of headers, <a href="http://docutils.sourceforge.net/mirror/setext.html">Setext</a> and <a href="http://www.aaronsw.com/2002/atx/">atx</a>.</p> + +<p>Setext-style headers are "underlined" using equal signs (for first-level +headers) and dashes (for second-level headers). For example:</p> + +<pre><code>This is an H1 +============= + +This is an H2 +------------- +</code></pre> + +<p>Any number of underlining <code>=</code>'s or <code>-</code>'s will work.</p> + +<p>Atx-style headers use 1-6 hash characters at the start of the line, +corresponding to header levels 1-6. For example:</p> + +<pre><code># This is an H1 + +## This is an H2 + +###### This is an H6 +</code></pre> + +<p>Optionally, you may "close" atx-style headers. This is purely +cosmetic -- you can use this if you think it looks better. The +closing hashes don't even need to match the number of hashes +used to open the header. (The number of opening hashes +determines the header level.) :</p> + +<pre><code># This is an H1 # + +## This is an H2 ## + +### This is an H3 ###### +</code></pre> + +<h3>Blockquotes</h3> + +<p>Markdown uses email-style <code>></code> characters for blockquoting. If you're +familiar with quoting passages of text in an email message, then you +know how to create a blockquote in Markdown. It looks best if you hard +wrap the text and put a <code>></code> before every line:</p> + +<pre><code>> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, +> consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. +> Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. +> +> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse +> id sem consectetuer libero luctus adipiscing. +</code></pre> + +<p>Markdown allows you to be lazy and only put the <code>></code> before the first +line of a hard-wrapped paragraph:</p> + +<pre><code>> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, +consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. +Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. + +> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse +id sem consectetuer libero luctus adipiscing. +</code></pre> + +<p>Blockquotes can be nested (i.e. a blockquote-in-a-blockquote) by +adding additional levels of <code>></code>:</p> + +<pre><code>> This is the first level of quoting. +> +> > This is nested blockquote. +> +> Back to the first level. +</code></pre> + +<p>Blockquotes can contain other Markdown elements, including headers, lists, +and code blocks:</p> + +<pre><code>> ## This is a header. +> +> 1. This is the first list item. + +> 2. This is the second list item. + +> +> Here's some example code: +> +> return shell_exec("echo $input | $markdown_script"); +</code></pre> + +<p>Any decent text editor should make email-style quoting easy. For +example, with BBEdit, you can make a selection and choose Increase +Quote Level from the Text menu.</p> + +<h3>Lists</h3> + +<p>Markdown supports ordered (numbered) and unordered (bulleted) lists.</p> + +<p>Unordered lists use asterisks, pluses, and hyphens -- interchangably +-- as list markers:</p> + +<pre><code>* Red +* Green +* Blue +</code></pre> + +<p>is equivalent to:</p> + +<pre><code>+ Red ++ Green ++ Blue +</code></pre> + +<p>and:</p> + +<pre><code>- Red +- Green +- Blue +</code></pre> + +<p>Ordered lists use numbers followed by periods:</p> + +<pre><code>1. Bird +2. McHale +3. Parish +</code></pre> + +<p>It's important to note that the actual numbers you use to mark the +list have no effect on the HTML output Markdown produces. The HTML +Markdown produces from the above list is:</p> + +<pre><code><ol> +<li>Bird</li> +<li>McHale</li> +<li>Parish</li> +</ol> +</code></pre> + +<p>If you instead wrote the list in Markdown like this:</p> + +<pre><code>1. Bird +1. McHale +1. Parish +</code></pre> + +<p>or even:</p> + +<pre><code>3. Bird +1. McHale +8. Parish +</code></pre> + +<p>you'd get the exact same HTML output. The point is, if you want to, +you can use ordinal numbers in your ordered Markdown lists, so that +the numbers in your source match the numbers in your published HTML. +But if you want to be lazy, you don't have to.</p> + +<p>If you do use lazy list numbering, however, you should still start the +list with the number 1. At some point in the future, Markdown may support +starting ordered lists at an arbitrary number.</p> + +<p>List markers typically start at the left margin, but may be indented by +up to three spaces. List markers must be followed by one or more spaces +or a tab.</p> + +<p>To make lists look nice, you can wrap items with hanging indents:</p> + +<pre><code>* Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, + viverra nec, fringilla in, laoreet vitae, risus. +* Donec sit amet nisl. Aliquam semper ipsum sit amet velit. + Suspendisse id sem consectetuer libero luctus adipiscing. +</code></pre> + +<p>But if you want to be lazy, you don't have to:</p> + +<pre><code>* Lorem ipsum dolor sit amet, consectetuer adipiscing elit. +Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, +viverra nec, fringilla in, laoreet vitae, risus. +* Donec sit amet nisl. Aliquam semper ipsum sit amet velit. +Suspendisse id sem consectetuer libero luctus adipiscing. +</code></pre> + +<p>If list items are separated by blank lines, Markdown will wrap the +items in <code><p></code> tags in the HTML output. For example, this input:</p> + +<pre><code>* Bird +* Magic +</code></pre> + +<p>will turn into:</p> + +<pre><code><ul> +<li>Bird</li> +<li>Magic</li> +</ul> +</code></pre> + +<p>But this:</p> + +<pre><code>* Bird + +* Magic +</code></pre> + +<p>will turn into:</p> + +<pre><code><ul> +<li><p>Bird</p></li> +<li><p>Magic</p></li> +</ul> +</code></pre> + +<p>List items may consist of multiple paragraphs. Each subsequent +paragraph in a list item must be intended by either 4 spaces +or one tab:</p> + +<pre><code>1. This is a list item with two paragraphs. Lorem ipsum dolor + sit amet, consectetuer adipiscing elit. Aliquam hendrerit + mi posuere lectus. + + Vestibulum enim wisi, viverra nec, fringilla in, laoreet + vitae, risus. Donec sit amet nisl. Aliquam semper ipsum + sit amet velit. + +2. Suspendisse id sem consectetuer libero luctus adipiscing. +</code></pre> + +<p>It looks nice if you indent every line of the subsequent +paragraphs, but here again, Markdown will allow you to be +lazy:</p> + +<pre><code>* This is a list item with two paragraphs. + + This is the second paragraph in the list item. You're +only required to indent the first line. Lorem ipsum dolor +sit amet, consectetuer adipiscing elit. + +* Another item in the same list. +</code></pre> + +<p>To put a blockquote within a list item, the blockquote's <code>></code> +delimiters need to be indented:</p> + +<pre><code>* A list item with a blockquote: + + > This is a blockquote + > inside a list item. +</code></pre> + +<p>To put a code block within a list item, the code block needs +to be indented <em>twice</em> -- 8 spaces or two tabs:</p> + +<pre><code>* A list item with a code block: + + <code goes here> +</code></pre> + +<p>It's worth noting that it's possible to trigger an ordered list by +accident, by writing something like this:</p> + +<pre><code>1986. What a great season. +</code></pre> + +<p>In other words, a <em>number-period-space</em> sequence at the beginning of a +line. To avoid this, you can backslash-escape the period:</p> + +<pre><code>1986\. What a great season. +</code></pre> + +<h3>Code Blocks</h3> + +<p>Pre-formatted code blocks are used for writing about programming or +markup source code. Rather than forming normal paragraphs, the lines +of a code block are interpreted literally. Markdown wraps a code block +in both <code><pre></code> and <code><code></code> tags.</p> + +<p>To produce a code block in Markdown, simply indent every line of the +block by at least 4 spaces or 1 tab. For example, given this input:</p> + +<pre><code>This is a normal paragraph: + + This is a code block. +</code></pre> + +<p>Markdown will generate:</p> + +<pre><code><p>This is a normal paragraph:</p> + +<pre><code>This is a code block. +</code></pre> +</code></pre> + +<p>One level of indentation -- 4 spaces or 1 tab -- is removed from each +line of the code block. For example, this:</p> + +<pre><code>Here is an example of AppleScript: + + tell application "Foo" + beep + end tell +</code></pre> + +<p>will turn into:</p> + +<pre><code><p>Here is an example of AppleScript:</p> + +<pre><code>tell application "Foo" + beep +end tell +</code></pre> +</code></pre> + +<p>A code block continues until it reaches a line that is not indented +(or the end of the article).</p> + +<p>Within a code block, ampersands (<code>&</code>) and angle brackets (<code><</code> and <code>></code>) +are automatically converted into HTML entities. This makes it very +easy to include example HTML source code using Markdown -- just paste +it and indent it, and Markdown will handle the hassle of encoding the +ampersands and angle brackets. For example, this:</p> + +<pre><code><div class="footer"> + &copy; 2004 Foo Corporation + </div> +</code></pre> + +<p>will turn into:</p> + +<pre><code><pre><code>&lt;div class="footer"&gt; + &amp;copy; 2004 Foo Corporation +&lt;/div&gt; +</code></pre> +</code></pre> + +<p>Regular Markdown syntax is not processed within code blocks. E.g., +asterisks are just literal asterisks within a code block. This means +it's also easy to use Markdown to write about Markdown's own syntax.</p> + +<h3>Horizontal Rules</h3> + +<p>You can produce a horizontal rule tag (<code><hr /></code>) by placing three or +more hyphens, asterisks, or underscores on a line by themselves. If you +wish, you may use spaces between the hyphens or asterisks. Each of the +following lines will produce a horizontal rule:</p> + +<pre><code>* * * + +*** + +***** + +- - - + +--------------------------------------- + +_ _ _ +</code></pre> + +<hr /> + +<h2>Span Elements</h2> + +<h3>Links</h3> + +<p>Markdown supports two style of links: <em>inline</em> and <em>reference</em>.</p> + +<p>In both styles, the link text is delimited by [square brackets].</p> + +<p>To create an inline link, use a set of regular parentheses immediately +after the link text's closing square bracket. Inside the parentheses, +put the URL where you want the link to point, along with an <em>optional</em> +title for the link, surrounded in quotes. For example:</p> + +<pre><code>This is [an example](http://example.com/ "Title") inline link. + +[This link](http://example.net/) has no title attribute. +</code></pre> + +<p>Will produce:</p> + +<pre><code><p>This is <a href="http://example.com/" title="Title"> +an example</a> inline link.</p> + +<p><a href="http://example.net/">This link</a> has no +title attribute.</p> +</code></pre> + +<p>If you're referring to a local resource on the same server, you can +use relative paths:</p> + +<pre><code>See my [About](/about/) page for details. +</code></pre> + +<p>Reference-style links use a second set of square brackets, inside +which you place a label of your choosing to identify the link:</p> + +<pre><code>This is [an example][id] reference-style link. +</code></pre> + +<p>You can optionally use a space to separate the sets of brackets:</p> + +<pre><code>This is [an example] [id] reference-style link. +</code></pre> + +<p>Then, anywhere in the document, you define your link label like this, +on a line by itself:</p> + +<pre><code>[id]: http://example.com/ "Optional Title Here" +</code></pre> + +<p>That is:</p> + +<ul> +<li>Square brackets containing the link identifier (optionally +indented from the left margin using up to three spaces);</li> +<li>followed by a colon;</li> +<li>followed by one or more spaces (or tabs);</li> +<li>followed by the URL for the link;</li> +<li>optionally followed by a title attribute for the link, enclosed +in double or single quotes.</li> +</ul> + +<p>The link URL may, optionally, be surrounded by angle brackets:</p> + +<pre><code>[id]: <http://example.com/> "Optional Title Here" +</code></pre> + +<p>You can put the title attribute on the next line and use extra spaces +or tabs for padding, which tends to look better with longer URLs:</p> + +<pre><code>[id]: http://example.com/longish/path/to/resource/here + "Optional Title Here" +</code></pre> + +<p>Link definitions are only used for creating links during Markdown +processing, and are stripped from your document in the HTML output.</p> + +<p>Link definition names may constist of letters, numbers, spaces, and punctuation -- but they are <em>not</em> case sensitive. E.g. these two links:</p> + +<pre><code>[link text][a] +[link text][A] +</code></pre> + +<p>are equivalent.</p> + +<p>The <em>implicit link name</em> shortcut allows you to omit the name of the +link, in which case the link text itself is used as the name. +Just use an empty set of square brackets -- e.g., to link the word +"Google" to the google.com web site, you could simply write:</p> + +<pre><code>[Google][] +</code></pre> + +<p>And then define the link:</p> + +<pre><code>[Google]: http://google.com/ +</code></pre> + +<p>Because link names may contain spaces, this shortcut even works for +multiple words in the link text:</p> + +<pre><code>Visit [Daring Fireball][] for more information. +</code></pre> + +<p>And then define the link:</p> + +<pre><code>[Daring Fireball]: http://daringfireball.net/ +</code></pre> + +<p>Link definitions can be placed anywhere in your Markdown document. I +tend to put them immediately after each paragraph in which they're +used, but if you want, you can put them all at the end of your +document, sort of like footnotes.</p> + +<p>Here's an example of reference links in action:</p> + +<pre><code>I get 10 times more traffic from [Google] [1] than from +[Yahoo] [2] or [MSN] [3]. + + [1]: http://google.com/ "Google" + [2]: http://search.yahoo.com/ "Yahoo Search" + [3]: http://search.msn.com/ "MSN Search" +</code></pre> + +<p>Using the implicit link name shortcut, you could instead write:</p> + +<pre><code>I get 10 times more traffic from [Google][] than from +[Yahoo][] or [MSN][]. + + [google]: http://google.com/ "Google" + [yahoo]: http://search.yahoo.com/ "Yahoo Search" + [msn]: http://search.msn.com/ "MSN Search" +</code></pre> + +<p>Both of the above examples will produce the following HTML output:</p> + +<pre><code><p>I get 10 times more traffic from <a href="http://google.com/" +title="Google">Google</a> than from +<a href="http://search.yahoo.com/" title="Yahoo Search">Yahoo</a> +or <a href="http://search.msn.com/" title="MSN Search">MSN</a>.</p> +</code></pre> + +<p>For comparison, here is the same paragraph written using +Markdown's inline link style:</p> + +<pre><code>I get 10 times more traffic from [Google](http://google.com/ "Google") +than from [Yahoo](http://search.yahoo.com/ "Yahoo Search") or +[MSN](http://search.msn.com/ "MSN Search"). +</code></pre> + +<p>The point of reference-style links is not that they're easier to +write. The point is that with reference-style links, your document +source is vastly more readable. Compare the above examples: using +reference-style links, the paragraph itself is only 81 characters +long; with inline-style links, it's 176 characters; and as raw HTML, +it's 234 characters. In the raw HTML, there's more markup than there +is text.</p> + +<p>With Markdown's reference-style links, a source document much more +closely resembles the final output, as rendered in a browser. By +allowing you to move the markup-related metadata out of the paragraph, +you can add links without interrupting the narrative flow of your +prose.</p> + +<h3>Emphasis</h3> + +<p>Markdown treats asterisks (<code>*</code>) and underscores (<code>_</code>) as indicators of +emphasis. Text wrapped with one <code>*</code> or <code>_</code> will be wrapped with an +HTML <code><em></code> tag; double <code>*</code>'s or <code>_</code>'s will be wrapped with an HTML +<code><strong></code> tag. E.g., this input:</p> + +<pre><code>*single asterisks* + +_single underscores_ + +**double asterisks** + +__double underscores__ +</code></pre> + +<p>will produce:</p> + +<pre><code><em>single asterisks</em> + +<em>single underscores</em> + +<strong>double asterisks</strong> + +<strong>double underscores</strong> +</code></pre> + +<p>You can use whichever style you prefer; the lone restriction is that +the same character must be used to open and close an emphasis span.</p> + +<p>Emphasis can be used in the middle of a word:</p> + +<pre><code>un*fucking*believable +</code></pre> + +<p>But if you surround an <code>*</code> or <code>_</code> with spaces, it'll be treated as a +literal asterisk or underscore.</p> + +<p>To produce a literal asterisk or underscore at a position where it +would otherwise be used as an emphasis delimiter, you can backslash +escape it:</p> + +<pre><code>\*this text is surrounded by literal asterisks\* +</code></pre> + +<h3>Code</h3> + +<p>To indicate a span of code, wrap it with backtick quotes (<code>`</code>). +Unlike a pre-formatted code block, a code span indicates code within a +normal paragraph. For example:</p> + +<pre><code>Use the `printf()` function. +</code></pre> + +<p>will produce:</p> + +<pre><code><p>Use the <code>printf()</code> function.</p> +</code></pre> + +<p>To include a literal backtick character within a code span, you can use +multiple backticks as the opening and closing delimiters:</p> + +<pre><code>``There is a literal backtick (`) here.`` +</code></pre> + +<p>which will produce this:</p> + +<pre><code><p><code>There is a literal backtick (`) here.</code></p> +</code></pre> + +<p>The backtick delimiters surrounding a code span may include spaces -- +one after the opening, one before the closing. This allows you to place +literal backtick characters at the beginning or end of a code span:</p> + +<pre><code>A single backtick in a code span: `` ` `` + +A backtick-delimited string in a code span: `` `foo` `` +</code></pre> + +<p>will produce:</p> + +<pre><code><p>A single backtick in a code span: <code>`</code></p> + +<p>A backtick-delimited string in a code span: <code>`foo`</code></p> +</code></pre> + +<p>With a code span, ampersands and angle brackets are encoded as HTML +entities automatically, which makes it easy to include example HTML +tags. Markdown will turn this:</p> + +<pre><code>Please don't use any `<blink>` tags. +</code></pre> + +<p>into:</p> + +<pre><code><p>Please don't use any <code>&lt;blink&gt;</code> tags.</p> +</code></pre> + +<p>You can write this:</p> + +<pre><code>`&#8212;` is the decimal-encoded equivalent of `&mdash;`. +</code></pre> + +<p>to produce:</p> + +<pre><code><p><code>&amp;#8212;</code> is the decimal-encoded +equivalent of <code>&amp;mdash;</code>.</p> +</code></pre> + +<h3>Images</h3> + +<p>Admittedly, it's fairly difficult to devise a "natural" syntax for +placing images into a plain text document format.</p> + +<p>Markdown uses an image syntax that is intended to resemble the syntax +for links, allowing for two styles: <em>inline</em> and <em>reference</em>.</p> + +<p>Inline image syntax looks like this:</p> + +<pre><code> + + +</code></pre> + +<p>That is:</p> + +<ul> +<li>An exclamation mark: <code>!</code>;</li> +<li>followed by a set of square brackets, containing the <code>alt</code> +attribute text for the image;</li> +<li>followed by a set of parentheses, containing the URL or path to +the image, and an optional <code>title</code> attribute enclosed in double +or single quotes.</li> +</ul> + +<p>Reference-style image syntax looks like this:</p> + +<pre><code>![Alt text][id] +</code></pre> + +<p>Where "id" is the name of a defined image reference. Image references +are defined using syntax identical to link references:</p> + +<pre><code>[id]: url/to/image "Optional title attribute" +</code></pre> + +<p>As of this writing, Markdown has no syntax for specifying the +dimensions of an image; if this is important to you, you can simply +use regular HTML <code><img></code> tags.</p> + +<hr /> + +<h2>Miscellaneous</h2> + +<h3>Automatic Links</h3> + +<p>Markdown supports a shortcut style for creating "automatic" links for URLs and email addresses: simply surround the URL or email address with angle brackets. What this means is that if you want to show the actual text of a URL or email address, and also have it be a clickable link, you can do this:</p> + +<pre><code><http://example.com/> +</code></pre> + +<p>Markdown will turn this into:</p> + +<pre><code><a href="http://example.com/">http://example.com/</a> +</code></pre> + +<p>Automatic links for email addresses work similarly, except that +Markdown will also perform a bit of randomized decimal and hex +entity-encoding to help obscure your address from address-harvesting +spambots. For example, Markdown will turn this:</p> + +<pre><code><address@example.com> +</code></pre> + +<p>into something like this:</p> + +<pre><code><a href="&#x6D;&#x61;i&#x6C;&#x74;&#x6F;:&#x61;&#x64;&#x64;&#x72;&#x65; +&#115;&#115;&#64;&#101;&#120;&#x61;&#109;&#x70;&#x6C;e&#x2E;&#99;&#111; +&#109;">&#x61;&#x64;&#x64;&#x72;&#x65;&#115;&#115;&#64;&#101;&#120;&#x61; +&#109;&#x70;&#x6C;e&#x2E;&#99;&#111;&#109;</a> +</code></pre> + +<p>which will render in a browser as a clickable link to "address@example.com".</p> + +<p>(This sort of entity-encoding trick will indeed fool many, if not +most, address-harvesting bots, but it definitely won't fool all of +them. It's better than nothing, but an address published in this way +will probably eventually start receiving spam.)</p> + +<h3>Backslash Escapes</h3> + +<p>Markdown allows you to use backslash escapes to generate literal +characters which would otherwise have special meaning in Markdown's +formatting syntax. For example, if you wanted to surround a word with +literal asterisks (instead of an HTML <code><em></code> tag), you can backslashes +before the asterisks, like this:</p> + +<pre><code>\*literal asterisks\* +</code></pre> + +<p>Markdown provides backslash escapes for the following characters:</p> + +<pre><code>\ backslash +` backtick +* asterisk +_ underscore +{} curly braces +[] square brackets +() parentheses +# hash mark ++ plus sign +- minus sign (hyphen) +. dot +! exclamation mark +</code></pre> diff --git a/test/javascripts/mdtest/fixtures/Nested blockquotes.text b/test/javascripts/mdtest/fixtures/Nested blockquotes.text new file mode 100755 index 000000000..ed3c624ff --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Nested blockquotes.text @@ -0,0 +1,5 @@ +> foo +> +> > bar +> +> foo diff --git a/test/javascripts/mdtest/fixtures/Nested blockquotes.xhtml b/test/javascripts/mdtest/fixtures/Nested blockquotes.xhtml new file mode 100755 index 000000000..d8ec7f8e0 --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Nested blockquotes.xhtml @@ -0,0 +1,9 @@ +<blockquote> + <p>foo</p> + + <blockquote> + <p>bar</p> + </blockquote> + + <p>foo</p> +</blockquote> diff --git a/test/javascripts/mdtest/fixtures/Ordered and unordered lists.text b/test/javascripts/mdtest/fixtures/Ordered and unordered lists.text new file mode 100755 index 000000000..37dee0fa9 --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Ordered and unordered lists.text @@ -0,0 +1,131 @@ +## Unordered + +Asterisks tight: + +* asterisk 1 +* asterisk 2 +* asterisk 3 + + +Asterisks loose: + +* asterisk 1 + +* asterisk 2 + +* asterisk 3 + +* * * + +Pluses tight: + ++ Plus 1 ++ Plus 2 ++ Plus 3 + + +Pluses loose: + ++ Plus 1 + ++ Plus 2 + ++ Plus 3 + +* * * + + +Minuses tight: + +- Minus 1 +- Minus 2 +- Minus 3 + + +Minuses loose: + +- Minus 1 + +- Minus 2 + +- Minus 3 + + +## Ordered + +Tight: + +1. First +2. Second +3. Third + +and: + +1. One +2. Two +3. Three + + +Loose using tabs: + +1. First + +2. Second + +3. Third + +and using spaces: + +1. One + +2. Two + +3. Three + +Multiple paragraphs: + +1. Item 1, graf one. + + Item 2. graf two. The quick brown fox jumped over the lazy dog's + back. + +2. Item 2. + +3. Item 3. + + + +## Nested + +* Tab + * Tab + * Tab + +Here's another: + +1. First +2. Second: + * Fee + * Fie + * Foe +3. Third + +Same thing but with paragraphs: + +1. First + +2. Second: + * Fee + * Fie + * Foe + +3. Third + + +This was an error in Markdown 1.0.1: + +* this + + * sub + + that diff --git a/test/javascripts/mdtest/fixtures/Ordered and unordered lists.xhtml b/test/javascripts/mdtest/fixtures/Ordered and unordered lists.xhtml new file mode 100755 index 000000000..ba71eab39 --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Ordered and unordered lists.xhtml @@ -0,0 +1,148 @@ +<h2>Unordered</h2> + +<p>Asterisks tight:</p> + +<ul> +<li>asterisk 1</li> +<li>asterisk 2</li> +<li>asterisk 3</li> +</ul> + +<p>Asterisks loose:</p> + +<ul> +<li><p>asterisk 1</p></li> +<li><p>asterisk 2</p></li> +<li><p>asterisk 3</p></li> +</ul> + +<hr /> + +<p>Pluses tight:</p> + +<ul> +<li>Plus 1</li> +<li>Plus 2</li> +<li>Plus 3</li> +</ul> + +<p>Pluses loose:</p> + +<ul> +<li><p>Plus 1</p></li> +<li><p>Plus 2</p></li> +<li><p>Plus 3</p></li> +</ul> + +<hr /> + +<p>Minuses tight:</p> + +<ul> +<li>Minus 1</li> +<li>Minus 2</li> +<li>Minus 3</li> +</ul> + +<p>Minuses loose:</p> + +<ul> +<li><p>Minus 1</p></li> +<li><p>Minus 2</p></li> +<li><p>Minus 3</p></li> +</ul> + +<h2>Ordered</h2> + +<p>Tight:</p> + +<ol> +<li>First</li> +<li>Second</li> +<li>Third</li> +</ol> + +<p>and:</p> + +<ol> +<li>One</li> +<li>Two</li> +<li>Three</li> +</ol> + +<p>Loose using tabs:</p> + +<ol> +<li><p>First</p></li> +<li><p>Second</p></li> +<li><p>Third</p></li> +</ol> + +<p>and using spaces:</p> + +<ol> +<li><p>One</p></li> +<li><p>Two</p></li> +<li><p>Three</p></li> +</ol> + +<p>Multiple paragraphs:</p> + +<ol> +<li><p>Item 1, graf one.</p> + +<p>Item 2. graf two. The quick brown fox jumped over the lazy dog's +back.</p></li> +<li><p>Item 2.</p></li> +<li><p>Item 3.</p></li> +</ol> + +<h2>Nested</h2> + +<ul> +<li>Tab +<ul> +<li>Tab +<ul> +<li>Tab</li> +</ul></li> +</ul></li> +</ul> + +<p>Here's another:</p> + +<ol> +<li>First</li> +<li>Second: +<ul> +<li>Fee</li> +<li>Fie</li> +<li>Foe</li> +</ul></li> +<li>Third</li> +</ol> + +<p>Same thing but with paragraphs:</p> + +<ol> +<li><p>First</p></li> +<li><p>Second:</p> + +<ul> +<li>Fee</li> +<li>Fie</li> +<li>Foe</li> +</ul></li> +<li><p>Third</p></li> +</ol> + + +<p>This was an error in Markdown 1.0.1:</p> + +<ul> +<li><p>this</p> + +<ul><li>sub</li></ul> + +<p>that</p></li> +</ul> diff --git a/test/javascripts/mdtest/fixtures/Strong and em together.text b/test/javascripts/mdtest/fixtures/Strong and em together.text new file mode 100755 index 000000000..95ee690db --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Strong and em together.text @@ -0,0 +1,7 @@ +***This is strong and em.*** + +So is ***this*** word. + +___This is strong and em.___ + +So is ___this___ word. diff --git a/test/javascripts/mdtest/fixtures/Strong and em together.xhtml b/test/javascripts/mdtest/fixtures/Strong and em together.xhtml new file mode 100755 index 000000000..71ec78c70 --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Strong and em together.xhtml @@ -0,0 +1,7 @@ +<p><strong><em>This is strong and em.</em></strong></p> + +<p>So is <strong><em>this</em></strong> word.</p> + +<p><strong><em>This is strong and em.</em></strong></p> + +<p>So is <strong><em>this</em></strong> word.</p> diff --git a/test/javascripts/mdtest/fixtures/Tabs.text b/test/javascripts/mdtest/fixtures/Tabs.text new file mode 100755 index 000000000..589d1136e --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Tabs.text @@ -0,0 +1,21 @@ ++ this is a list item + indented with tabs + ++ this is a list item + indented with spaces + +Code: + + this code block is indented by one tab + +And: + + this code block is indented by two tabs + +And: + + + this is an example list item + indented with tabs + + + this is an example list item + indented with spaces diff --git a/test/javascripts/mdtest/fixtures/Tabs.xhtml b/test/javascripts/mdtest/fixtures/Tabs.xhtml new file mode 100755 index 000000000..3301ba803 --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Tabs.xhtml @@ -0,0 +1,25 @@ +<ul> +<li><p>this is a list item +indented with tabs</p></li> +<li><p>this is a list item +indented with spaces</p></li> +</ul> + +<p>Code:</p> + +<pre><code>this code block is indented by one tab +</code></pre> + +<p>And:</p> + +<pre><code> this code block is indented by two tabs +</code></pre> + +<p>And:</p> + +<pre><code>+ this is an example list item + indented with tabs + ++ this is an example list item + indented with spaces +</code></pre> diff --git a/test/javascripts/mdtest/fixtures/Tidyness.text b/test/javascripts/mdtest/fixtures/Tidyness.text new file mode 100755 index 000000000..5f18b8da2 --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Tidyness.text @@ -0,0 +1,5 @@ +> A list within a blockquote: +> +> * asterisk 1 +> * asterisk 2 +> * asterisk 3 diff --git a/test/javascripts/mdtest/fixtures/Tidyness.xhtml b/test/javascripts/mdtest/fixtures/Tidyness.xhtml new file mode 100755 index 000000000..f2a8ce70f --- /dev/null +++ b/test/javascripts/mdtest/fixtures/Tidyness.xhtml @@ -0,0 +1,8 @@ +<blockquote> +<p>A list within a blockquote:</p> +<ul> +<li>asterisk 1</li> +<li>asterisk 2</li> +<li>asterisk 3</li> +</ul> +</blockquote> diff --git a/test/javascripts/mdtest/mdtest.js.erb b/test/javascripts/mdtest/mdtest.js.erb new file mode 100644 index 000000000..0384b3464 --- /dev/null +++ b/test/javascripts/mdtest/mdtest.js.erb @@ -0,0 +1,53 @@ +module("MDTest", { + setup: function() { + Discourse.SiteSettings.traditional_markdown_linebreaks = false; + } +}); + +// This is cheating, but the trivial differences between sanitization +// do not affect formatting. +function normalize(str) { + return str.replace(/\n\s*/g, ''). + replace(/ \/\>/g, '/>'). + replace(/ ?/g, "\t"). + replace(/"/g, '"'); +} + +var md = function(input, expected, text) { + var result = Discourse.Markdown.cook(input, {mentionLookup: false, sanitize: true, traditional_markdown_linebreaks: true}), + resultNorm = normalize(result), + expectedNorm = normalize(expected), + same = (result === expected) || (resultNorm === expectedNorm); + + + if (same) { + ok(same, text); + } else { + console.log(resultNorm); + console.log(expectedNorm); + equal(resultNorm, expectedNorm, text); + } +}; + +test("first", function(){ + equal(1, 1, "cool") +}); + +<% + def mdtest_suite + result = "" + Dir.glob("#{Rails.root}/test/javascripts/mdtest/fixtures/*.text").each do |f| + + filename_no_ext = f.sub(/\.text$/, '') + filename = Pathname.new(filename_no_ext) + + text = File.read(f) + html = File.read("#{filename_no_ext}.xhtml").gsub(/\<\!\-\-(.*?)\-\-\>/m, '') + result << "test(\"#{filename}\", function() { md(#{text.to_json}, #{html.to_json}, 'passes MDTest'); });\n" + end + result + end + +%> + +<%= mdtest_suite %> \ No newline at end of file diff --git a/vendor/assets/javascripts/better_markdown.js b/vendor/assets/javascripts/better_markdown.js index ab3ffaae6..c73224f03 100644 --- a/vendor/assets/javascripts/better_markdown.js +++ b/vendor/assets/javascripts/better_markdown.js @@ -4,16 +4,10 @@ * We have replaced the strong/em handlers because we prefer them only to work on word boundaries. - * We removed the maraku support as we don't use it. + // Fix code within attrs + if (prev && (typeof prev[0] === "string") && prev[0].match(/<[^>]+$/)) { return; } - * We don't escape the contents of HTML as we prefer to use a whitelist. - - * We fixed a bug where references can be created directly following a list. - - * Fix to blockquote to handle spaces in front and when nested. - - * Note the name BetterMarkdown doesn't mean it's *better* than markdown-js, it refers - to it being better than our previous markdown parser! + // __RAW__ */ @@ -260,27 +254,26 @@ function create_reference(attrs, m) { * the block processing. */ Markdown.prototype.processBlock = function processBlock( block, next ) { - var cbs = this.dialect.block, - ord = cbs.__order__; + var cbs = this.dialect.block, + ord = cbs.__order__; - if ( "__call__" in cbs ) { - return cbs.__call__.call(this, block, next); - } + if ( "__call__" in cbs ) + return cbs.__call__.call(this, block, next); - for ( var i = 0; i < ord.length; i++ ) { - //D:this.debug( "Testing", ord[i] ); - var res = cbs[ ord[i] ].call( this, block, next ); - if ( res ) { - //D:this.debug(" matched"); - if ( !isArray(res) || ( res.length > 0 && !( isArray(res[0]) ) ) ) - this.debug(ord[i], "didn't return a proper array"); - //D:this.debug( "" ); - return res; + for ( var i = 0; i < ord.length; i++ ) { + //D:this.debug( "Testing", ord[i] ); + var res = cbs[ ord[i] ].call( this, block, next ); + if ( res ) { + //D:this.debug(" matched"); + if ( !isArray(res) || ( res.length > 0 && !( isArray(res[0]) ) && ( typeof res[0] !== "string")) ) + this.debug(ord[i], "didn't return a proper array"); + //D:this.debug( "" ); + return res; + } } - } - // Uhoh! no match! Should we throw an error? - return []; + // Uhoh! no match! Should we throw an error? + return []; }; Markdown.prototype.processInline = function processInline( block ) { @@ -551,6 +544,7 @@ Markdown.dialects.Gruber = { if ( last_li[1] instanceof Array && last_li[1][0] == "para" ) { return; } + if ( i + 1 == stack.length ) { // Last stack frame // Keep the same array, but replace the contents @@ -558,6 +552,7 @@ Markdown.dialects.Gruber = { } else { var sublist = last_li.pop(); + last_li.push( ["para"].concat( last_li.splice(1, last_li.length - 1) ), sublist ); } } @@ -671,7 +666,13 @@ Markdown.dialects.Gruber = { } // tight_search if ( li_accumulate.length ) { + add( last_li, loose, this.processInline( li_accumulate ), nl ); + + if(last_li[last_li.length-1] === "\n") { + last_li.pop(); + } + // Loose mode will have been dealt with. Reset it loose = false; li_accumulate = ""; @@ -693,6 +694,7 @@ Markdown.dialects.Gruber = { if ( next_block.match(is_list_re) || (next_block.match(/^ /) && (!next_block.match(/^ *\>/))) ) { + block = next.shift(); // Check for an HR following a list: features/lists/hr_abutting @@ -703,8 +705,10 @@ Markdown.dialects.Gruber = { break; } - // Make sure all listitems up the stack are paragraphs - forEach( stack, paragraphify, this); + // Add paragraphs if the indentation level stays the same + if (stack[stack.length-1].indent === block.match(/^\s*/)[0]) { + forEach( stack, paragraphify, this); + } loose = true; continue loose_search; @@ -712,7 +716,6 @@ Markdown.dialects.Gruber = { break; } // loose_search - return ret; }; })(), @@ -781,7 +784,7 @@ Markdown.dialects.Gruber = { referenceDefn: function referenceDefn( block, next) { - var re = /^\s*\[(.*?)\]:\s*(\S+)(?:\s+(?:(['"])(.*?)\3|\((.*?)\)))?\n?/; + var re = /^\s*\[(.*?)\]:\s*(\S+)(?:\s+(?:(['"])(.*)\3|\((.*?)\)))?\n?/; // interesting matches are [ , ref_id, url, , title, title ] if ( !block.match(re) ) @@ -864,7 +867,7 @@ Markdown.dialects.Gruber.inline = { "]": function () {}, "}": function () {}, - __escape__ : /^\\[\\`\*_{}\[\]()#\+.!\-]/, + __escape__ : /^\\[\\`\*_\<\>{}\[\]()#\+.!\-]/, "\\": function escaped( text ) { // [ length of input processed, node/children to add... ] @@ -883,7 +886,11 @@ Markdown.dialects.Gruber.inline = { //  // 1 2 3 4 <--- captures - var m = text.match( /^!\[(.*?)\][ \t]*\([ \t]*([^")]*?)(?:[ \t]+(["'])(.*?)\3)?[ \t]*\)/ ); + // + // First attempt to use a strong URL regexp to catch things like parentheses. If it misses, use the + // old one. + var m = text.match( /^!\[(.*?)][ \t]*\(((?:https?:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.])(?:[^\s()<>]+|\([^\s()<>]+\))+(?:\([^\s()<>]+\)|[^`!()\[\]{};:'".,<>?«»“”‘’\s]))\)([ \t])*(["'].*["'])?/ ) || + text.match( /^!\[(.*?)\][ \t]*\([ \t]*([^")]*?)(?:[ \t]+(["'])(.*?)\3)?[ \t]*\)/ ); if ( m ) { if ( m[2] && m[2][0] == "<" && m[2][m[2].length-1] == ">" ) @@ -938,7 +945,7 @@ Markdown.dialects.Gruber.inline = { // The parens have to be balanced var m = text.match( /^\s*\([ \t]*([^"']*)(?:[ \t]+(["'])(.*?)\2)?[ \t]*\)/ ); if ( m ) { - var url = m[1]; + var url = m[1].replace(/ +$/, ''); consumed += m[0].length; if ( url && url[0] == "<" && url[url.length-1] == ">" ) @@ -991,7 +998,7 @@ Markdown.dialects.Gruber.inline = { return [ consumed, link ]; } - m = orig.match(/^\s*\[(.*?)\]:\s*(\S+)(?:\s+(?:(['"])(.*?)\3|\((.*?)\)))?\n?/); + m = orig.match(/^\s*\[(.*?)\]:\s*(\S+)(?:\s+(?:(['"])(.*?)\3|\((.*?)\)))?\n?/m); if (m) { var attrs = create_attrs.call(this); @@ -1004,7 +1011,8 @@ Markdown.dialects.Gruber.inline = { // Only if id is plain (no formatting.) if ( children.length == 1 && typeof children[0] == "string" ) { - attrs = { ref: children[0].toLowerCase(), original: orig.substr( 0, consumed ) }; + var normalized = children[0].toLowerCase().replace(/\n/, " ").replace(/\s+/, ' '); + attrs = { ref: normalized, original: orig.substr( 0, consumed ) }; link = [ "link_ref", attrs, children[0] ]; return [ consumed, link ]; } @@ -1032,7 +1040,11 @@ Markdown.dialects.Gruber.inline = { return [ 1, "<" ]; }, - "`": function inlineCode( text ) { + "`": function inlineCode( text, match, prev ) { + + // If we're in a tag, don't do it. + if (prev && (typeof prev[0] === "string") && prev[0].match(/<[^>]+$/)) { return; } + // Inline code block. as many backticks as you like to start it // Always skip over the opening ticks. var m = text.match( /(`+)(([\s\S]*?)\1)/ ); @@ -1217,6 +1229,10 @@ function render_tree( jsonml ) { return jsonml; } + if ( jsonml[0] == "__RAW" ) { + return jsonml[1]; + } + var tag = jsonml.shift(), attributes = {}, content = []; @@ -1230,6 +1246,13 @@ function render_tree( jsonml ) { } var tag_attrs = ""; + + // MDTest has src attributes first + if (typeof attributes.src !== 'undefined') { + tag_attrs += ' src="' + escapeHTML( attributes.src ) + '"'; + delete attributes.src; + } + for ( var a in attributes ) { tag_attrs += " " + a + '="' + escapeHTML( attributes[ a ] ) + '"'; }