Comparing version 0.4.1 to 0.5.0
0.5.0 / 2015-02-17 | ||
================== | ||
* Add tab support | ||
0.4.1 / 2015-02-15 | ||
@@ -3,0 +8,0 @@ ================== |
@@ -6,3 +6,3 @@ /* This file is generated by `script/build-expressions.js` */ | ||
"bullet":/(?:[*+-]|\d+\.)/, | ||
"code":/^( {4}[^\n]+\n*)+/, | ||
"code":/^((?: {4}|\t)[^\n]+\n*)+/, | ||
"horizontalRule":/^( *[-*_]){3,} *(?=\n|$)/, | ||
@@ -13,7 +13,7 @@ "heading":/^ *((#{1,6}) *)([^\n]+?) *#* *(?=\n|$)/, | ||
"blockText":/^[^\n]+/, | ||
"item":/^( *)((?:[*+-]|\d+\.)) [^\n]*(?:\n(?!\1(?:[*+-]|\d+\.) )[^\n]*)*/gm, | ||
"list":/^( *)((?:[*+-]|\d+\.))((?: [\s\S]+?)(?:\n+(?=\1?(?:[-*_] *){3,}(?=\n|$))|\n+(?= *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?=\n|$))|\n{2,}(?! )(?!\1(?:[*+-]|\d+\.) )|\s*$))/, | ||
"blockquote":/^( *>[^\n]+(\n(?! *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?=\n|$))[^\n]+)*)+/, | ||
"html":/^ *(?:<!--[\s\S]*?--> *(?:\n|\s*$)|<((?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\b)\w+(?!:\/|[^\w\s@]*@)\b)[\s\S]+?<\/\1> *(?:\n{2,}|\s*$)|<(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\b)\w+(?!:\/|[^\w\s@]*@)\b(?:"[^"]*"|'[^']*'|[^'">])*?> *(?:\n{2,}|\s*$))/, | ||
"paragraph":/^(?:(?:[^\n]+\n?(?!( *[-*_]){3,} *(?=\n|$)| *((#{1,6}) *)([^\n]+?) *#* *(?=\n|$)|([^\n]+)\n *(=|-){2,} *(?=\n|$)|( *>[^\n]+(\n(?! *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?=\n|$))[^\n]+)*)+|<(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\b)\w+(?!:\/|[^\w\s@]*@)\b| *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?=\n|$)))+)/, | ||
"item":/^([ \t]*)((?:[*+-]|\d+\.))[ \t][^\n]*(?:\n(?!\1(?:[*+-]|\d+\.)[ \t])[^\n]*)*/gm, | ||
"list":/^([ \t]*)((?:[*+-]|\d+\.))((?:[ \t][\s\S]+?)(?:\n+(?=\1?(?:[-*_][ \t]*){3,}(?=\n|$))|\n+(?= *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?=\n|$))|\n{2,}(?![ \t])(?!\1(?:[*+-]|\d+\.)[ \t])|\s*$))/, | ||
"blockquote":/^([ \t]*>[^\n]+(\n(?! *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?=\n|$))[^\n]+)*)+/, | ||
"html":/^[ \t]*(?:<!--[\s\S]*?-->[ \t]*(?:\n|\s*$)|<((?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\b)\w+(?!:\/|[^\w\s@]*@)\b)[\s\S]+?<\/\1>[ \t]*(?:\n{2,}|\s*$)|<(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\b)\w+(?!:\/|[^\w\s@]*@)\b(?:"[^"]*"|'[^']*'|[^'">])*?>[ \t]*(?:\n{2,}|\s*$))/, | ||
"paragraph":/^(?:(?:[^\n]+\n?(?!( *[-*_]){3,} *(?=\n|$)| *((#{1,6}) *)([^\n]+?) *#* *(?=\n|$)|([^\n]+)\n *(=|-){2,} *(?=\n|$)|([ \t]*>[^\n]+(\n(?! *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?=\n|$))[^\n]+)*)+|<(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\b)\w+(?!:\/|[^\w\s@]*@)\b| *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?=\n|$)))+)/, | ||
"escape":/^\\([\\`*{}\[\]()#+\-.!_>])/, | ||
@@ -38,4 +38,4 @@ "autoLink":/^<([^ >]+(@|:\/)[^ >]+)>/, | ||
"gfm": { | ||
"fences":/^ *(`{3,}|~{3,}) *(\S+)? *\n([\s\S]*?)\s*\1 *(?=\n|$)/, | ||
"paragraph":/^(?:(?:[^\n]+\n?(?! *(`{3,}|~{3,}) *(\S+)? *\n([\s\S]*?)\s*\2 *(?=\n|$)|( *)((?:[*+-]|\d+\.))((?: [\s\S]+?)(?:\n+(?=\3?(?:[-*_] *){3,}(?=\n|$))|\n+(?= *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?=\n|$))|\n{2,}(?! )(?!\1(?:[*+-]|\d+\.) )|\s*$))|( *[-*_]){3,} *(?=\n|$)| *((#{1,6}) *)([^\n]+?) *#* *(?=\n|$)|([^\n]+)\n *(=|-){2,} *(?=\n|$)|( *>[^\n]+(\n(?! *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?=\n|$))[^\n]+)*)+|<(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\b)\w+(?!:\/|[^\w\s@]*@)\b| *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?=\n|$)))+)/, | ||
"fences":/^[ \\t]*(`{3,}|~{3,})[ \\t]*(\S+)?[ \\t]*\n([\s\S]*?)\s*\1[ \\t]*(?=\n|$)/, | ||
"paragraph":/^(?:(?:[^\n]+\n?(?![ \\t]*(`{3,}|~{3,})[ \\t]*(\S+)?[ \\t]*\n([\s\S]*?)\s*\2[ \\t]*(?=\n|$)|([ \t]*)((?:[*+-]|\d+\.))((?:[ \t][\s\S]+?)(?:\n+(?=\3?(?:[-*_][ \t]*){3,}(?=\n|$))|\n+(?= *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?=\n|$))|\n{2,}(?![ \t])(?!\1(?:[*+-]|\d+\.)[ \t])|\s*$))|( *[-*_]){3,} *(?=\n|$)| *((#{1,6}) *)([^\n]+?) *#* *(?=\n|$)|([^\n]+)\n *(=|-){2,} *(?=\n|$)|([ \t]*>[^\n]+(\n(?! *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?=\n|$))[^\n]+)*)+|<(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\b)\w+(?!:\/|[^\w\s@]*@)\b| *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?=\n|$)))+)/, | ||
"escape":/^\\([\\`*{}\[\]()#+\-.!_>~|])/, | ||
@@ -42,0 +42,0 @@ "url":/^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/, |
259
lib/parse.js
@@ -15,2 +15,3 @@ 'use strict'; | ||
var repeat = utilities.repeat; | ||
var copy = utilities.copy; | ||
@@ -35,2 +36,3 @@ var raise = utilities.raise; | ||
var SPACE = ' '; | ||
var TAB = '\t'; | ||
var EMPTY = ''; | ||
@@ -66,17 +68,23 @@ var BLOCK = 'block'; | ||
/* | ||
* Tab size. | ||
*/ | ||
var TAB_SIZE = 4; | ||
/* | ||
* Expressions. | ||
*/ | ||
var EXPRESSION_INITIAL_SPACES = /^ +/; | ||
var EXPRESSION_RIGHT_ALIGNMENT = /^ *-+: *$/; | ||
var EXPRESSION_CENTER_ALIGNMENT = /^ *:-+: *$/; | ||
var EXPRESSION_SPACES_ONLY_LINE = /^ +$/gm; | ||
var EXPRESSION_TABLE_FENCE = /^ *|\| *$/g; | ||
var EXPRESSION_TABLE_INITIAL = /^ *\| */g; | ||
var EXPRESSION_TABLE_CONTENT = /([\s\S]+?)( *\| *\n?|\n?$)/g; | ||
var EXPRESSION_TABLE_BORDER = / *\| */; | ||
var EXPRESSION_BLOCK_QUOTE = /^ *> ?/gm; | ||
var EXPRESSION_BULLET = /^ *([*+-]|\d+\.) +/; | ||
var EXPRESSION_INITIAL_INDENT = /^ {1,4}/gm; | ||
var EXPRESSION_INITIAL_TAB = /^( {4})?/gm; | ||
var EXPRESSION_RIGHT_ALIGNMENT = /^[ \t]*-+:[ \t]*$/; | ||
var EXPRESSION_CENTER_ALIGNMENT = /^[ \t]*:-+:[ \t]*$/; | ||
var EXPRESSION_SPACES_ONLY_LINE = /^[ \t]+$/gm; | ||
var EXPRESSION_TABLE_FENCE = /^[ \t]*|\|[ \t]*$/g; | ||
var EXPRESSION_TABLE_INITIAL = /^[ \t]*\|[ \t]*/g; | ||
var EXPRESSION_TABLE_CONTENT = /([\s\S]+?)([ \t]*\|[ \t]*\n?|\n?$)/g; | ||
var EXPRESSION_TABLE_BORDER = /[ \t]*\|[ \t]*/; | ||
var EXPRESSION_BLOCK_QUOTE = /^[ \t]*>[ \t]?/gm; | ||
var EXPRESSION_BULLET = /^([ \t]*)([*+-]|\d+\.)([ \t]+)([^\n]*)/; | ||
var EXPRESSION_PEDANTIC_BULLET = /^([ \t]*)([*+-]|\d+\.)([ \t]+)/; | ||
var EXPRESSION_INITIAL_INDENT = /^( {1,4}|\t)?/gm; | ||
var EXPRESSION_INITIAL_TAB = /^( {4}|\t)?/gm; | ||
var EXPRESSION_HTML_LINK_OPEN = /^<a /i; | ||
@@ -87,3 +95,46 @@ var EXPRESSION_HTML_LINK_CLOSE = /^<\/a>/i; | ||
/* | ||
* A map of characters, and their column length, | ||
* which can be used as indentation | ||
*/ | ||
var INDENTATION_CHARACTERS = {}; | ||
INDENTATION_CHARACTERS[SPACE] = SPACE.length; | ||
INDENTATION_CHARACTERS[TAB] = TAB_SIZE; | ||
/** | ||
* Gets column-size of the indentation. | ||
* | ||
* @param {string} value | ||
* @return {Object} | ||
*/ | ||
function getIndent(value) { | ||
var index = 0; | ||
var indent = 0; | ||
var character = value.charAt(index); | ||
var stops = {}; | ||
var size; | ||
while (character in INDENTATION_CHARACTERS) { | ||
size = INDENTATION_CHARACTERS[character]; | ||
indent += size; | ||
if (size > 1) { | ||
indent = Math.floor(indent / size) * size; | ||
} | ||
stops[indent] = index; | ||
character = value.charAt(++index); | ||
} | ||
return { | ||
'indent': indent, | ||
'stops': stops | ||
}; | ||
} | ||
/** | ||
* Remove the minimum indent from `value`. | ||
@@ -94,24 +145,27 @@ * | ||
*/ | ||
function removeIndent(value) { | ||
function removeIndentation(value) { | ||
var values = value.split(NEW_LINE); | ||
var index = values.length; | ||
var position = values.length; | ||
var minIndent = Infinity; | ||
var indent; | ||
var expression; | ||
var matrix = []; | ||
var index; | ||
var indentation; | ||
var stops; | ||
var padding; | ||
while (index--) { | ||
if (values[index].length === 0) { | ||
while (position--) { | ||
if (values[position].length === 0) { | ||
continue; | ||
} | ||
indent = values[index].match(EXPRESSION_INITIAL_SPACES); | ||
indentation = getIndent(values[position]); | ||
matrix[position] = indentation.stops; | ||
if (indent) { | ||
indent = indent[0].length; | ||
if (indent > 0 && indent < minIndent) { | ||
minIndent = indent; | ||
if (indentation.indent) { | ||
if (indentation.indent > 0 && indentation.indent < minIndent) { | ||
minIndent = indentation.indent; | ||
} | ||
} else { | ||
minIndent = Infinity; | ||
break; | ||
@@ -122,7 +176,21 @@ } | ||
if (minIndent !== Infinity) { | ||
expression = new RegExp('^ {1,' + minIndent + '}'); | ||
index = values.length; | ||
position = values.length; | ||
while (index--) { | ||
values[index] = values[index].replace(expression, EMPTY); | ||
while (position--) { | ||
stops = matrix[position]; | ||
index = minIndent; | ||
if (!stops) { | ||
continue; | ||
} | ||
while (index && !(index in stops)) { | ||
index--; | ||
} | ||
padding = minIndent && index !== minIndent ? TAB : EMPTY; | ||
values[position] = padding + values[position].slice( | ||
index in stops ? stops[index] + 1 : 0 | ||
); | ||
} | ||
@@ -225,3 +293,3 @@ } | ||
eat($0)(this.renderCodeBlock($0)); | ||
eat($0)(this.renderCodeBlock(removeIndentation($0))); | ||
} | ||
@@ -639,3 +707,3 @@ | ||
'lang': language || null, | ||
'value': trimRightLines(removeIndent(value || EMPTY)) | ||
'value': trimRightLines(removeIndentation(value || EMPTY)) | ||
}; | ||
@@ -660,14 +728,27 @@ } | ||
/** | ||
* Create a list-item token. | ||
* Create a list-item using lacks behaviour. | ||
* | ||
* @param {string} token | ||
* @param {Object} position | ||
* @return {Object} | ||
*/ | ||
function renderListItem(token, position) { | ||
var space = 0; | ||
var offset = this.offset; | ||
function renderPedanticListItem(token, position) { | ||
var self = this; | ||
var offset = self.offset; | ||
var line = position.line; | ||
var expression; | ||
var loose; | ||
/** | ||
* A simple replacer which removed all matches, | ||
* and adds their length to `offset`. | ||
* | ||
* @param {string} $0 | ||
* @return {string} | ||
*/ | ||
function replacer($0) { | ||
offset[line] = (offset[line] || 0) + $0.length; | ||
line++; | ||
return EMPTY; | ||
} | ||
/* | ||
@@ -677,44 +758,102 @@ * Remove the list token's bullet. | ||
token = token.replace(EXPRESSION_BULLET, function ($0) { | ||
space = $0.length; | ||
token = token.replace(EXPRESSION_PEDANTIC_BULLET, replacer); | ||
offset[line] = (offset[line] || 0) + space; | ||
/* | ||
* The initial line is also matched by the below, so | ||
* we reset the `line`. | ||
*/ | ||
/* | ||
* Make sure that the first nine numbered list items | ||
* can indent with an extra space: | ||
*/ | ||
line = position.line; | ||
space = Math.ceil(space / 2) * 2; | ||
return token.replace(EXPRESSION_INITIAL_INDENT, replacer); | ||
} | ||
return EMPTY; | ||
}); | ||
/** | ||
* Create a list-item using sane behaviour. | ||
* | ||
* @param {string} token | ||
* @param {Object} position | ||
* @return {Object} | ||
*/ | ||
function renderNormalListItem(token, position) { | ||
var self = this; | ||
var offset = self.offset; | ||
var line = position.line; | ||
var bullet; | ||
var rest; | ||
var lines; | ||
var trimmedLines; | ||
var index; | ||
var length; | ||
/* | ||
* Exdent whatever the list token contains. Hacky. | ||
* Remove the list token's bullet. | ||
*/ | ||
if (this.options.pedantic) { | ||
expression = EXPRESSION_INITIAL_INDENT; | ||
} else { | ||
expression = new RegExp('^( {0,' + space + '})', 'gm'); | ||
} | ||
token = token.replace(EXPRESSION_BULLET, function ($0, $1, $2, $3, $4) { | ||
bullet = $1 + $2 + $3; | ||
rest = $4; | ||
token = token.replace(expression, function ($0) { | ||
offset[line] = (offset[line] || 0) + $0.length; | ||
line++; | ||
/* | ||
* Make sure that the first nine numbered list items | ||
* can indent with an extra space: | ||
*/ | ||
return EMPTY; | ||
if (Number($2) < 10) { | ||
$2 = SPACE + $2; | ||
} | ||
return $1 + repeat($2.length, SPACE) + $3 + rest; | ||
}); | ||
lines = token.split(NEW_LINE); | ||
trimmedLines = removeIndentation(token).split(NEW_LINE); | ||
/* | ||
* Determine whether token is loose or not. | ||
* We replaced the initial bullet with something | ||
* else above, which was used to trick | ||
* `removeIndentation` into removing some more | ||
* characters when possible. However, that could | ||
* result in the initial line to be stripped more | ||
* than it should be. | ||
*/ | ||
loose = EXPRESSION_LOOSE_LIST_ITEM.test(token) || | ||
token.charAt(token.length - 1) === NEW_LINE; | ||
trimmedLines[0] = rest; | ||
offset[line] = (offset[line] || 0) + bullet.length; | ||
line++; | ||
index = 0; | ||
length = lines.length; | ||
while (++index < length) { | ||
offset[line] = (offset[line] || 0) + | ||
lines[index].length - trimmedLines[index].length; | ||
line++; | ||
} | ||
return trimmedLines.join(NEW_LINE); | ||
} | ||
/* | ||
* A map of two functions which can create list items. | ||
*/ | ||
var LIST_ITEM_MAP = {}; | ||
LIST_ITEM_MAP.true = renderPedanticListItem; | ||
LIST_ITEM_MAP.false = renderNormalListItem; | ||
/** | ||
* Create a list-item token. | ||
* | ||
* @return {Object} | ||
*/ | ||
function renderListItem(token, position) { | ||
token = LIST_ITEM_MAP[this.options.pedantic].apply(this, arguments); | ||
return { | ||
'type': LIST_ITEM, | ||
'loose': loose, | ||
'loose': EXPRESSION_LOOSE_LIST_ITEM.test(token) || | ||
token.charAt(token.length - 1) === NEW_LINE, | ||
'children': this.tokenizeBlock(token, position) | ||
@@ -721,0 +860,0 @@ }; |
@@ -14,2 +14,3 @@ 'use strict'; | ||
var repeat = utilities.repeat; | ||
var copy = utilities.copy; | ||
@@ -128,13 +129,2 @@ var raise = utilities.raise; | ||
/** | ||
* Repeat `character` `times` times. | ||
* | ||
* @param {number} times | ||
* @param {string} character | ||
* @return {string} | ||
*/ | ||
function repeat(times, character) { | ||
return new Array(times + 1).join(character); | ||
} | ||
/** | ||
* Get the count of the longest repeating streak | ||
@@ -141,0 +131,0 @@ * of `character` in `value`. |
@@ -17,3 +17,2 @@ 'use strict'; | ||
var EXPRESSION_LINE_BREAKS = /\r\n|\r/g; | ||
var EXPRESSION_TAB = /\t/g; | ||
var EXPRESSION_SYMBOL_FOR_NEW_LINE = /\u2424/g; | ||
@@ -164,3 +163,2 @@ var EXPRESSION_NO_BREAK_SPACE = /\u00a0/g; | ||
.replace(EXPRESSION_LINE_BREAKS, '\n') | ||
.replace(EXPRESSION_TAB, ' ') | ||
.replace(EXPRESSION_NO_BREAK_SPACE, ' ') | ||
@@ -170,3 +168,20 @@ .replace(EXPRESSION_SYMBOL_FOR_NEW_LINE, '\n'); | ||
/** | ||
* Repeat `character` `times` times. | ||
* | ||
* @param {number} times | ||
* @param {string} character | ||
* @return {string} | ||
*/ | ||
function repeat(times, character) { | ||
return new Array(times + 1).join(character); | ||
} | ||
/* | ||
* Expose `repeat`. | ||
*/ | ||
exports.repeat = repeat; | ||
/* | ||
* Expose `copy`. | ||
@@ -173,0 +188,0 @@ */ |
{ | ||
"name": "mdast", | ||
"version": "0.4.1", | ||
"version": "0.5.0", | ||
"description": "Speedy Markdown parser/stringifier for multipurpose analysis", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
109317
2866