summaryrefslogtreecommitdiff
path: root/node_modules/markdown-it/lib/rules_inline/state_inline.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/markdown-it/lib/rules_inline/state_inline.js')
-rw-r--r--node_modules/markdown-it/lib/rules_inline/state_inline.js154
1 files changed, 154 insertions, 0 deletions
diff --git a/node_modules/markdown-it/lib/rules_inline/state_inline.js b/node_modules/markdown-it/lib/rules_inline/state_inline.js
new file mode 100644
index 0000000..efbf9bd
--- /dev/null
+++ b/node_modules/markdown-it/lib/rules_inline/state_inline.js
@@ -0,0 +1,154 @@
+// Inline parser state
+
+'use strict';
+
+
+var Token = require('../token');
+var isWhiteSpace = require('../common/utils').isWhiteSpace;
+var isPunctChar = require('../common/utils').isPunctChar;
+var isMdAsciiPunct = require('../common/utils').isMdAsciiPunct;
+
+
+function StateInline(src, md, env, outTokens) {
+ this.src = src;
+ this.env = env;
+ this.md = md;
+ this.tokens = outTokens;
+ this.tokens_meta = Array(outTokens.length);
+
+ this.pos = 0;
+ this.posMax = this.src.length;
+ this.level = 0;
+ this.pending = '';
+ this.pendingLevel = 0;
+
+ // Stores { start: end } pairs. Useful for backtrack
+ // optimization of pairs parse (emphasis, strikes).
+ this.cache = {};
+
+ // List of emphasis-like delimiters for current tag
+ this.delimiters = [];
+
+ // Stack of delimiter lists for upper level tags
+ this._prev_delimiters = [];
+
+ // backtick length => last seen position
+ this.backticks = {};
+ this.backticksScanned = false;
+}
+
+
+// Flush pending text
+//
+StateInline.prototype.pushPending = function () {
+ var token = new Token('text', '', 0);
+ token.content = this.pending;
+ token.level = this.pendingLevel;
+ this.tokens.push(token);
+ this.pending = '';
+ return token;
+};
+
+
+// Push new token to "stream".
+// If pending text exists - flush it as text token
+//
+StateInline.prototype.push = function (type, tag, nesting) {
+ if (this.pending) {
+ this.pushPending();
+ }
+
+ var token = new Token(type, tag, nesting);
+ var token_meta = null;
+
+ if (nesting < 0) {
+ // closing tag
+ this.level--;
+ this.delimiters = this._prev_delimiters.pop();
+ }
+
+ token.level = this.level;
+
+ if (nesting > 0) {
+ // opening tag
+ this.level++;
+ this._prev_delimiters.push(this.delimiters);
+ this.delimiters = [];
+ token_meta = { delimiters: this.delimiters };
+ }
+
+ this.pendingLevel = this.level;
+ this.tokens.push(token);
+ this.tokens_meta.push(token_meta);
+ return token;
+};
+
+
+// Scan a sequence of emphasis-like markers, and determine whether
+// it can start an emphasis sequence or end an emphasis sequence.
+//
+// - start - position to scan from (it should point at a valid marker);
+// - canSplitWord - determine if these markers can be found inside a word
+//
+StateInline.prototype.scanDelims = function (start, canSplitWord) {
+ var pos = start, lastChar, nextChar, count, can_open, can_close,
+ isLastWhiteSpace, isLastPunctChar,
+ isNextWhiteSpace, isNextPunctChar,
+ left_flanking = true,
+ right_flanking = true,
+ max = this.posMax,
+ marker = this.src.charCodeAt(start);
+
+ // treat beginning of the line as a whitespace
+ lastChar = start > 0 ? this.src.charCodeAt(start - 1) : 0x20;
+
+ while (pos < max && this.src.charCodeAt(pos) === marker) { pos++; }
+
+ count = pos - start;
+
+ // treat end of the line as a whitespace
+ nextChar = pos < max ? this.src.charCodeAt(pos) : 0x20;
+
+ isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctChar(String.fromCharCode(lastChar));
+ isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctChar(String.fromCharCode(nextChar));
+
+ isLastWhiteSpace = isWhiteSpace(lastChar);
+ isNextWhiteSpace = isWhiteSpace(nextChar);
+
+ if (isNextWhiteSpace) {
+ left_flanking = false;
+ } else if (isNextPunctChar) {
+ if (!(isLastWhiteSpace || isLastPunctChar)) {
+ left_flanking = false;
+ }
+ }
+
+ if (isLastWhiteSpace) {
+ right_flanking = false;
+ } else if (isLastPunctChar) {
+ if (!(isNextWhiteSpace || isNextPunctChar)) {
+ right_flanking = false;
+ }
+ }
+
+ if (!canSplitWord) {
+ can_open = left_flanking && (!right_flanking || isLastPunctChar);
+ can_close = right_flanking && (!left_flanking || isNextPunctChar);
+ } else {
+ can_open = left_flanking;
+ can_close = right_flanking;
+ }
+
+ return {
+ can_open: can_open,
+ can_close: can_close,
+ length: count
+ };
+};
+
+
+// re-export Token class to use in block rules
+StateInline.prototype.Token = Token;
+
+
+module.exports = StateInline;