Browse Source

Add strikeout (del) tag

+ trivial emphasis bugfix
pull/14/head
Alex Kocharin 10 years ago
parent
commit
9942fd5b4b
  1. 3
      lib/parser_inline.js
  2. 8
      lib/renderer.js
  3. 105
      lib/rules_inline/del.js
  4. 6
      lib/rules_inline/emphasis.js

3
lib/parser_inline.js

@ -17,6 +17,7 @@ rules.push(require('./rules_inline/text'));
rules.push(require('./rules_inline/newline'));
rules.push(require('./rules_inline/escape'));
rules.push(require('./rules_inline/backticks'));
rules.push(require('./rules_inline/del'));
rules.push(require('./rules_inline/emphasis'));
rules.push(require('./rules_inline/links'));
rules.push(require('./rules_inline/autolink'));
@ -33,7 +34,7 @@ function ParserInline() {
// Rule to skip pure text
// - '{$%@}' reserved for extentions
// - '<>"' added for internal html escaping
this.textMatch = /^[^\n\\`*_\[\]!&{}$%@<>"]+/;
this.textMatch = /^[^\n\\`*_\[\]!&{}$%@<>"~]+/;
this.ruler = new Ruler(this.rulesUpdate.bind(this));

8
lib/renderer.js

@ -180,6 +180,14 @@ rules.em_close = function(/*tokens, idx, options*/) {
};
rules.del_open = function(/*tokens, idx, options*/) {
return '<del>';
};
rules.del_close = function(/*tokens, idx, options*/) {
return '</del>';
};
rules.hardbreak = function (tokens, idx, options) {
return options.xhtml ? '<br />\n' : '<br>\n';
};

105
lib/rules_inline/del.js

@ -0,0 +1,105 @@
// Process ~~strikeout~~
'use strict';
module.exports = function del(state) {
var oldLength,
oldPending,
oldFlag,
found,
ok,
pos,
stack,
max = state.posMax,
start = state.pos,
lastChar,
nextChar;
if (state.src.charCodeAt(start) !== 0x7E/* ~ */) { return false; }
if (start + 4 >= max) { return false; }
if (state.src.charCodeAt(start + 1) !== 0x7E/* ~ */) { return false; }
// make del lower a priority tag with respect to links, same as <em>;
// this code also prevents recursion
if (state.validateInsideEm || state.validateInsideLink) { return false; }
if (state.level >= state.options.level) { return false; }
lastChar = state.pending.length !== 0 ? state.pending.charCodeAt(state.pending.length - 1) : -1;
nextChar = state.src.charCodeAt(start + 2);
if (lastChar === 0x7E/* ~ */) { return false; }
if (nextChar === 0x7E/* */) { return false; }
if (nextChar === 0x20/* */) { return false; }
pos = start + 2;
while (pos < max && state.src.charCodeAt(pos) === 0x7E/* ~ */) { pos++; }
if (pos !== start + 2) {
// sequence of 3+ markers taking as literal, same as in a emphasis
state.pos += pos - start;
state.pending += state.src.slice(start, pos);
return true;
}
oldLength = state.tokens.length;
oldPending = state.pending;
oldFlag = state.validateInsideEm;
state.pos = start + 2;
state.validateInsideEm = true;
stack = 1;
while (state.pos + 1 < max) {
if (state.src.charCodeAt(state.pos) === 0x7E/* ~ */) {
if (state.src.charCodeAt(state.pos + 1) === 0x7E/* ~ */) {
lastChar = state.pending.length !== 0 ? state.pending.charCodeAt(state.pending.length - 1) : -1;
nextChar = state.pos + 2 < max ? state.src.charCodeAt(state.pos + 2) : -1;
if (nextChar !== 0x7E/* ~ */ && lastChar !== 0x7E/* ~ */) {
if (lastChar !== 0x20) {
// closing '~~'
stack--;
} else if (nextChar !== 0x20) {
// opening '~~'
stack++;
} // else {
// // standalone ' ~~ ' indented with spaces
//}
if (stack <= 0) {
found = true;
break;
}
}
}
}
ok = state.parser.tokenizeSingle(state);
if (!ok) {
state.pending += state.src[state.pos];
state.pos++;
}
}
// restore old state
state.tokens.length = oldLength;
state.pending = oldPending;
state.validateInsideEm = oldFlag;
if (!found) {
// parser failed to find ending tag, so it's not valid emphasis
state.pos = start;
return false;
}
// found!
state.posMax = state.pos;
state.pos = start + 2;
state.push({ type: 'del_open', level: state.level++ });
state.parser.tokenize(state);
state.push({ type: 'del_close', level: --state.level });
state.pos = state.posMax + 2;
state.posMax = max;
return true;
};

6
lib/rules_inline/emphasis.js

@ -16,7 +16,7 @@ function isAlphaNum(code) {
// should be treated as a special case
function parseStart(state, start) {
var pos = start, lastChar, count,
max = Math.min(state.posMax, pos + 4),
max = state.posMax,
marker = state.src.charCodeAt(start);
lastChar = state.pending.length !== 0 ? state.pending.charCodeAt(state.pending.length - 1) : -1;
@ -60,7 +60,7 @@ function parseStart(state, start) {
// should be treated as a special case
function parseEnd(state, start) {
var pos = start, lastChar, count,
max = Math.min(state.posMax, pos + 4),
max = state.posMax,
marker = state.src.charCodeAt(start);
lastChar = state.pending.length !== 0 ? state.pending.charCodeAt(state.pending.length - 1) : -1;
@ -179,7 +179,7 @@ module.exports = function emphasis(state/*, silent*/) {
}
count = parseStart(state, state.pos);
if (count >= 1) {
if (count >= 1 && count < 4) {
stack.push(count);
state.pos += count;
continue;

Loading…
Cancel
Save