UNPKG

@awesome-fe/translate

Version:
367 lines 11.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.listTokenizer = void 0; const remove_indent_1 = require("./utils/remove-indent"); const get_indent_1 = require("./utils/get-indent"); const tabSize = 4; const looseListItemExpression = /\n\n(?!\s*$)/; const taskItemExpression = /^\[([ \t]|x|X)][ \t]/; const bulletExpression = /^([ \t]*)([*+-]|\d+[.)])( {1,4}(?! )| |\t|$|(?=\n))([^\n]*)/; const pedanticBulletExpression = /^([ \t]*)([*+-]|\d+[.)])([ \t]+)/; const initialIndentExpression = /^( {1,4}|\t)?/gm; function isDecimal(character) { const code = typeof character === 'string' ? character.charCodeAt(0) : character; return code >= 48 && code <= 57; /* 0-9 */ } function listTokenizer(eat, value, silent) { const self = this; const commonmark = self.options.commonmark; const pedantic = self.options.pedantic; const tokenizers = self.blockTokenizers; const interuptors = self.interruptList; let index = 0; let length = value.length; let start = null; let size = 0; let queue; let ordered; let character; let marker; let currentMarker; let empty; let item; let spread = false; while (index < length) { character = value.charAt(index); if (character === '\t') { size += tabSize - (size % tabSize); } else if (character === ' ') { size++; } else { break; } index++; } if (size >= tabSize) { return; } character = value.charAt(index); if (character === '*' || character === '+' || character === '-') { marker = character; ordered = false; } else { ordered = true; queue = ''; while (index < length) { character = value.charAt(index); if (!isDecimal(character)) { break; } queue += character; index++; } character = value.charAt(index); if (!queue || !(character === '.' || (commonmark && character === ')'))) { return; } start = parseInt(queue, 10); marker = character; } character = value.charAt(++index); if (character !== ' ' && character !== '\t' && (pedantic || (character !== '\n' && character !== ''))) { return; } if (silent) { return true; } index = 0; const items = []; let allLines = []; let emptyLines = []; while (index < length) { let nextIndex = value.indexOf('\n', index); const startIndex = index; let prefixed = false; let indented = false; if (nextIndex === -1) { nextIndex = length; } let end = index + tabSize; size = 0; while (index < length) { character = value.charAt(index); if (character === '\t') { size += tabSize - (size % tabSize); } else if (character === ' ') { size++; } else { break; } index++; } if (size >= tabSize) { indented = true; } if (item && size >= item.indent) { indented = true; } character = value.charAt(index); currentMarker = null; if (!indented) { if (character === '*' || character === '+' || character === '-') { currentMarker = character; index++; size++; } else { queue = ''; while (index < length) { character = value.charAt(index); if (!isDecimal(character)) { break; } queue += character; index++; } character = value.charAt(index); index++; if (queue && (character === '.' || (commonmark && character === ')'))) { currentMarker = character; size += queue.length + 1; } } if (currentMarker) { character = value.charAt(index); if (character === '\t') { size += tabSize - (size % tabSize); index++; } else if (character === ' ') { end = index + tabSize; while (index < end) { if (value.charAt(index) !== ' ') { break; } index++; size++; } if (index === end && value.charAt(index) === ' ') { index -= tabSize - 1; size -= tabSize - 1; } } else if (character !== '\n' && character !== '') { currentMarker = null; } } } if (currentMarker) { if (!pedantic && marker !== currentMarker) { break; } prefixed = true; } else { if (!commonmark && !indented && value.charAt(startIndex) === ' ') { indented = true; } else if (commonmark && item) { indented = size >= item.indent || size > tabSize; } prefixed = false; index = startIndex; } const line = value.slice(startIndex, nextIndex); const content = startIndex === index ? line : value.slice(index, nextIndex); if (currentMarker === '*' || currentMarker === '_' || currentMarker === '-') { if (tokenizers.thematicBreak.call(self, eat, line, true)) { break; } } const prevEmpty = empty; empty = !prefixed && !content?.trim()?.length; if (indented && item) { item.value = item.value.concat(emptyLines, line); allLines = allLines.concat(emptyLines, line); emptyLines = []; } else if (prefixed) { if (emptyLines.length !== 0) { spread = true; item.value.push(''); item.trail = emptyLines.concat(); } item = { value: [line], indent: size, trail: [], }; items.push(item); allLines = allLines.concat(emptyLines, line); emptyLines = []; } else if (empty) { if (prevEmpty && !commonmark) { break; } emptyLines.push(line); } else { if (prevEmpty) { break; } if (interrupt(interuptors, tokenizers, self, [eat, line, true])) { break; } item.value = item.value.concat(emptyLines, line); allLines = allLines.concat(emptyLines, line); emptyLines = []; } index = nextIndex + 1; } const node = eat(allLines.join('\n')).reset({ type: 'list', ordered: ordered, start: start, spread: spread, children: [], }); const enterTop = self.enterList(); const exitBlockquote = self.enterBlock(); index = -1; length = items.length; while (++index < length) { item = items[index].value.join('\n'); const now = eat.now(); eat(item)(listItem(self, item, now, item.split(' ')[0]), node); item = items[index].trail.join('\n'); if (index !== length - 1) { item += '\n'; } eat(item); } enterTop(); exitBlockquote(); return node; } exports.listTokenizer = listTokenizer; function listItem(ctx, value, position, marker) { const offsets = ctx.offset; const fn = ctx.options.pedantic ? pedanticListItem : normalListItem; let checked = null; let task; let indent; value = fn.call(null, ctx, value, position); if (ctx.options.gfm) { task = value.match(taskItemExpression); if (task) { indent = task[0].length; checked = task[1].toLowerCase() === 'x'; offsets[position.line] += indent; value = value.slice(indent); } } return { type: 'listItem', marker, spread: looseListItemExpression.test(value), checked: checked, children: ctx.tokenizeBlock(value, position), }; } // Create a list-item using overly simple mechanics. function pedanticListItem(ctx, value, position) { const offsets = ctx.offset; let line = position.line; // Remove the list-item’s bullet. value = value.replace(pedanticBulletExpression, replacer); // The initial line was also matched by the below, so we reset the `line`. line = position.line; return value.replace(initialIndentExpression, replacer); // A simple replacer which removed all matches, and adds their length to // `offset`. function replacer($0) { offsets[line] = (offsets[line] || 0) + $0.length; line++; return ''; } } // Create a list-item using sane mechanics. function normalListItem(ctx, value, position) { const offsets = ctx.offset; let line = position.line; let max; let bullet; let rest; let lines; let trimmedLines; let index; let length; // Remove the list-item’s bullet. value = value.replace(bulletExpression, replacer); lines = value.split('\n'); trimmedLines = (0, remove_indent_1.removeIndent)(value, (0, get_indent_1.getIndent)(max).indent).split('\n'); // 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. trimmedLines[0] = rest; offsets[line] = (offsets[line] || 0) + bullet.length; line++; index = 0; length = lines.length; while (++index < length) { offsets[line] = (offsets[line] || 0) + lines[index].length - trimmedLines[index].length; line++; } return trimmedLines.join('\n'); function replacer($0, $1, $2, $3, $4) { bullet = $1 + $2 + $3; rest = $4; // Make sure that the first nine numbered list items can indent with an // extra space. That is, when the bullet did not receive an extra final // space. if (Number($2) < 10 && bullet.length % 2 === 1) { $2 = ' ' + $2; } max = $1 + ' '.repeat($2.length) + $3; return max + rest; } } function interrupt(interruptors, tokenizers, ctx, params) { const length = interruptors.length; let index = -1; let interruptor; let config; while (++index < length) { interruptor = interruptors[index]; config = interruptor[1] || {}; if (config.pedantic !== undefined && config.pedantic !== ctx.options.pedantic) { continue; } if (config.commonmark !== undefined && config.commonmark !== ctx.options.commonmark) { continue; } if (tokenizers[interruptor[0]].apply(ctx, params)) { return true; } } return false; } //# sourceMappingURL=list-tokenizer.js.map