Browse Source

Add subscript and superscript

pull/14/head
Alex Kocharin 10 years ago
parent
commit
3b785a0bfa
  1. 4
      lib/parser_inline.js
  2. 14
      lib/renderer.js
  3. 68
      lib/rules_inline/sub.js
  4. 68
      lib/rules_inline/sup.js

4
lib/parser_inline.js

@ -19,6 +19,8 @@ _rules.push(require('./rules_inline/del'));
_rules.push(require('./rules_inline/ins'));
_rules.push(require('./rules_inline/mark'));
_rules.push(require('./rules_inline/emphasis'));
_rules.push(require('./rules_inline/sub'));
_rules.push(require('./rules_inline/sup'));
_rules.push(require('./rules_inline/links'));
_rules.push(require('./rules_inline/autolink'));
_rules.push(require('./rules_inline/htmltag'));
@ -49,7 +51,7 @@ function ParserInline() {
// Rule to skip pure text
// - '{}$%@+=:' reserved for extentions
this.textMatch = /[\n\\`*_\[\]!&<{}$%@~+=:]/;
this.textMatch = /[\n\\`*_^\[\]!&<{}$%@~+=:]/;
// By default CommonMark allows too much in links
// If you need to restrict it - override this with your validator.

14
lib/renderer.js

@ -240,6 +240,20 @@ rules.mark_close = function(/*tokens, idx, options*/) {
};
rules.sub_open = function(/*tokens, idx, options*/) {
return '<sub>';
};
rules.sub_close = function(/*tokens, idx, options*/) {
return '</sub>';
};
rules.sup_open = function(/*tokens, idx, options*/) {
return '<sup>';
};
rules.sup_close = function(/*tokens, idx, options*/) {
return '</sup>';
};
rules.hardbreak = function (tokens, idx, options) {
return options.xhtmlOut ? '<br />\n' : '<br>\n';
};

68
lib/rules_inline/sub.js

@ -0,0 +1,68 @@
// Process ~subscript~
'use strict';
module.exports = function sub(state, silent) {
var found,
stack,
max = state.posMax,
start = state.pos,
lastChar,
nextChar;
if (state.src.charCodeAt(start) !== 0x7E/* ~ */) { return false; }
if (start + 2 >= max) { return false; }
if (state.level >= state.options.maxNesting) { return false; }
lastChar = start > 0 ? state.src.charCodeAt(start - 1) : -1;
nextChar = state.src.charCodeAt(start + 2);
if (nextChar === 0x20 || nextChar === 0x0A) { return false; }
state.pos = start + 1;
stack = 1;
while (state.pos < max) {
if (state.src.charCodeAt(state.pos) === 0x7E/* ~ */) {
lastChar = state.src.charCodeAt(state.pos - 1);
nextChar = state.pos + 1 < max ? state.src.charCodeAt(state.pos + 1) : -1;
if (nextChar !== 0x7E/* ~ */ && lastChar !== 0x7E/* ~ */) {
if (lastChar !== 0x20 && lastChar !== 0x0A) {
// closing '~'
stack--;
} else if (nextChar !== 0x20 && nextChar !== 0x0A) {
// opening '~'
stack++;
} // else {
// // standalone ' ~ ' indented with spaces
//}
if (stack <= 0) {
found = true;
break;
}
}
}
state.parser.skipToken(state);
}
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 + 1;
if (!silent) {
state.push({ type: 'sub_open', level: state.level++ });
state.parser.tokenize(state);
state.push({ type: 'sub_close', level: --state.level });
}
state.pos = state.posMax + 1;
state.posMax = max;
return true;
};

68
lib/rules_inline/sup.js

@ -0,0 +1,68 @@
// Process ~superscript~
'use strict';
module.exports = function sup(state, silent) {
var found,
stack,
max = state.posMax,
start = state.pos,
lastChar,
nextChar;
if (state.src.charCodeAt(start) !== 0x5E/* ^ */) { return false; }
if (start + 2 >= max) { return false; }
if (state.level >= state.options.maxNesting) { return false; }
lastChar = start > 0 ? state.src.charCodeAt(start - 1) : -1;
nextChar = state.src.charCodeAt(start + 2);
if (nextChar === 0x20 || nextChar === 0x0A) { return false; }
state.pos = start + 1;
stack = 1;
while (state.pos < max) {
if (state.src.charCodeAt(state.pos) === 0x5E/* ^ */) {
lastChar = state.src.charCodeAt(state.pos - 1);
nextChar = state.pos + 1 < max ? state.src.charCodeAt(state.pos + 1) : -1;
if (nextChar !== 0x5E/* ^ */ && lastChar !== 0x5E/* ^ */) {
if (lastChar !== 0x20 && lastChar !== 0x0A) {
// closing '^'
stack--;
} else if (nextChar !== 0x20 && nextChar !== 0x0A) {
// opening '^'
stack++;
} // else {
// // standalone ' ^ ' indented with spaces
//}
if (stack <= 0) {
found = true;
break;
}
}
}
state.parser.skipToken(state);
}
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 + 1;
if (!silent) {
state.push({ type: 'sub_open', level: state.level++ });
state.parser.tokenize(state);
state.push({ type: 'sub_close', level: --state.level });
}
state.pos = state.posMax + 1;
state.posMax = max;
return true;
};
Loading…
Cancel
Save