diff --git a/app/assets/javascripts/external/better_markdown.js b/app/assets/javascripts/external/better_markdown.js index 29e708fb8..dd46e8782 100644 --- a/app/assets/javascripts/external/better_markdown.js +++ b/app/assets/javascripts/external/better_markdown.js @@ -8,6 +8,8 @@ * We don't escape the contents of HTML as we prefer to use a whitelist. + * We fixed a bug where references can be created directly following a list. + * Note the name BetterMarkdown doesn't mean it's *better* than markdown-js, it refers to it being better than our previous markdown parser! @@ -205,6 +207,35 @@ Markdown.prototype.split_blocks = function splitBlocks( input, startLine ) { return blocks; }; +function create_attrs() { + if ( !extract_attr( this.tree ) ) { + this.tree.splice( 1, 0, {} ); + } + + var attrs = extract_attr( this.tree ); + + // make a references hash if it doesn't exist + if ( attrs.references === undefined ) { + attrs.references = {}; + } + + return attrs; +} + +function create_reference(attrs, m) { + if ( m[2] && m[2][0] == "<" && m[2][m[2].length-1] == ">" ) + m[2] = m[2].substring( 1, m[2].length - 1 ); + + var ref = attrs.references[ m[1].toLowerCase() ] = { + href: m[2] + }; + + if ( m[4] !== undefined ) + ref.title = m[4]; + else if ( m[5] !== undefined ) + ref.title = m[5]; +} + /** * Markdown#processBlock( block, next ) -> undefined | [ JsonML, ... ] * - block (String): the block to process @@ -531,6 +562,7 @@ Markdown.dialects.Gruber = { // The matcher function return function( block, next ) { + var m = block.match( is_list_re ); if ( !m ) return undefined; @@ -682,6 +714,7 @@ Markdown.dialects.Gruber = { })(), blockquote: function blockquote( block, next ) { + if ( !block.match( /^>/m ) ) return undefined; @@ -736,39 +769,18 @@ Markdown.dialects.Gruber = { }, referenceDefn: function referenceDefn( block, next) { + var re = /^\s*\[(.*?)\]:\s*(\S+)(?:\s+(?:(['"])(.*?)\3|\((.*?)\)))?\n?/; // interesting matches are [ , ref_id, url, , title, title ] if ( !block.match(re) ) return undefined; - // make an attribute node if it doesn't exist - if ( !extract_attr( this.tree ) ) { - this.tree.splice( 1, 0, {} ); - } - - var attrs = extract_attr( this.tree ); - - // make a references hash if it doesn't exist - if ( attrs.references === undefined ) { - attrs.references = {}; - } + var attrs = create_attrs.call(this); var b = this.loop_re_over_block(re, block, function( m ) { - - if ( m[2] && m[2][0] == "<" && m[2][m[2].length-1] == ">" ) - m[2] = m[2].substring( 1, m[2].length - 1 ); - - var ref = attrs.references[ m[1].toLowerCase() ] = { - href: m[2] - }; - - if ( m[4] !== undefined ) - ref.title = m[4]; - else if ( m[5] !== undefined ) - ref.title = m[5]; - - } ); + create_reference(attrs, m); + }); if ( b.length ) next.unshift( mk_block( b, block.trailing ) ); @@ -891,6 +903,7 @@ Markdown.dialects.Gruber.inline = { "[": function link( text ) { var orig = String(text); + // Inline content is possible inside `link text` var res = Markdown.DialectHelpers.inline_until_char.call( this, text.substr(1), "]" ); @@ -954,7 +967,6 @@ Markdown.dialects.Gruber.inline = { m = text.match( /^\s*\[(.*?)\]/ ); if ( m ) { - consumed += m[ 0 ].length; // [links][] uses links as its reference @@ -968,6 +980,15 @@ Markdown.dialects.Gruber.inline = { return [ consumed, link ]; } + m = orig.match(/^\s*\[(.*?)\]:\s*(\S+)(?:\s+(?:(['"])(.*?)\3|\((.*?)\)))?\n?/); + if (m) { + + var attrs = create_attrs.call(this); + create_reference(attrs, m); + + return [ m[0].length ] + } + // [id] // Only if id is plain (no formatting.) if ( children.length == 1 && typeof children[0] == "string" ) { diff --git a/test/javascripts/components/markdown_test.js b/test/javascripts/components/markdown_test.js index 3450e457e..b4a22bf1b 100644 --- a/test/javascripts/components/markdown_test.js +++ b/test/javascripts/components/markdown_test.js @@ -103,6 +103,10 @@ test("Links", function() { "http://www.imdb.com/name/nm2225369

", 'allows multiple links on one line'); + cooked("* [Evil Trout][1]\n [1]: http://eviltrout.com", + "", + "allows markdown link references in a list"); + }); test("Quotes", function() {