Support for MDTest
This commit is contained in:
parent
3d647a4b41
commit
f27413219e
|
@ -125,6 +125,7 @@ Discourse.Markdown = {
|
||||||
if (Discourse.Markdown.validClasses[val]) { return val; }
|
if (Discourse.Markdown.validClasses[val]) { return val; }
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Sanitize text using the sanitizer
|
Sanitize text using the sanitizer
|
||||||
|
|
||||||
|
@ -152,10 +153,6 @@ Discourse.Markdown = {
|
||||||
text = Discourse.Dialect.cook(text, opts);
|
text = Discourse.Dialect.cook(text, opts);
|
||||||
if (!text) return "";
|
if (!text) return "";
|
||||||
|
|
||||||
if (opts.sanitize) {
|
|
||||||
text = Discourse.Markdown.sanitize(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -10,6 +10,12 @@ Discourse.Dialect.inlineBetween({
|
||||||
emitter: function(contents) { return ['strong', ['em'].concat(contents)]; }
|
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
|
// Builds a common markdown replacer
|
||||||
var replaceMarkdown = function(match, tag) {
|
var replaceMarkdown = function(match, tag) {
|
||||||
Discourse.Dialect.inlineBetween({
|
Discourse.Dialect.inlineBetween({
|
||||||
|
|
|
@ -31,19 +31,31 @@ function initializeDialects() {
|
||||||
@returns {Array} the parsed tree
|
@returns {Array} the parsed tree
|
||||||
**/
|
**/
|
||||||
function parseTree(tree, path, insideCounts) {
|
function parseTree(tree, path, insideCounts) {
|
||||||
|
|
||||||
if (tree instanceof Array) {
|
if (tree instanceof Array) {
|
||||||
Discourse.Dialect.trigger('parseNode', {node: tree, path: path, dialect: dialect, insideCounts: insideCounts || {}});
|
Discourse.Dialect.trigger('parseNode', {node: tree, path: path, dialect: dialect, insideCounts: insideCounts || {}});
|
||||||
|
|
||||||
|
|
||||||
path = path || [];
|
path = path || [];
|
||||||
insideCounts = insideCounts || {};
|
insideCounts = insideCounts || {};
|
||||||
|
|
||||||
path.push(tree);
|
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;
|
insideCounts[tagName] = (insideCounts[tagName] || 0) + 1;
|
||||||
|
|
||||||
|
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);
|
parseTree(n, path, insideCounts);
|
||||||
|
}
|
||||||
|
|
||||||
insideCounts[tagName] = insideCounts[tagName] - 1;
|
insideCounts[tagName] = insideCounts[tagName] - 1;
|
||||||
});
|
}
|
||||||
path.pop();
|
path.pop();
|
||||||
}
|
}
|
||||||
return tree;
|
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
|
Replaces a block of text between a start and stop. As opposed to inline, these
|
||||||
might span multiple lines.
|
might span multiple lines.
|
||||||
|
@ -233,9 +258,11 @@ Discourse.Dialect = {
|
||||||
|
|
||||||
**/
|
**/
|
||||||
replaceBlock: function(args) {
|
replaceBlock: function(args) {
|
||||||
dialect.block[args.start.toString()] = function(block, next) {
|
this.registerBlock(args.start.toString(), function(block, next) {
|
||||||
|
|
||||||
args.start.lastIndex = 0;
|
args.start.lastIndex = 0;
|
||||||
var m = (args.start).exec(block);
|
var m = (args.start).exec(block);
|
||||||
|
|
||||||
if (!m) { return; }
|
if (!m) { return; }
|
||||||
|
|
||||||
var startPos = block.indexOf(m[0]),
|
var startPos = block.indexOf(m[0]),
|
||||||
|
@ -261,16 +288,33 @@ Discourse.Dialect = {
|
||||||
}
|
}
|
||||||
|
|
||||||
lineNumber++;
|
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) {
|
while (next.length > 0) {
|
||||||
var b = next.shift(),
|
var b = next.shift(),
|
||||||
blockLine = b.lineNumber,
|
blockLine = b.lineNumber,
|
||||||
diff = ((typeof blockLine === "undefined") ? lineNumber : blockLine) - lineNumber;
|
diff = ((typeof blockLine === "undefined") ? lineNumber : blockLine) - lineNumber,
|
||||||
|
endFound = b.indexOf(args.stop),
|
||||||
var endFound = b.indexOf(args.stop),
|
|
||||||
leadingContents = b.slice(0, endFound),
|
leadingContents = b.slice(0, endFound),
|
||||||
trailingContents = b.slice(endFound+args.stop.length);
|
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("");
|
blockContents.push("");
|
||||||
}
|
}
|
||||||
lineNumber = blockLine + b.split("\n").length - 1;
|
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;
|
return result;
|
||||||
};
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -318,11 +367,21 @@ Discourse.Dialect = {
|
||||||
postProcessText: function(emitter) {
|
postProcessText: function(emitter) {
|
||||||
Discourse.Dialect.on("parseNode", function(event) {
|
Discourse.Dialect.on("parseNode", function(event) {
|
||||||
var node = event.node;
|
var node = event.node;
|
||||||
|
|
||||||
if (node.length < 2) { return; }
|
if (node.length < 2) { return; }
|
||||||
|
|
||||||
|
if (node[0] === '__RAW') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (var j=1; j<node.length; j++) {
|
for (var j=1; j<node.length; j++) {
|
||||||
var textContent = node[j];
|
var textContent = node[j];
|
||||||
if (typeof textContent === "string") {
|
if (typeof textContent === "string") {
|
||||||
|
|
||||||
|
if (dialect.options.sanitize) {
|
||||||
|
textContent = Discourse.Markdown.sanitize(textContent);
|
||||||
|
}
|
||||||
|
|
||||||
var result = emitter(textContent, event);
|
var result = emitter(textContent, event);
|
||||||
if (result) {
|
if (result) {
|
||||||
if (result instanceof Array) {
|
if (result instanceof Array) {
|
||||||
|
@ -330,7 +389,8 @@ Discourse.Dialect = {
|
||||||
} else {
|
} else {
|
||||||
node[j] = result;
|
node[j] = result;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
node[j] = textContent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,14 +16,6 @@ Discourse.Dialect.replaceBlock({
|
||||||
// Ensure that content in a code block is fully escaped. This way it's not white listed
|
// 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.
|
// and we can use HTML and Javascript examples.
|
||||||
Discourse.Dialect.postProcessTag('code', function (contents) {
|
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"
|
|
||||||
);
|
|
||||||
|
|
|
@ -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() ];
|
||||||
|
}
|
||||||
|
});
|
|
@ -20,4 +20,3 @@ Discourse.Dialect.inlineRegexp({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Discourse.Markdown.whiteListClass('mention');
|
|
|
@ -77,4 +77,3 @@ Discourse.Dialect.on("parseNode", function(event) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Discourse.Markdown.whiteListClass("onebox", "onebox-result", "onebox-result-body", "source", "clearfix", "thumbnail", "info");
|
|
|
@ -44,7 +44,7 @@ Discourse.Dialect.replaceBlock({
|
||||||
return ['p', ['aside', params,
|
return ['p', ['aside', params,
|
||||||
['div', {'class': 'title'},
|
['div', {'class': 'title'},
|
||||||
['div', {'class': 'quote-controls'}],
|
['div', {'class': 'quote-controls'}],
|
||||||
avatarImg ? avatarImg : "",
|
avatarImg ? ['__RAW', avatarImg] : "",
|
||||||
I18n.t('user.said', {username: username})
|
I18n.t('user.said', {username: username})
|
||||||
],
|
],
|
||||||
contents
|
contents
|
||||||
|
@ -69,4 +69,3 @@ Discourse.Dialect.on("parseNode", function(event) {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Discourse.Markdown.whiteListClass("quote", "title", "quote-controls", "avatar");
|
|
|
@ -5,47 +5,6 @@ require_dependency 'post'
|
||||||
|
|
||||||
module PrettyText
|
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
|
class Helpers
|
||||||
|
|
||||||
def t(key, opts)
|
def t(key, opts)
|
||||||
|
@ -226,7 +185,7 @@ module PrettyText
|
||||||
cloned = opts.dup
|
cloned = opts.dup
|
||||||
# we have a minor inconsistency
|
# we have a minor inconsistency
|
||||||
cloned[:topicId] = opts[:topic_id]
|
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
|
if SiteSetting.add_rel_nofollow_to_user_content
|
||||||
sanitized = add_rel_nofollow_to_user_content(sanitized)
|
sanitized = add_rel_nofollow_to_user_content(sanitized)
|
||||||
end
|
end
|
||||||
|
|
|
@ -32,7 +32,7 @@ describe PrettyText do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should sanitize the html" do
|
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
|
end
|
||||||
|
|
||||||
it 'should allow for @mentions to have punctuation' do
|
it 'should allow for @mentions to have punctuation' do
|
||||||
|
|
|
@ -184,7 +184,7 @@ describe PostAnalyzer do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "ignores code" do
|
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']
|
post_analyzer.raw_mentions.should == ['jake']
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -376,7 +376,7 @@ describe Post do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "ignores code" do
|
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']
|
post.raw_mentions.should == ['jake']
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,11 @@ test('basic bbcode', function() {
|
||||||
"allows embedding of tags");
|
"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() {
|
test('lists', function() {
|
||||||
format("[ul][li]option one[/li][/ul]", "<ul><li>option one</li></ul>", "creates an ul");
|
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");
|
format("[ol][li]option one[/li][/ol]", "<ol><li>option one</li></ol>", "creates an ol");
|
||||||
|
|
|
@ -8,6 +8,12 @@ module("Discourse.Markdown", {
|
||||||
|
|
||||||
var cooked = function(input, expected, text) {
|
var cooked = function(input, expected, text) {
|
||||||
var result = Discourse.Markdown.cook(input, {mentionLookup: false, sanitize: true});
|
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);
|
equal(result, expected, text);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -31,7 +37,7 @@ test("basic cooking", function() {
|
||||||
|
|
||||||
test("Traditional Line Breaks", function() {
|
test("Traditional Line Breaks", function() {
|
||||||
var input = "1\n2\n3";
|
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>";
|
var traditionalOutput = "<p>1\n2\n3</p>";
|
||||||
|
|
||||||
|
@ -46,7 +52,7 @@ test("Traditional Line Breaks", function() {
|
||||||
|
|
||||||
test("Line Breaks", function() {
|
test("Line Breaks", function() {
|
||||||
cooked("[] first choice\n[] second choice",
|
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");
|
"it handles new lines correctly with [] options");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -89,10 +95,10 @@ test("Links", function() {
|
||||||
"autolinks a URL with parentheses (like Wikipedia)");
|
"autolinks a URL with parentheses (like Wikipedia)");
|
||||||
|
|
||||||
cooked("Here's a tweet:\nhttps://twitter.com/evil_trout/status/345954894420787200",
|
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.");
|
"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>",
|
"<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.");
|
"allows autolinking within a list without inserting a paragraph.");
|
||||||
|
|
||||||
|
@ -105,7 +111,7 @@ test("Links", function() {
|
||||||
'allows multiple links on one line');
|
'allows multiple links on one line');
|
||||||
|
|
||||||
cooked("* [Evil Trout][1]\n [1]: http://eviltrout.com",
|
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");
|
"allows markdown link references in a list");
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -121,9 +127,9 @@ test("simple quotes", function() {
|
||||||
"it allows nesting of blockquotes with spaces");
|
"it allows nesting of blockquotes with spaces");
|
||||||
|
|
||||||
cooked("- hello\n\n > world\n > eviltrout",
|
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.");
|
"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");
|
"works with multiple lines");
|
||||||
|
|
||||||
cookedOptions("1[quote=\"bob, post:1\"]my quote[/quote]2",
|
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" +
|
"<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>",
|
"bob said:</div><blockquote><p>my quote</p></blockquote></aside></p>\n\n<p>2</p>",
|
||||||
"handles quotes properly");
|
"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("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("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("@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`",
|
cooked("`evil` @EvilTrout `trout`",
|
||||||
"<p><code>evil</code> <span class=\"mention\">@EvilTrout</span> <code>trout</code></p>",
|
"<p><code>evil</code> <span class=\"mention\">@EvilTrout</span> <code>trout</code></p>",
|
||||||
"deals correctly with multiple <code> blocks");
|
"deals correctly with multiple <code> blocks");
|
||||||
|
@ -171,7 +177,7 @@ test("Mentions", function() {
|
||||||
"handles mentions in simple quotes");
|
"handles mentions in simple quotes");
|
||||||
|
|
||||||
cooked("> foo bar baz @eviltrout ohmagerd\nlook at this",
|
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");
|
"does mentions properly with trailing text within a simple quote");
|
||||||
|
|
||||||
cooked("`code` is okay before @mention",
|
cooked("`code` is okay before @mention",
|
||||||
|
@ -224,7 +230,7 @@ test("Oneboxing", function() {
|
||||||
|
|
||||||
cooked("http://en.wikipedia.org/wiki/Homicide:_Life_on_the_Street",
|
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\"" +
|
"<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");
|
"works with links that have underscores in them");
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -248,7 +254,7 @@ test("Code Blocks", function() {
|
||||||
"it maintains new lines inside a code block.");
|
"it maintains new lines inside a code block.");
|
||||||
|
|
||||||
cooked("hello\nworld\n```json\nline 1\n\nline 2\n\n\nline3\n```",
|
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.");
|
"it maintains new lines inside a code block with leading content.");
|
||||||
|
|
||||||
cooked("```text\n<header>hello</header>\n```",
|
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("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>",
|
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");
|
"we can embed proper links");
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -295,7 +301,7 @@ test("sanitize", function() {
|
||||||
test("URLs in BBCode tags", function() {
|
test("URLs in BBCode tags", function() {
|
||||||
|
|
||||||
cooked("[img]http://eviltrout.com/eviltrout.png[/img][img]http://samsaffron.com/samsaffron.png[/img]",
|
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");
|
"images are properly parsed");
|
||||||
|
|
||||||
cooked("[url]http://discourse.org[/url]",
|
cooked("[url]http://discourse.org[/url]",
|
||||||
|
|
|
@ -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"
|
|
@ -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>
|
|
@ -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/>
|
|
@ -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>
|
|
@ -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>.
|
|
@ -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>
|
|
@ -0,0 +1,11 @@
|
||||||
|
> Example:
|
||||||
|
>
|
||||||
|
> sub status {
|
||||||
|
> print "working";
|
||||||
|
> }
|
||||||
|
>
|
||||||
|
> Or:
|
||||||
|
>
|
||||||
|
> sub status {
|
||||||
|
> return "working";
|
||||||
|
> }
|
|
@ -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>
|
|
@ -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
|
|
@ -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>
|
|
@ -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.
|
|
@ -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>
|
|
@ -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.
|
|
@ -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>
|
|
@ -0,0 +1,67 @@
|
||||||
|
Dashes:
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
- - -
|
||||||
|
|
||||||
|
- - -
|
||||||
|
|
||||||
|
- - -
|
||||||
|
|
||||||
|
- - -
|
||||||
|
|
||||||
|
- - -
|
||||||
|
|
||||||
|
|
||||||
|
Asterisks:
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
|
|
||||||
|
Underscores:
|
||||||
|
|
||||||
|
___
|
||||||
|
|
||||||
|
___
|
||||||
|
|
||||||
|
___
|
||||||
|
|
||||||
|
___
|
||||||
|
|
||||||
|
___
|
||||||
|
|
||||||
|
_ _ _
|
||||||
|
|
||||||
|
_ _ _
|
||||||
|
|
||||||
|
_ _ _
|
||||||
|
|
||||||
|
_ _ _
|
||||||
|
|
||||||
|
_ _ _
|
|
@ -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>
|
|
@ -0,0 +1,26 @@
|
||||||
|
![Alt text](/path/to/img.jpg)
|
||||||
|
|
||||||
|
![Alt text](/path/to/img.jpg "Optional title")
|
||||||
|
|
||||||
|
Inline within a paragraph: [alt text](/url/).
|
||||||
|
|
||||||
|
![alt text](/url/ "title preceded by two spaces")
|
||||||
|
|
||||||
|
![alt text](/url/ "title has spaces afterward" )
|
||||||
|
|
||||||
|
![alt text](</url/>)
|
||||||
|
|
||||||
|
![alt text](</url/> "with a title").
|
||||||
|
|
||||||
|
![Empty]()
|
||||||
|
|
||||||
|
![this is a stupid URL](http://example.com/(parens).jpg)
|
||||||
|
|
||||||
|
|
||||||
|
![alt text][foo]
|
||||||
|
|
||||||
|
[foo]: /url/
|
||||||
|
|
||||||
|
![alt text][bar]
|
||||||
|
|
||||||
|
[bar]: /url/ "Title here"
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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">
|
|
@ -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>
|
|
@ -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.
|
|
@ -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>
|
|
@ -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"))
|
|
@ -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>
|
|
@ -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/
|
|
@ -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>
|
|
@ -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
|
|
@ -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>
|
|
@ -0,0 +1,7 @@
|
||||||
|
Foo [bar][].
|
||||||
|
|
||||||
|
Foo [bar](/url/ "Title with "quotes" inside").
|
||||||
|
|
||||||
|
|
||||||
|
[bar]: /url/ "Title with "quotes" inside"
|
||||||
|
|
|
@ -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>
|
|
@ -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):
|
||||||
|
|
||||||
|
![alt text](/path/to/img.jpg "Title")
|
||||||
|
|
||||||
|
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>
|
|
@ -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>![alt text](/path/to/img.jpg "Title")
|
||||||
|
</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>
|
|
@ -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:
|
||||||
|
|
||||||
|
![Alt text](/path/to/img.jpg)
|
||||||
|
|
||||||
|
![Alt text](/path/to/img.jpg "Optional title")
|
||||||
|
|
||||||
|
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
|
||||||
|
|
|
@ -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>![Alt text](/path/to/img.jpg)
|
||||||
|
|
||||||
|
![Alt text](/path/to/img.jpg "Optional title")
|
||||||
|
</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>
|
|
@ -0,0 +1,5 @@
|
||||||
|
> foo
|
||||||
|
>
|
||||||
|
> > bar
|
||||||
|
>
|
||||||
|
> foo
|
|
@ -0,0 +1,9 @@
|
||||||
|
<blockquote>
|
||||||
|
<p>foo</p>
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
|
<p>bar</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
<p>foo</p>
|
||||||
|
</blockquote>
|
|
@ -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
|
|
@ -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>
|
|
@ -0,0 +1,7 @@
|
||||||
|
***This is strong and em.***
|
||||||
|
|
||||||
|
So is ***this*** word.
|
||||||
|
|
||||||
|
___This is strong and em.___
|
||||||
|
|
||||||
|
So is ___this___ word.
|
|
@ -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>
|
|
@ -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
|
|
@ -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>
|
|
@ -0,0 +1,5 @@
|
||||||
|
> A list within a blockquote:
|
||||||
|
>
|
||||||
|
> * asterisk 1
|
||||||
|
> * asterisk 2
|
||||||
|
> * asterisk 3
|
|
@ -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>
|
|
@ -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 %>
|
|
@ -4,16 +4,10 @@
|
||||||
* We have replaced the strong/em handlers because we prefer them only to work on word
|
* We have replaced the strong/em handlers because we prefer them only to work on word
|
||||||
boundaries.
|
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.
|
// __RAW__
|
||||||
|
|
||||||
* 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!
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -263,16 +257,15 @@ Markdown.prototype.processBlock = function processBlock( block, next ) {
|
||||||
var cbs = this.dialect.block,
|
var cbs = this.dialect.block,
|
||||||
ord = cbs.__order__;
|
ord = cbs.__order__;
|
||||||
|
|
||||||
if ( "__call__" in cbs ) {
|
if ( "__call__" in cbs )
|
||||||
return cbs.__call__.call(this, block, next);
|
return cbs.__call__.call(this, block, next);
|
||||||
}
|
|
||||||
|
|
||||||
for ( var i = 0; i < ord.length; i++ ) {
|
for ( var i = 0; i < ord.length; i++ ) {
|
||||||
//D:this.debug( "Testing", ord[i] );
|
//D:this.debug( "Testing", ord[i] );
|
||||||
var res = cbs[ ord[i] ].call( this, block, next );
|
var res = cbs[ ord[i] ].call( this, block, next );
|
||||||
if ( res ) {
|
if ( res ) {
|
||||||
//D:this.debug(" matched");
|
//D:this.debug(" matched");
|
||||||
if ( !isArray(res) || ( res.length > 0 && !( isArray(res[0]) ) ) )
|
if ( !isArray(res) || ( res.length > 0 && !( isArray(res[0]) ) && ( typeof res[0] !== "string")) )
|
||||||
this.debug(ord[i], "didn't return a proper array");
|
this.debug(ord[i], "didn't return a proper array");
|
||||||
//D:this.debug( "" );
|
//D:this.debug( "" );
|
||||||
return res;
|
return res;
|
||||||
|
@ -551,6 +544,7 @@ Markdown.dialects.Gruber = {
|
||||||
if ( last_li[1] instanceof Array && last_li[1][0] == "para" ) {
|
if ( last_li[1] instanceof Array && last_li[1][0] == "para" ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( i + 1 == stack.length ) {
|
if ( i + 1 == stack.length ) {
|
||||||
// Last stack frame
|
// Last stack frame
|
||||||
// Keep the same array, but replace the contents
|
// Keep the same array, but replace the contents
|
||||||
|
@ -558,6 +552,7 @@ Markdown.dialects.Gruber = {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var sublist = last_li.pop();
|
var sublist = last_li.pop();
|
||||||
|
|
||||||
last_li.push( ["para"].concat( last_li.splice(1, last_li.length - 1) ), sublist );
|
last_li.push( ["para"].concat( last_li.splice(1, last_li.length - 1) ), sublist );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -671,7 +666,13 @@ Markdown.dialects.Gruber = {
|
||||||
} // tight_search
|
} // tight_search
|
||||||
|
|
||||||
if ( li_accumulate.length ) {
|
if ( li_accumulate.length ) {
|
||||||
|
|
||||||
add( last_li, loose, this.processInline( li_accumulate ), nl );
|
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 mode will have been dealt with. Reset it
|
||||||
loose = false;
|
loose = false;
|
||||||
li_accumulate = "";
|
li_accumulate = "";
|
||||||
|
@ -693,6 +694,7 @@ Markdown.dialects.Gruber = {
|
||||||
|
|
||||||
|
|
||||||
if ( next_block.match(is_list_re) || (next_block.match(/^ /) && (!next_block.match(/^ *\>/))) ) {
|
if ( next_block.match(is_list_re) || (next_block.match(/^ /) && (!next_block.match(/^ *\>/))) ) {
|
||||||
|
|
||||||
block = next.shift();
|
block = next.shift();
|
||||||
|
|
||||||
// Check for an HR following a list: features/lists/hr_abutting
|
// Check for an HR following a list: features/lists/hr_abutting
|
||||||
|
@ -703,8 +705,10 @@ Markdown.dialects.Gruber = {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure all listitems up the stack are paragraphs
|
// Add paragraphs if the indentation level stays the same
|
||||||
|
if (stack[stack.length-1].indent === block.match(/^\s*/)[0]) {
|
||||||
forEach( stack, paragraphify, this);
|
forEach( stack, paragraphify, this);
|
||||||
|
}
|
||||||
|
|
||||||
loose = true;
|
loose = true;
|
||||||
continue loose_search;
|
continue loose_search;
|
||||||
|
@ -712,7 +716,6 @@ Markdown.dialects.Gruber = {
|
||||||
break;
|
break;
|
||||||
} // loose_search
|
} // loose_search
|
||||||
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
})(),
|
})(),
|
||||||
|
@ -781,7 +784,7 @@ Markdown.dialects.Gruber = {
|
||||||
|
|
||||||
referenceDefn: function referenceDefn( block, next) {
|
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 ]
|
// interesting matches are [ , ref_id, url, , title, title ]
|
||||||
|
|
||||||
if ( !block.match(re) )
|
if ( !block.match(re) )
|
||||||
|
@ -864,7 +867,7 @@ Markdown.dialects.Gruber.inline = {
|
||||||
"]": function () {},
|
"]": function () {},
|
||||||
"}": function () {},
|
"}": function () {},
|
||||||
|
|
||||||
__escape__ : /^\\[\\`\*_{}\[\]()#\+.!\-]/,
|
__escape__ : /^\\[\\`\*_\<\>{}\[\]()#\+.!\-]/,
|
||||||
|
|
||||||
"\\": function escaped( text ) {
|
"\\": function escaped( text ) {
|
||||||
// [ length of input processed, node/children to add... ]
|
// [ length of input processed, node/children to add... ]
|
||||||
|
@ -883,7 +886,11 @@ Markdown.dialects.Gruber.inline = {
|
||||||
|
|
||||||
// ![Alt text](/path/to/img.jpg "Optional title")
|
// ![Alt text](/path/to/img.jpg "Optional title")
|
||||||
// 1 2 3 4 <--- captures
|
// 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 ) {
|
||||||
if ( m[2] && m[2][0] == "<" && m[2][m[2].length-1] == ">" )
|
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
|
// The parens have to be balanced
|
||||||
var m = text.match( /^\s*\([ \t]*([^"']*)(?:[ \t]+(["'])(.*?)\2)?[ \t]*\)/ );
|
var m = text.match( /^\s*\([ \t]*([^"']*)(?:[ \t]+(["'])(.*?)\2)?[ \t]*\)/ );
|
||||||
if ( m ) {
|
if ( m ) {
|
||||||
var url = m[1];
|
var url = m[1].replace(/ +$/, '');
|
||||||
consumed += m[0].length;
|
consumed += m[0].length;
|
||||||
|
|
||||||
if ( url && url[0] == "<" && url[url.length-1] == ">" )
|
if ( url && url[0] == "<" && url[url.length-1] == ">" )
|
||||||
|
@ -991,7 +998,7 @@ Markdown.dialects.Gruber.inline = {
|
||||||
return [ consumed, link ];
|
return [ consumed, link ];
|
||||||
}
|
}
|
||||||
|
|
||||||
m = orig.match(/^\s*\[(.*?)\]:\s*(\S+)(?:\s+(?:(['"])(.*?)\3|\((.*?)\)))?\n?/);
|
m = orig.match(/^\s*\[(.*?)\]:\s*(\S+)(?:\s+(?:(['"])(.*?)\3|\((.*?)\)))?\n?/m);
|
||||||
if (m) {
|
if (m) {
|
||||||
|
|
||||||
var attrs = create_attrs.call(this);
|
var attrs = create_attrs.call(this);
|
||||||
|
@ -1004,7 +1011,8 @@ Markdown.dialects.Gruber.inline = {
|
||||||
// Only if id is plain (no formatting.)
|
// Only if id is plain (no formatting.)
|
||||||
if ( children.length == 1 && typeof children[0] == "string" ) {
|
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] ];
|
link = [ "link_ref", attrs, children[0] ];
|
||||||
return [ consumed, link ];
|
return [ consumed, link ];
|
||||||
}
|
}
|
||||||
|
@ -1032,7 +1040,11 @@ Markdown.dialects.Gruber.inline = {
|
||||||
return [ 1, "<" ];
|
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
|
// Inline code block. as many backticks as you like to start it
|
||||||
// Always skip over the opening ticks.
|
// Always skip over the opening ticks.
|
||||||
var m = text.match( /(`+)(([\s\S]*?)\1)/ );
|
var m = text.match( /(`+)(([\s\S]*?)\1)/ );
|
||||||
|
@ -1217,6 +1229,10 @@ function render_tree( jsonml ) {
|
||||||
return jsonml;
|
return jsonml;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( jsonml[0] == "__RAW" ) {
|
||||||
|
return jsonml[1];
|
||||||
|
}
|
||||||
|
|
||||||
var tag = jsonml.shift(),
|
var tag = jsonml.shift(),
|
||||||
attributes = {},
|
attributes = {},
|
||||||
content = [];
|
content = [];
|
||||||
|
@ -1230,6 +1246,13 @@ function render_tree( jsonml ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var tag_attrs = "";
|
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 ) {
|
for ( var a in attributes ) {
|
||||||
tag_attrs += " " + a + '="' + escapeHTML( attributes[ a ] ) + '"';
|
tag_attrs += " " + a + '="' + escapeHTML( attributes[ a ] ) + '"';
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue