diff --git a/.eslintrc.yml b/.eslintrc.yml index 2658bb8..19fbf26 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -21,6 +21,9 @@ ignorePatterns: - benchmark/extra/ rules: + no-var: 2 + prefer-const: 2 + no-const-assign: 2 accessor-pairs: 2 array-bracket-spacing: [ 2, "always", { "singleValue": true, "objectsInArrays": true, "arraysInArrays": true } ] block-scoped-var: 2 diff --git a/benchmark/benchmark.mjs b/benchmark/benchmark.mjs index 0441af2..fdf23d0 100755 --- a/benchmark/benchmark.mjs +++ b/benchmark/benchmark.mjs @@ -4,13 +4,13 @@ import { createRequire } from 'node:module'; const require = createRequire(import.meta.url); -var fs = require('fs'); -var util = require('util'); -var Benchmark = require('benchmark'); -var ansi = require('ansi'); -var cursor = ansi(process.stdout); +const fs = require('fs'); +const util = require('util'); +const Benchmark = require('benchmark'); +const ansi = require('ansi'); +const cursor = ansi(process.stdout); -var IMPLS = []; +const IMPLS = []; for (const name of fs.readdirSync(new URL('./implementations', import.meta.url)).sort()) { const filepath = new URL(`./implementations/${name}/index.mjs`, import.meta.url); @@ -31,11 +31,11 @@ fs.readdirSync(new URL('./samples', import.meta.url)).sort().forEach(sample => { content.string = fs.readFileSync(filepath, 'utf8'); - var title = `(${content.string.length} bytes)`; + const title = `(${content.string.length} bytes)`; function onComplete() { cursor.write('\n'); } - var suite = new Benchmark.Suite( + const suite = new Benchmark.Suite( title, { onStart: () => { console.log('\nSample: %s %s', sample, title); }, @@ -68,7 +68,7 @@ fs.readdirSync(new URL('./samples', import.meta.url)).sort().forEach(sample => { function select(patterns) { - var result = []; + const result = []; if (!(patterns instanceof Array)) { patterns = [ patterns ]; @@ -91,7 +91,7 @@ function select(patterns) { function run(files) { - var selected = select(files); + const selected = select(files); if (selected.length > 0) { console.log('Selected samples: (%d of %d)', selected.length, SAMPLES.length); diff --git a/benchmark/implementations/commonmark-reference/index.mjs b/benchmark/implementations/commonmark-reference/index.mjs index 3487c39..45f6ac4 100644 --- a/benchmark/implementations/commonmark-reference/index.mjs +++ b/benchmark/implementations/commonmark-reference/index.mjs @@ -3,8 +3,8 @@ const require = createRequire(import.meta.url); const commonmark = require('../../extra/lib/node_modules/commonmark'); -var parser = new commonmark.Parser(); -var renderer = new commonmark.HtmlRenderer(); +const parser = new commonmark.Parser(); +const renderer = new commonmark.HtmlRenderer(); export function run(data) { return renderer.render(parser.parse(data)); diff --git a/benchmark/implementations/current-commonmark/index.mjs b/benchmark/implementations/current-commonmark/index.mjs index 4627887..83b7b5c 100644 --- a/benchmark/implementations/current-commonmark/index.mjs +++ b/benchmark/implementations/current-commonmark/index.mjs @@ -1,10 +1,10 @@ import markdownit from '../../../index.mjs'; -var md = markdownit('commonmark'); +const md = markdownit('commonmark'); // Replace normalizers to more primitive, for more "honest" compare. // Default ones can cause 1.5x slowdown. -var encode = md.utils.lib.mdurl.encode; +const encode = md.utils.lib.mdurl.encode; md.normalizeLink = function (url) { return encode(url); }; md.normalizeLinkText = function (str) { return str; }; diff --git a/benchmark/implementations/current/index.mjs b/benchmark/implementations/current/index.mjs index 97e1519..a638196 100644 --- a/benchmark/implementations/current/index.mjs +++ b/benchmark/implementations/current/index.mjs @@ -1,6 +1,6 @@ import markdownit from '../../../index.mjs'; -var md = markdownit({ +const md = markdownit({ html: true, linkify: true, typographer: true diff --git a/benchmark/implementations/markdown-it-2.2.1-commonmark/index.mjs b/benchmark/implementations/markdown-it-2.2.1-commonmark/index.mjs index 995441e..ae77026 100644 --- a/benchmark/implementations/markdown-it-2.2.1-commonmark/index.mjs +++ b/benchmark/implementations/markdown-it-2.2.1-commonmark/index.mjs @@ -3,7 +3,7 @@ const require = createRequire(import.meta.url); const markdownit = require('../../extra/lib/node_modules/markdown-it'); -var md = markdownit('commonmark'); +const md = markdownit('commonmark'); export function run(data) { return md.render(data); diff --git a/benchmark/profile.mjs b/benchmark/profile.mjs index 857582c..fe64319 100755 --- a/benchmark/profile.mjs +++ b/benchmark/profile.mjs @@ -4,14 +4,14 @@ import { readFileSync } from 'fs'; import markdownit from '../index.mjs'; -var md = markdownit({ +const md = markdownit({ html: true, linkify: false, typographer: false }); -var data = readFileSync(new URL('../test/fixtures/commonmark/spec.txt', import.meta.url), 'utf8'); +const data = readFileSync(new URL('../test/fixtures/commonmark/spec.txt', import.meta.url), 'utf8'); -for (var i = 0; i < 20; i++) { +for (let i = 0; i < 20; i++) { md.render(data); } diff --git a/bin/markdown-it.mjs b/bin/markdown-it.mjs index 7ba2e53..4e78cfe 100755 --- a/bin/markdown-it.mjs +++ b/bin/markdown-it.mjs @@ -7,7 +7,7 @@ import markdownit from '../index.mjs'; //////////////////////////////////////////////////////////////////////////////// -var cli = new argparse.ArgumentParser({ +const cli = new argparse.ArgumentParser({ prog: 'markdown-it', add_help: true }); @@ -48,13 +48,13 @@ cli.add_argument('-o', '--output', { default: '-' }); -var options = cli.parse_args(); +const options = cli.parse_args(); function readFile(filename, encoding, callback) { if (options.file === '-') { // read from stdin - var chunks = []; + const chunks = []; process.stdin.on('data', function (chunk) { chunks.push(chunk); }); @@ -70,7 +70,7 @@ function readFile(filename, encoding, callback) { //////////////////////////////////////////////////////////////////////////////// readFile(options.file, 'utf8', function (err, input) { - var output, md; + let output; if (err) { if (err.code === 'ENOENT') { @@ -86,7 +86,7 @@ readFile(options.file, 'utf8', function (err, input) { process.exit(1); } - md = markdownit({ + const md = markdownit({ html: !options.no_html, xhtmlOut: false, typographer: options.typographer, diff --git a/lib/common/html_re.mjs b/lib/common/html_re.mjs index df6ee9f..677ce56 100644 --- a/lib/common/html_re.mjs +++ b/lib/common/html_re.mjs @@ -1,25 +1,25 @@ // Regexps to match html elements -var attr_name = '[a-zA-Z_:][a-zA-Z0-9:._-]*'; +const attr_name = '[a-zA-Z_:][a-zA-Z0-9:._-]*'; -var unquoted = '[^"\'=<>`\\x00-\\x20]+'; -var single_quoted = "'[^']*'"; -var double_quoted = '"[^"]*"'; +const unquoted = '[^"\'=<>`\\x00-\\x20]+'; +const single_quoted = "'[^']*'"; +const double_quoted = '"[^"]*"'; -var attr_value = '(?:' + unquoted + '|' + single_quoted + '|' + double_quoted + ')'; +const attr_value = '(?:' + unquoted + '|' + single_quoted + '|' + double_quoted + ')'; -var attribute = '(?:\\s+' + attr_name + '(?:\\s*=\\s*' + attr_value + ')?)'; +const attribute = '(?:\\s+' + attr_name + '(?:\\s*=\\s*' + attr_value + ')?)'; -var open_tag = '<[A-Za-z][A-Za-z0-9\\-]*' + attribute + '*\\s*\\/?>'; +const open_tag = '<[A-Za-z][A-Za-z0-9\\-]*' + attribute + '*\\s*\\/?>'; -var close_tag = '<\\/[A-Za-z][A-Za-z0-9\\-]*\\s*>'; -var comment = '|'; -var processing = '<[?][\\s\\S]*?[?]>'; -var declaration = ']*>'; -var cdata = ''; +const close_tag = '<\\/[A-Za-z][A-Za-z0-9\\-]*\\s*>'; +const comment = '|'; +const processing = '<[?][\\s\\S]*?[?]>'; +const declaration = ']*>'; +const cdata = ''; -var HTML_TAG_RE = new RegExp('^(?:' + open_tag + '|' + close_tag + '|' + comment + +const HTML_TAG_RE = new RegExp('^(?:' + open_tag + '|' + close_tag + '|' + comment + '|' + processing + '|' + declaration + '|' + cdata + ')'); -var HTML_OPEN_CLOSE_TAG_RE = new RegExp('^(?:' + open_tag + '|' + close_tag + ')'); +const HTML_OPEN_CLOSE_TAG_RE = new RegExp('^(?:' + open_tag + '|' + close_tag + ')'); export { HTML_TAG_RE, HTML_OPEN_CLOSE_TAG_RE }; diff --git a/lib/common/utils.mjs b/lib/common/utils.mjs index 3220e44..5359f6b 100644 --- a/lib/common/utils.mjs +++ b/lib/common/utils.mjs @@ -10,7 +10,7 @@ function _class(obj) { return Object.prototype.toString.call(obj); } function isString(obj) { return _class(obj) === '[object String]'; } -var _hasOwnProperty = Object.prototype.hasOwnProperty; +const _hasOwnProperty = Object.prototype.hasOwnProperty; function has(object, key) { return _hasOwnProperty.call(object, key); @@ -19,7 +19,7 @@ function has(object, key) { // Merge objects // function assign(obj /*from1, from2, from3, ...*/) { - var sources = Array.prototype.slice.call(arguments, 1); + const sources = Array.prototype.slice.call(arguments, 1); sources.forEach(function (source) { if (!source) { return; } @@ -65,8 +65,8 @@ function fromCodePoint(c) { /*eslint no-bitwise:0*/ if (c > 0xffff) { c -= 0x10000; - var surrogate1 = 0xd800 + (c >> 10), - surrogate2 = 0xdc00 + (c & 0x3ff); + const surrogate1 = 0xd800 + (c >> 10), + surrogate2 = 0xdc00 + (c & 0x3ff); return String.fromCharCode(surrogate1, surrogate2); } @@ -74,18 +74,16 @@ function fromCodePoint(c) { } -var UNESCAPE_MD_RE = /\\([!"#$%&'()*+,\-.\/:;<=>?@[\\\]^_`{|}~])/g; -var ENTITY_RE = /&([a-z#][a-z0-9]{1,31});/gi; -var UNESCAPE_ALL_RE = new RegExp(UNESCAPE_MD_RE.source + '|' + ENTITY_RE.source, 'gi'); +const UNESCAPE_MD_RE = /\\([!"#$%&'()*+,\-.\/:;<=>?@[\\\]^_`{|}~])/g; +const ENTITY_RE = /&([a-z#][a-z0-9]{1,31});/gi; +const UNESCAPE_ALL_RE = new RegExp(UNESCAPE_MD_RE.source + '|' + ENTITY_RE.source, 'gi'); -var DIGITAL_ENTITY_TEST_RE = /^#((?:x[a-f0-9]{1,8}|[0-9]{1,8}))$/i; +const DIGITAL_ENTITY_TEST_RE = /^#((?:x[a-f0-9]{1,8}|[0-9]{1,8}))$/i; function replaceEntityPattern(match, name) { - var decoded, code; - if (name.charCodeAt(0) === 0x23/* # */ && DIGITAL_ENTITY_TEST_RE.test(name)) { - code = name[1].toLowerCase() === 'x' ? + const code = name[1].toLowerCase() === 'x' ? parseInt(name.slice(2), 16) : parseInt(name.slice(1), 10); if (isValidEntityCode(code)) { @@ -95,7 +93,7 @@ function replaceEntityPattern(match, name) { return match; } - decoded = decodeHTML(match); + const decoded = decodeHTML(match); if (decoded !== match) { return decoded; } @@ -125,9 +123,9 @@ function unescapeAll(str) { //////////////////////////////////////////////////////////////////////////////// -var HTML_ESCAPE_TEST_RE = /[&<>"]/; -var HTML_ESCAPE_REPLACE_RE = /[&<>"]/g; -var HTML_REPLACEMENTS = { +const HTML_ESCAPE_TEST_RE = /[&<>"]/; +const HTML_ESCAPE_REPLACE_RE = /[&<>"]/g; +const HTML_REPLACEMENTS = { '&': '&', '<': '<', '>': '>', @@ -147,7 +145,7 @@ function escapeHtml(str) { //////////////////////////////////////////////////////////////////////////////// -var REGEXP_ESCAPE_RE = /[.?*+^$[\]\\(){}|-]/g; +const REGEXP_ESCAPE_RE = /[.?*+^$[\]\\(){}|-]/g; function escapeRE(str) { return str.replace(REGEXP_ESCAPE_RE, '\\$&'); diff --git a/lib/helpers/parse_link_destination.mjs b/lib/helpers/parse_link_destination.mjs index 5dfa1bd..9d1892d 100644 --- a/lib/helpers/parse_link_destination.mjs +++ b/lib/helpers/parse_link_destination.mjs @@ -4,14 +4,15 @@ import { unescapeAll } from '../common/utils.mjs'; export default function parseLinkDestination(str, start, max) { - var code, level, - pos = start, - result = { - ok: false, - pos: 0, - lines: 0, - str: '' - }; + let code; + let pos = start; + + const result = { + ok: false, + pos: 0, + lines: 0, + str: '' + }; if (str.charCodeAt(pos) === 0x3C /* < */) { pos++; @@ -39,7 +40,7 @@ export default function parseLinkDestination(str, start, max) { // this should be ... } else { ... branch - level = 0; + let level = 0; while (pos < max) { code = str.charCodeAt(pos); diff --git a/lib/helpers/parse_link_label.mjs b/lib/helpers/parse_link_label.mjs index 6750793..ae86070 100644 --- a/lib/helpers/parse_link_label.mjs +++ b/lib/helpers/parse_link_label.mjs @@ -5,10 +5,10 @@ // export default function parseLinkLabel(state, start, disableNested) { - var level, found, marker, prevPos, - labelEnd = -1, - max = state.posMax, - oldPos = state.pos; + let level, found, marker, prevPos; + + const max = state.posMax; + const oldPos = state.pos; state.pos = start + 1; level = 1; @@ -36,6 +36,8 @@ export default function parseLinkLabel(state, start, disableNested) { } } + let labelEnd = -1; + if (found) { labelEnd = state.pos; } diff --git a/lib/helpers/parse_link_title.mjs b/lib/helpers/parse_link_title.mjs index e283ae9..5e3b196 100644 --- a/lib/helpers/parse_link_title.mjs +++ b/lib/helpers/parse_link_title.mjs @@ -5,16 +5,16 @@ import { unescapeAll } from '../common/utils.mjs'; export default function parseLinkTitle(str, start, max) { - var code, - marker, - lines = 0, - pos = start, - result = { - ok: false, - pos: 0, - lines: 0, - str: '' - }; + let code, marker; + let lines = 0; + let pos = start; + + const result = { + ok: false, + pos: 0, + lines: 0, + str: '' + }; if (pos >= max) { return result; } diff --git a/lib/index.mjs b/lib/index.mjs index ff7d849..0046a24 100644 --- a/lib/index.mjs +++ b/lib/index.mjs @@ -14,7 +14,7 @@ import cfg_default from './presets/default.mjs'; import cfg_zero from './presets/zero.mjs'; import cfg_commonmark from './presets/commonmark.mjs'; -var config = { +const config = { default: cfg_default, zero: cfg_zero, commonmark: cfg_commonmark @@ -29,12 +29,12 @@ var config = { // replace it with dummy function and use external sanitizer. // -var BAD_PROTO_RE = /^(vbscript|javascript|file|data):/; -var GOOD_DATA_RE = /^data:image\/(gif|png|jpeg|webp);/; +const BAD_PROTO_RE = /^(vbscript|javascript|file|data):/; +const GOOD_DATA_RE = /^data:image\/(gif|png|jpeg|webp);/; function validateLink(url) { // url should be normalized at this point, and existing entities are decoded - var str = url.trim().toLowerCase(); + const str = url.trim().toLowerCase(); return BAD_PROTO_RE.test(str) ? (GOOD_DATA_RE.test(str) ? true : false) : true; } @@ -42,10 +42,10 @@ function validateLink(url) { //////////////////////////////////////////////////////////////////////////////// -var RECODE_HOSTNAME_FOR = [ 'http:', 'https:', 'mailto:' ]; +const RECODE_HOSTNAME_FOR = [ 'http:', 'https:', 'mailto:' ]; function normalizeLink(url) { - var parsed = mdurl.parse(url, true); + const parsed = mdurl.parse(url, true); if (parsed.hostname) { // Encode hostnames in urls like: @@ -65,7 +65,7 @@ function normalizeLink(url) { } function normalizeLinkText(url) { - var parsed = mdurl.parse(url, true); + const parsed = mdurl.parse(url, true); if (parsed.hostname) { // Encode hostnames in urls like: @@ -385,10 +385,10 @@ MarkdownIt.prototype.set = function (options) { * will give better compatibility with next versions. **/ MarkdownIt.prototype.configure = function (presets) { - var self = this, presetName; + const self = this; if (utils.isString(presets)) { - presetName = presets; + const presetName = presets; presets = config[presetName]; if (!presets) { throw new Error('Wrong `markdown-it` preset "' + presetName + '", check name'); } } @@ -429,7 +429,7 @@ MarkdownIt.prototype.configure = function (presets) { * ``` **/ MarkdownIt.prototype.enable = function (list, ignoreInvalid) { - var result = []; + let result = []; if (!Array.isArray(list)) { list = [ list ]; } @@ -439,7 +439,7 @@ MarkdownIt.prototype.enable = function (list, ignoreInvalid) { result = result.concat(this.inline.ruler2.enable(list, true)); - var missed = list.filter(function (name) { return result.indexOf(name) < 0; }); + const missed = list.filter(function (name) { return result.indexOf(name) < 0; }); if (missed.length && !ignoreInvalid) { throw new Error('MarkdownIt. Failed to enable unknown rule(s): ' + missed); @@ -457,7 +457,7 @@ MarkdownIt.prototype.enable = function (list, ignoreInvalid) { * The same as [[MarkdownIt.enable]], but turn specified rules off. **/ MarkdownIt.prototype.disable = function (list, ignoreInvalid) { - var result = []; + let result = []; if (!Array.isArray(list)) { list = [ list ]; } @@ -467,7 +467,7 @@ MarkdownIt.prototype.disable = function (list, ignoreInvalid) { result = result.concat(this.inline.ruler2.disable(list, true)); - var missed = list.filter(function (name) { return result.indexOf(name) < 0; }); + const missed = list.filter(function (name) { return result.indexOf(name) < 0; }); if (missed.length && !ignoreInvalid) { throw new Error('MarkdownIt. Failed to disable unknown rule(s): ' + missed); @@ -493,7 +493,7 @@ MarkdownIt.prototype.disable = function (list, ignoreInvalid) { * ``` **/ MarkdownIt.prototype.use = function (plugin /*, params, ... */) { - var args = [ this ].concat(Array.prototype.slice.call(arguments, 1)); + const args = [ this ].concat(Array.prototype.slice.call(arguments, 1)); plugin.apply(plugin, args); return this; }; @@ -519,7 +519,7 @@ MarkdownIt.prototype.parse = function (src, env) { throw new Error('Input data should be a String'); } - var state = new this.core.State(src, this, env); + const state = new this.core.State(src, this, env); this.core.process(state); @@ -555,7 +555,7 @@ MarkdownIt.prototype.render = function (src, env) { * tokens in `children` property. Also updates `env` object. **/ MarkdownIt.prototype.parseInline = function (src, env) { - var state = new this.core.State(src, this, env); + const state = new this.core.State(src, this, env); state.inlineMode = true; this.core.process(state); diff --git a/lib/parser_block.mjs b/lib/parser_block.mjs index 106d476..825e44a 100644 --- a/lib/parser_block.mjs +++ b/lib/parser_block.mjs @@ -19,7 +19,7 @@ import r_heading from './rules_block/heading.mjs'; import r_lheading from './rules_block/lheading.mjs'; import r_paragraph from './rules_block/paragraph.mjs'; -var _rules = [ +const _rules = [ // First 2 params - rule name & source. Secondary array - list of rules, // which can be terminated by this one. [ 'table', r_table, [ 'paragraph', 'reference' ] ], @@ -47,7 +47,7 @@ function ParserBlock() { **/ this.ruler = new Ruler(); - for (var i = 0; i < _rules.length; i++) { + for (let i = 0; i < _rules.length; i++) { this.ruler.push(_rules[i][0], _rules[i][1], { alt: (_rules[i][2] || []).slice() }); } } @@ -56,12 +56,11 @@ function ParserBlock() { // Generate tokens for input range // ParserBlock.prototype.tokenize = function (state, startLine, endLine) { - var ok, i, prevLine, - rules = this.ruler.getRules(''), - len = rules.length, - line = startLine, - hasEmptyLines = false, - maxNesting = state.md.options.maxNesting; + const rules = this.ruler.getRules(''); + const len = rules.length; + const maxNesting = state.md.options.maxNesting; + let line = startLine; + let hasEmptyLines = false; while (line < endLine) { state.line = line = state.skipEmptyLines(line); @@ -84,9 +83,10 @@ ParserBlock.prototype.tokenize = function (state, startLine, endLine) { // - update `state.line` // - update `state.tokens` // - return true - prevLine = state.line; + const prevLine = state.line; + let ok = false; - for (i = 0; i < len; i++) { + for (let i = 0; i < len; i++) { ok = rules[i](state, line, endLine, false); if (ok) { if (prevLine >= state.line) { @@ -125,11 +125,9 @@ ParserBlock.prototype.tokenize = function (state, startLine, endLine) { * Process input string and push block tokens into `outTokens` **/ ParserBlock.prototype.parse = function (src, md, env, outTokens) { - var state; - if (!src) { return; } - state = new this.State(src, md, env, outTokens); + const state = new this.State(src, md, env, outTokens); this.tokenize(state, state.line, state.lineMax); }; diff --git a/lib/parser_core.mjs b/lib/parser_core.mjs index 4e9ce95..aeb56fb 100644 --- a/lib/parser_core.mjs +++ b/lib/parser_core.mjs @@ -17,7 +17,7 @@ import r_smartquotes from './rules_core/smartquotes.mjs'; import r_text_join from './rules_core/text_join.mjs'; -var _rules = [ +const _rules = [ [ 'normalize', r_normalize ], [ 'block', r_block ], [ 'inline', r_inline ], @@ -41,7 +41,7 @@ function Core() { **/ this.ruler = new Ruler(); - for (var i = 0; i < _rules.length; i++) { + for (let i = 0; i < _rules.length; i++) { this.ruler.push(_rules[i][0], _rules[i][1]); } } @@ -53,11 +53,9 @@ function Core() { * Executes core chain rules. **/ Core.prototype.process = function (state) { - var i, l, rules; + const rules = this.ruler.getRules(''); - rules = this.ruler.getRules(''); - - for (i = 0, l = rules.length; i < l; i++) { + for (let i = 0, l = rules.length; i < l; i++) { rules[i](state); } }; diff --git a/lib/parser_inline.mjs b/lib/parser_inline.mjs index 202aba4..41b8df6 100644 --- a/lib/parser_inline.mjs +++ b/lib/parser_inline.mjs @@ -28,7 +28,7 @@ import r_fragments_join from './rules_inline/fragments_join.mjs'; //////////////////////////////////////////////////////////////////////////////// // Parser rules -var _rules = [ +const _rules = [ [ 'text', r_text ], [ 'linkify', r_linkify ], [ 'newline', r_newline ], @@ -48,7 +48,7 @@ var _rules = [ // // Don't use this for anything except pairs (plugins working with `balance_pairs`). // -var _rules2 = [ +const _rules2 = [ [ 'balance_pairs', r_balance_pairs ], [ 'strikethrough', r_strikethrough.postProcess ], [ 'emphasis', r_emphasis.postProcess ], @@ -62,8 +62,6 @@ var _rules2 = [ * new ParserInline() **/ function ParserInline() { - var i; - /** * ParserInline#ruler -> Ruler * @@ -71,7 +69,7 @@ function ParserInline() { **/ this.ruler = new Ruler(); - for (i = 0; i < _rules.length; i++) { + for (let i = 0; i < _rules.length; i++) { this.ruler.push(_rules[i][0], _rules[i][1]); } @@ -83,7 +81,7 @@ function ParserInline() { **/ this.ruler2 = new Ruler(); - for (i = 0; i < _rules2.length; i++) { + for (let i = 0; i < _rules2.length; i++) { this.ruler2.push(_rules2[i][0], _rules2[i][1]); } } @@ -93,11 +91,11 @@ function ParserInline() { // returns `true` if any rule reported success // ParserInline.prototype.skipToken = function (state) { - var ok, i, pos = state.pos, - rules = this.ruler.getRules(''), - len = rules.length, - maxNesting = state.md.options.maxNesting, - cache = state.cache; + const pos = state.pos; + const rules = this.ruler.getRules(''); + const len = rules.length; + const maxNesting = state.md.options.maxNesting; + const cache = state.cache; if (typeof cache[pos] !== 'undefined') { @@ -105,8 +103,10 @@ ParserInline.prototype.skipToken = function (state) { return; } + let ok = false; + if (state.level < maxNesting) { - for (i = 0; i < len; i++) { + for (let i = 0; i < len; i++) { // Increment state.level and decrement it later to limit recursion. // It's harmless to do here, because no tokens are created. But ideally, // we'd need a separate private state variable for this purpose. @@ -143,11 +143,10 @@ ParserInline.prototype.skipToken = function (state) { // Generate tokens for input range // ParserInline.prototype.tokenize = function (state) { - var ok, i, prevPos, - rules = this.ruler.getRules(''), - len = rules.length, - end = state.posMax, - maxNesting = state.md.options.maxNesting; + const rules = this.ruler.getRules(''); + const len = rules.length; + const end = state.posMax; + const maxNesting = state.md.options.maxNesting; while (state.pos < end) { // Try all possible rules. @@ -156,10 +155,11 @@ ParserInline.prototype.tokenize = function (state) { // - update `state.pos` // - update `state.tokens` // - return true - prevPos = state.pos; + const prevPos = state.pos; + let ok = false; if (state.level < maxNesting) { - for (i = 0; i < len; i++) { + for (let i = 0; i < len; i++) { ok = rules[i](state, false); if (ok) { if (prevPos >= state.pos) { throw new Error("inline rule didn't increment state.pos"); } @@ -188,15 +188,14 @@ ParserInline.prototype.tokenize = function (state) { * Process input string and push inline tokens into `outTokens` **/ ParserInline.prototype.parse = function (str, md, env, outTokens) { - var i, rules, len; - var state = new this.State(str, md, env, outTokens); + const state = new this.State(str, md, env, outTokens); this.tokenize(state); - rules = this.ruler2.getRules(''); - len = rules.length; + const rules = this.ruler2.getRules(''); + const len = rules.length; - for (i = 0; i < len; i++) { + for (let i = 0; i < len; i++) { rules[i](state); } }; diff --git a/lib/renderer.mjs b/lib/renderer.mjs index e1f61fe..22b7e83 100644 --- a/lib/renderer.mjs +++ b/lib/renderer.mjs @@ -10,11 +10,11 @@ import { assign, unescapeAll, escapeHtml } from './common/utils.mjs'; //////////////////////////////////////////////////////////////////////////////// -var default_rules = {}; +const default_rules = {}; default_rules.code_inline = function (tokens, idx, options, env, slf) { - var token = tokens[idx]; + const token = tokens[idx]; return '' + escapeHtml(token.content) + @@ -23,7 +23,7 @@ default_rules.code_inline = function (tokens, idx, options, env, slf) { default_rules.code_block = function (tokens, idx, options, env, slf) { - var token = tokens[idx]; + const token = tokens[idx]; return '' + escapeHtml(tokens[idx].content) + @@ -32,18 +32,18 @@ default_rules.code_block = function (tokens, idx, options, env, slf) { default_rules.fence = function (tokens, idx, options, env, slf) { - var token = tokens[idx], - info = token.info ? unescapeAll(token.info).trim() : '', - langName = '', - langAttrs = '', - highlighted, i, arr, tmpAttrs, tmpToken; + const token = tokens[idx]; + const info = token.info ? unescapeAll(token.info).trim() : ''; + let langName = ''; + let langAttrs = ''; if (info) { - arr = info.split(/(\s+)/g); + const arr = info.split(/(\s+)/g); langName = arr[0]; langAttrs = arr.slice(2).join(''); } + let highlighted; if (options.highlight) { highlighted = options.highlight(token.content, langName, langAttrs) || escapeHtml(token.content); } else { @@ -58,8 +58,8 @@ default_rules.fence = function (tokens, idx, options, env, slf) { // May be, one day we will add .deepClone() for token and simplify this part, but // now we prefer to keep things local. if (info) { - i = token.attrIndex('class'); - tmpAttrs = token.attrs ? token.attrs.slice() : []; + const i = token.attrIndex('class'); + const tmpAttrs = token.attrs ? token.attrs.slice() : []; if (i < 0) { tmpAttrs.push([ 'class', options.langPrefix + langName ]); @@ -69,7 +69,7 @@ default_rules.fence = function (tokens, idx, options, env, slf) { } // Fake token just to render attributes - tmpToken = { + const tmpToken = { attrs: tmpAttrs }; @@ -86,7 +86,7 @@ default_rules.fence = function (tokens, idx, options, env, slf) { default_rules.image = function (tokens, idx, options, env, slf) { - var token = tokens[idx]; + const token = tokens[idx]; // "alt" attr MUST be set, even if empty. Because it's mandatory and // should be placed on proper position for tests. @@ -166,7 +166,7 @@ function Renderer() { * Render token attributes to string. **/ Renderer.prototype.renderAttrs = function renderAttrs(token) { - var i, l, result; + let i, l, result; if (!token.attrs) { return ''; } @@ -190,10 +190,8 @@ Renderer.prototype.renderAttrs = function renderAttrs(token) { * in [[Renderer#rules]]. **/ Renderer.prototype.renderToken = function renderToken(tokens, idx, options) { - var nextToken, - result = '', - needLf = false, - token = tokens[idx]; + const token = tokens[idx]; + let result = ''; // Tight list paragraphs if (token.hidden) { @@ -223,12 +221,13 @@ Renderer.prototype.renderToken = function renderToken(tokens, idx, options) { } // Check if we need to add a newline after this tag + let needLf = false; if (token.block) { needLf = true; if (token.nesting === 1) { if (idx + 1 < tokens.length) { - nextToken = tokens[idx + 1]; + const nextToken = tokens[idx + 1]; if (nextToken.type === 'inline' || nextToken.hidden) { // Block-level tag containing an inline tag. @@ -259,12 +258,11 @@ Renderer.prototype.renderToken = function renderToken(tokens, idx, options) { * The same as [[Renderer.render]], but for single token of `inline` type. **/ Renderer.prototype.renderInline = function (tokens, options, env) { - var type, - result = '', - rules = this.rules; + let result = ''; + const rules = this.rules; - for (var i = 0, len = tokens.length; i < len; i++) { - type = tokens[i].type; + for (let i = 0, len = tokens.length; i < len; i++) { + const type = tokens[i].type; if (typeof rules[type] !== 'undefined') { result += rules[type](tokens, i, options, env, this); @@ -288,9 +286,9 @@ Renderer.prototype.renderInline = function (tokens, options, env) { * instead of simple escaping. **/ Renderer.prototype.renderInlineAsText = function (tokens, options, env) { - var result = ''; + let result = ''; - for (var i = 0, len = tokens.length; i < len; i++) { + for (let i = 0, len = tokens.length; i < len; i++) { if (tokens[i].type === 'text') { result += tokens[i].content; } else if (tokens[i].type === 'image') { @@ -314,12 +312,11 @@ Renderer.prototype.renderInlineAsText = function (tokens, options, env) { * this method directly. **/ Renderer.prototype.render = function (tokens, options, env) { - var i, len, type, - result = '', - rules = this.rules; + let result = ''; + const rules = this.rules; - for (i = 0, len = tokens.length; i < len; i++) { - type = tokens[i].type; + for (let i = 0, len = tokens.length; i < len; i++) { + const type = tokens[i].type; if (type === 'inline') { result += this.renderInline(tokens[i].children, options, env); diff --git a/lib/ruler.mjs b/lib/ruler.mjs index 83591f0..b749571 100644 --- a/lib/ruler.mjs +++ b/lib/ruler.mjs @@ -47,7 +47,7 @@ function Ruler() { // Find rule index by name // Ruler.prototype.__find__ = function (name) { - for (var i = 0; i < this.__rules__.length; i++) { + for (let i = 0; i < this.__rules__.length; i++) { if (this.__rules__[i].name === name) { return i; } @@ -59,8 +59,8 @@ Ruler.prototype.__find__ = function (name) { // Build rules lookup cache // Ruler.prototype.__compile__ = function () { - var self = this; - var chains = [ '' ]; + const self = this; + const chains = [ '' ]; // collect unique names self.__rules__.forEach(function (rule) { @@ -114,8 +114,8 @@ Ruler.prototype.__compile__ = function () { * ``` **/ Ruler.prototype.at = function (name, fn, options) { - var index = this.__find__(name); - var opt = options || {}; + const index = this.__find__(name); + const opt = options || {}; if (index === -1) { throw new Error('Parser rule not found: ' + name); } @@ -150,8 +150,8 @@ Ruler.prototype.at = function (name, fn, options) { * ``` **/ Ruler.prototype.before = function (beforeName, ruleName, fn, options) { - var index = this.__find__(beforeName); - var opt = options || {}; + const index = this.__find__(beforeName); + const opt = options || {}; if (index === -1) { throw new Error('Parser rule not found: ' + beforeName); } @@ -191,8 +191,8 @@ Ruler.prototype.before = function (beforeName, ruleName, fn, options) { * ``` **/ Ruler.prototype.after = function (afterName, ruleName, fn, options) { - var index = this.__find__(afterName); - var opt = options || {}; + const index = this.__find__(afterName); + const opt = options || {}; if (index === -1) { throw new Error('Parser rule not found: ' + afterName); } @@ -230,7 +230,7 @@ Ruler.prototype.after = function (afterName, ruleName, fn, options) { * ``` **/ Ruler.prototype.push = function (ruleName, fn, options) { - var opt = options || {}; + const opt = options || {}; this.__rules__.push({ name: ruleName, @@ -258,11 +258,11 @@ Ruler.prototype.push = function (ruleName, fn, options) { Ruler.prototype.enable = function (list, ignoreInvalid) { if (!Array.isArray(list)) { list = [ list ]; } - var result = []; + const result = []; // Search by name and enable list.forEach(function (name) { - var idx = this.__find__(name); + const idx = this.__find__(name); if (idx < 0) { if (ignoreInvalid) { return; } @@ -311,11 +311,11 @@ Ruler.prototype.enableOnly = function (list, ignoreInvalid) { Ruler.prototype.disable = function (list, ignoreInvalid) { if (!Array.isArray(list)) { list = [ list ]; } - var result = []; + const result = []; // Search by name and disable list.forEach(function (name) { - var idx = this.__find__(name); + const idx = this.__find__(name); if (idx < 0) { if (ignoreInvalid) { return; } diff --git a/lib/rules_block/blockquote.mjs b/lib/rules_block/blockquote.mjs index 65bba4f..12f7a7b 100644 --- a/lib/rules_block/blockquote.mjs +++ b/lib/rules_block/blockquote.mjs @@ -3,29 +3,10 @@ import { isSpace } from '../common/utils.mjs'; export default function blockquote(state, startLine, endLine, silent) { - var adjustTab, - ch, - i, - initial, - l, - lastLineEmpty, - lines, - nextLine, - offset, - oldBMarks, - oldBSCount, - oldIndent, - oldParentType, - oldSCount, - oldTShift, - spaceAfterMarker, - terminate, - terminatorRules, - token, - isOutdented, - oldLineMax = state.lineMax, - pos = state.bMarks[startLine] + state.tShift[startLine], - max = state.eMarks[startLine]; + let pos = state.bMarks[startLine] + state.tShift[startLine]; + let max = state.eMarks[startLine]; + + const oldLineMax = state.lineMax; // if it's indented more than 3 spaces, it should be a code block if (state.sCount[startLine] - state.blkIndent >= 4) { return false; } @@ -37,15 +18,17 @@ export default function blockquote(state, startLine, endLine, silent) { // so no point trying to find the end of it in silent mode if (silent) { return true; } - oldBMarks = []; - oldBSCount = []; - oldSCount = []; - oldTShift = []; + const oldBMarks = []; + const oldBSCount = []; + const oldSCount = []; + const oldTShift = []; - terminatorRules = state.md.block.ruler.getRules('blockquote'); + const terminatorRules = state.md.block.ruler.getRules('blockquote'); - oldParentType = state.parentType; + const oldParentType = state.parentType; state.parentType = 'blockquote'; + let lastLineEmpty = false; + let nextLine; // Search the end of the block // @@ -74,7 +57,7 @@ export default function blockquote(state, startLine, endLine, silent) { // > current blockquote // 2. checking this line // ``` - isOutdented = state.sCount[nextLine] < state.blkIndent; + const isOutdented = state.sCount[nextLine] < state.blkIndent; pos = state.bMarks[nextLine] + state.tShift[nextLine]; max = state.eMarks[nextLine]; @@ -88,7 +71,9 @@ export default function blockquote(state, startLine, endLine, silent) { // This line is inside the blockquote. // set offset past spaces and ">" - initial = state.sCount[nextLine] + 1; + let initial = state.sCount[nextLine] + 1; + let spaceAfterMarker; + let adjustTab; // skip one optional space after '>' if (state.src.charCodeAt(pos) === 0x20 /* space */) { @@ -117,12 +102,12 @@ export default function blockquote(state, startLine, endLine, silent) { spaceAfterMarker = false; } - offset = initial; + let offset = initial; oldBMarks.push(state.bMarks[nextLine]); state.bMarks[nextLine] = pos; while (pos < max) { - ch = state.src.charCodeAt(pos); + const ch = state.src.charCodeAt(pos); if (isSpace(ch)) { if (ch === 0x09) { @@ -154,8 +139,8 @@ export default function blockquote(state, startLine, endLine, silent) { if (lastLineEmpty) { break; } // Case 3: another tag found. - terminate = false; - for (i = 0, l = terminatorRules.length; i < l; i++) { + let terminate = false; + for (let i = 0, l = terminatorRules.length; i < l; i++) { if (terminatorRules[i](state, nextLine, endLine, true)) { terminate = true; break; @@ -193,17 +178,18 @@ export default function blockquote(state, startLine, endLine, silent) { state.sCount[nextLine] = -1; } - oldIndent = state.blkIndent; + const oldIndent = state.blkIndent; state.blkIndent = 0; - token = state.push('blockquote_open', 'blockquote', 1); - token.markup = '>'; - token.map = lines = [ startLine, 0 ]; + const token_o = state.push('blockquote_open', 'blockquote', 1); + token_o.markup = '>'; + const lines = [ startLine, 0 ]; + token_o.map = lines; state.md.block.tokenize(state, startLine, nextLine); - token = state.push('blockquote_close', 'blockquote', -1); - token.markup = '>'; + const token_c = state.push('blockquote_close', 'blockquote', -1); + token_c.markup = '>'; state.lineMax = oldLineMax; state.parentType = oldParentType; @@ -211,7 +197,7 @@ export default function blockquote(state, startLine, endLine, silent) { // Restore original tShift; this might not be necessary since the parser // has already been here, but just to make sure we can do that. - for (i = 0; i < oldTShift.length; i++) { + for (let i = 0; i < oldTShift.length; i++) { state.bMarks[i + startLine] = oldBMarks[i]; state.tShift[i + startLine] = oldTShift[i]; state.sCount[i + startLine] = oldSCount[i]; diff --git a/lib/rules_block/code.mjs b/lib/rules_block/code.mjs index 252f385..bcd36d3 100644 --- a/lib/rules_block/code.mjs +++ b/lib/rules_block/code.mjs @@ -1,11 +1,10 @@ // Code block (4 spaces padded) export default function code(state, startLine, endLine/*, silent*/) { - var nextLine, last, token; - if (state.sCount[startLine] - state.blkIndent < 4) { return false; } - last = nextLine = startLine + 1; + let nextLine = startLine + 1; + let last = nextLine; while (nextLine < endLine) { if (state.isEmpty(nextLine)) { @@ -23,7 +22,7 @@ export default function code(state, startLine, endLine/*, silent*/) { state.line = last; - token = state.push('code_block', 'code', 0); + const token = state.push('code_block', 'code', 0); token.content = state.getLines(startLine, last, 4 + state.blkIndent, false) + '\n'; token.map = [ startLine, state.line ]; diff --git a/lib/rules_block/fence.mjs b/lib/rules_block/fence.mjs index 498e841..7f5ebb2 100644 --- a/lib/rules_block/fence.mjs +++ b/lib/rules_block/fence.mjs @@ -1,32 +1,30 @@ // fences (``` lang, ~~~ lang) export default function fence(state, startLine, endLine, silent) { - var marker, len, params, nextLine, mem, token, markup, - haveEndMarker = false, - pos = state.bMarks[startLine] + state.tShift[startLine], - max = state.eMarks[startLine]; + let pos = state.bMarks[startLine] + state.tShift[startLine]; + let max = state.eMarks[startLine]; // if it's indented more than 3 spaces, it should be a code block if (state.sCount[startLine] - state.blkIndent >= 4) { return false; } if (pos + 3 > max) { return false; } - marker = state.src.charCodeAt(pos); + const marker = state.src.charCodeAt(pos); if (marker !== 0x7E/* ~ */ && marker !== 0x60 /* ` */) { return false; } // scan marker length - mem = pos; + let mem = pos; pos = state.skipChars(pos, marker); - len = pos - mem; + let len = pos - mem; if (len < 3) { return false; } - markup = state.src.slice(mem, pos); - params = state.src.slice(pos, max); + const markup = state.src.slice(mem, pos); + const params = state.src.slice(pos, max); if (marker === 0x60 /* ` */) { if (params.indexOf(String.fromCharCode(marker)) >= 0) { @@ -38,7 +36,8 @@ export default function fence(state, startLine, endLine, silent) { if (silent) { return true; } // search end of block - nextLine = startLine; + let nextLine = startLine; + let haveEndMarker = false; for (;;) { nextLine++; @@ -85,7 +84,7 @@ export default function fence(state, startLine, endLine, silent) { state.line = nextLine + (haveEndMarker ? 1 : 0); - token = state.push('fence', 'code', 0); + const token = state.push('fence', 'code', 0); token.info = params; token.content = state.getLines(startLine + 1, nextLine, len, true); token.markup = markup; diff --git a/lib/rules_block/heading.mjs b/lib/rules_block/heading.mjs index 0bbd2d2..5831ac0 100644 --- a/lib/rules_block/heading.mjs +++ b/lib/rules_block/heading.mjs @@ -3,19 +3,18 @@ import { isSpace } from '../common/utils.mjs'; export default function heading(state, startLine, endLine, silent) { - var ch, level, tmp, token, - pos = state.bMarks[startLine] + state.tShift[startLine], - max = state.eMarks[startLine]; + let pos = state.bMarks[startLine] + state.tShift[startLine]; + let max = state.eMarks[startLine]; // if it's indented more than 3 spaces, it should be a code block if (state.sCount[startLine] - state.blkIndent >= 4) { return false; } - ch = state.src.charCodeAt(pos); + let ch = state.src.charCodeAt(pos); if (ch !== 0x23/* # */ || pos >= max) { return false; } // count heading level - level = 1; + let level = 1; ch = state.src.charCodeAt(++pos); while (ch === 0x23/* # */ && pos < max && level <= 6) { level++; @@ -29,24 +28,24 @@ export default function heading(state, startLine, endLine, silent) { // Let's cut tails like ' ### ' from the end of string max = state.skipSpacesBack(max, pos); - tmp = state.skipCharsBack(max, 0x23, pos); // # + const tmp = state.skipCharsBack(max, 0x23, pos); // # if (tmp > pos && isSpace(state.src.charCodeAt(tmp - 1))) { max = tmp; } state.line = startLine + 1; - token = state.push('heading_open', 'h' + String(level), 1); - token.markup = '########'.slice(0, level); - token.map = [ startLine, state.line ]; + const token_o = state.push('heading_open', 'h' + String(level), 1); + token_o.markup = '########'.slice(0, level); + token_o.map = [ startLine, state.line ]; - token = state.push('inline', '', 0); - token.content = state.src.slice(pos, max).trim(); - token.map = [ startLine, state.line ]; - token.children = []; + const token_i = state.push('inline', '', 0); + token_i.content = state.src.slice(pos, max).trim(); + token_i.map = [ startLine, state.line ]; + token_i.children = []; - token = state.push('heading_close', 'h' + String(level), -1); - token.markup = '########'.slice(0, level); + const token_c = state.push('heading_close', 'h' + String(level), -1); + token_c.markup = '########'.slice(0, level); return true; } diff --git a/lib/rules_block/hr.mjs b/lib/rules_block/hr.mjs index e7ae1e8..1afa72d 100644 --- a/lib/rules_block/hr.mjs +++ b/lib/rules_block/hr.mjs @@ -3,14 +3,12 @@ import { isSpace } from '../common/utils.mjs'; export default function hr(state, startLine, endLine, silent) { - var marker, cnt, ch, token, - pos = state.bMarks[startLine] + state.tShift[startLine], - max = state.eMarks[startLine]; - + const max = state.eMarks[startLine]; // if it's indented more than 3 spaces, it should be a code block if (state.sCount[startLine] - state.blkIndent >= 4) { return false; } - marker = state.src.charCodeAt(pos++); + let pos = state.bMarks[startLine] + state.tShift[startLine]; + const marker = state.src.charCodeAt(pos++); // Check hr marker if (marker !== 0x2A/* * */ && @@ -21,9 +19,9 @@ export default function hr(state, startLine, endLine, silent) { // markers can be mixed with spaces, but there should be at least 3 of them - cnt = 1; + let cnt = 1; while (pos < max) { - ch = state.src.charCodeAt(pos++); + const ch = state.src.charCodeAt(pos++); if (ch !== marker && !isSpace(ch)) { return false; } if (ch === marker) { cnt++; } } @@ -34,7 +32,7 @@ export default function hr(state, startLine, endLine, silent) { state.line = startLine + 1; - token = state.push('hr', 'hr', 0); + const token = state.push('hr', 'hr', 0); token.map = [ startLine, state.line ]; token.markup = Array(cnt + 1).join(String.fromCharCode(marker)); diff --git a/lib/rules_block/html_block.mjs b/lib/rules_block/html_block.mjs index 4d5f356..5019713 100644 --- a/lib/rules_block/html_block.mjs +++ b/lib/rules_block/html_block.mjs @@ -6,7 +6,7 @@ import { HTML_OPEN_CLOSE_TAG_RE } from '../common/html_re.mjs'; // An array of opening and corresponding closing sequences for html tags, // last argument defines whether it can terminate a paragraph or not // -var HTML_SEQUENCES = [ +const HTML_SEQUENCES = [ [ /^<(script|pre|style|textarea)(?=(\s|>|$))/i, /<\/(script|pre|style|textarea)>/i, true ], [ /^/, true ], [ /^<\?/, /\?>/, true ], @@ -18,9 +18,8 @@ var HTML_SEQUENCES = [ export default function html_block(state, startLine, endLine, silent) { - var i, nextLine, token, lineText, - pos = state.bMarks[startLine] + state.tShift[startLine], - max = state.eMarks[startLine]; + let pos = state.bMarks[startLine] + state.tShift[startLine]; + let max = state.eMarks[startLine]; // if it's indented more than 3 spaces, it should be a code block if (state.sCount[startLine] - state.blkIndent >= 4) { return false; } @@ -29,12 +28,12 @@ export default function html_block(state, startLine, endLine, silent) { if (state.src.charCodeAt(pos) !== 0x3C/* < */) { return false; } - lineText = state.src.slice(pos, max); + let lineText = state.src.slice(pos, max); - for (i = 0; i < HTML_SEQUENCES.length; i++) { + let i = 0; + for (; i < HTML_SEQUENCES.length; i++) { if (HTML_SEQUENCES[i][0].test(lineText)) { break; } } - if (i === HTML_SEQUENCES.length) { return false; } if (silent) { @@ -42,7 +41,7 @@ export default function html_block(state, startLine, endLine, silent) { return HTML_SEQUENCES[i][2]; } - nextLine = startLine + 1; + let nextLine = startLine + 1; // If we are here - we detected HTML block. // Let's roll down till block end. @@ -63,7 +62,7 @@ export default function html_block(state, startLine, endLine, silent) { state.line = nextLine; - token = state.push('html_block', '', 0); + const token = state.push('html_block', '', 0); token.map = [ startLine, nextLine ]; token.content = state.getLines(startLine, nextLine, state.blkIndent, true); diff --git a/lib/rules_block/lheading.mjs b/lib/rules_block/lheading.mjs index aa532e2..8984c11 100644 --- a/lib/rules_block/lheading.mjs +++ b/lib/rules_block/lheading.mjs @@ -1,17 +1,19 @@ // lheading (---, ===) export default function lheading(state, startLine, endLine/*, silent*/) { - var content, terminate, i, l, token, pos, max, level, marker, - nextLine = startLine + 1, oldParentType, - terminatorRules = state.md.block.ruler.getRules('paragraph'); + const terminatorRules = state.md.block.ruler.getRules('paragraph'); // if it's indented more than 3 spaces, it should be a code block if (state.sCount[startLine] - state.blkIndent >= 4) { return false; } - oldParentType = state.parentType; + const oldParentType = state.parentType; state.parentType = 'paragraph'; // use paragraph to match terminatorRules // jump line-by-line until empty one or EOF + let level = 0; + let marker; + let nextLine = startLine + 1; + for (; nextLine < endLine && !state.isEmpty(nextLine); nextLine++) { // this would be a code block normally, but after paragraph // it's considered a lazy continuation regardless of what's there @@ -21,8 +23,8 @@ export default function lheading(state, startLine, endLine/*, silent*/) { // Check for underline in setext header // if (state.sCount[nextLine] >= state.blkIndent) { - pos = state.bMarks[nextLine] + state.tShift[nextLine]; - max = state.eMarks[nextLine]; + let pos = state.bMarks[nextLine] + state.tShift[nextLine]; + const max = state.eMarks[nextLine]; if (pos < max) { marker = state.src.charCodeAt(pos); @@ -43,8 +45,8 @@ export default function lheading(state, startLine, endLine/*, silent*/) { if (state.sCount[nextLine] < 0) { continue; } // Some tags can terminate paragraph without empty line. - terminate = false; - for (i = 0, l = terminatorRules.length; i < l; i++) { + let terminate = false; + for (let i = 0, l = terminatorRules.length; i < l; i++) { if (terminatorRules[i](state, nextLine, endLine, true)) { terminate = true; break; @@ -58,21 +60,21 @@ export default function lheading(state, startLine, endLine/*, silent*/) { return false; } - content = state.getLines(startLine, nextLine, state.blkIndent, false).trim(); + const content = state.getLines(startLine, nextLine, state.blkIndent, false).trim(); state.line = nextLine + 1; - token = state.push('heading_open', 'h' + String(level), 1); - token.markup = String.fromCharCode(marker); - token.map = [ startLine, state.line ]; + const token_o = state.push('heading_open', 'h' + String(level), 1); + token_o.markup = String.fromCharCode(marker); + token_o.map = [ startLine, state.line ]; - token = state.push('inline', '', 0); - token.content = content; - token.map = [ startLine, state.line - 1 ]; - token.children = []; + const token_i = state.push('inline', '', 0); + token_i.content = content; + token_i.map = [ startLine, state.line - 1 ]; + token_i.children = []; - token = state.push('heading_close', 'h' + String(level), -1); - token.markup = String.fromCharCode(marker); + const token_c = state.push('heading_close', 'h' + String(level), -1); + token_c.markup = String.fromCharCode(marker); state.parentType = oldParentType; diff --git a/lib/rules_block/list.mjs b/lib/rules_block/list.mjs index aa101c3..61da6f1 100644 --- a/lib/rules_block/list.mjs +++ b/lib/rules_block/list.mjs @@ -5,12 +5,10 @@ import { isSpace } from '../common/utils.mjs'; // Search `[-+*][\n ]`, returns next pos after marker on success // or -1 on fail. function skipBulletListMarker(state, startLine) { - var marker, pos, max, ch; + const max = state.eMarks[startLine]; + let pos = state.bMarks[startLine] + state.tShift[startLine]; - pos = state.bMarks[startLine] + state.tShift[startLine]; - max = state.eMarks[startLine]; - - marker = state.src.charCodeAt(pos++); + const marker = state.src.charCodeAt(pos++); // Check bullet if (marker !== 0x2A/* * */ && marker !== 0x2D/* - */ && @@ -19,7 +17,7 @@ function skipBulletListMarker(state, startLine) { } if (pos < max) { - ch = state.src.charCodeAt(pos); + const ch = state.src.charCodeAt(pos); if (!isSpace(ch)) { // " -test " - is not a list item @@ -33,15 +31,14 @@ function skipBulletListMarker(state, startLine) { // Search `\d+[.)][\n ]`, returns next pos after marker on success // or -1 on fail. function skipOrderedListMarker(state, startLine) { - var ch, - start = state.bMarks[startLine] + state.tShift[startLine], - pos = start, - max = state.eMarks[startLine]; + const start = state.bMarks[startLine] + state.tShift[startLine]; + const max = state.eMarks[startLine]; + let pos = start; // List marker should have at least 2 chars (digit + dot) if (pos + 1 >= max) { return -1; } - ch = state.src.charCodeAt(pos++); + let ch = state.src.charCodeAt(pos++); if (ch < 0x30/* 0 */ || ch > 0x39/* 9 */) { return -1; } @@ -68,7 +65,6 @@ function skipOrderedListMarker(state, startLine) { return -1; } - if (pos < max) { ch = state.src.charCodeAt(pos); @@ -81,10 +77,9 @@ function skipOrderedListMarker(state, startLine) { } function markTightParagraphs(state, idx) { - var i, l, - level = state.level + 2; + const level = state.level + 2; - for (i = idx + 2, l = state.tokens.length - 2; i < l; i++) { + for (let i = idx + 2, l = state.tokens.length - 2; i < l; i++) { if (state.tokens[i].level === level && state.tokens[i].type === 'paragraph_open') { state.tokens[i + 2].hidden = true; state.tokens[i].hidden = true; @@ -95,36 +90,13 @@ function markTightParagraphs(state, idx) { export default function list(state, startLine, endLine, silent) { - var ch, - contentStart, - i, - indent, - indentAfterMarker, - initial, - isOrdered, - itemLines, - l, - listLines, - listTokIdx, - markerCharCode, - markerValue, - max, - offset, - oldListIndent, - oldParentType, - oldSCount, - oldTShift, - oldTight, + let max, pos, - posAfterMarker, - prevEmptyEnd, start, - terminate, - terminatorRules, - token, - nextLine = startLine, - isTerminatingParagraph = false, - tight = true; + token; + + let nextLine = startLine; + let tight = true; // if it's indented more than 3 spaces, it should be a code block if (state.sCount[nextLine] - state.blkIndent >= 4) { return false; } @@ -141,6 +113,8 @@ export default function list(state, startLine, endLine, silent) { return false; } + let isTerminatingParagraph = false; + // limit conditions when list can interrupt // a paragraph (validation mode only) if (silent && state.parentType === 'paragraph') { @@ -155,6 +129,9 @@ export default function list(state, startLine, endLine, silent) { } // Detect list type and position after marker + let isOrdered; + let markerValue; + let posAfterMarker; if ((posAfterMarker = skipOrderedListMarker(state, nextLine)) >= 0) { isOrdered = true; start = state.bMarks[nextLine] + state.tShift[nextLine]; @@ -181,10 +158,10 @@ export default function list(state, startLine, endLine, silent) { if (silent) { return true; } // We should terminate list on style change. Remember first one to compare. - markerCharCode = state.src.charCodeAt(posAfterMarker - 1); + const markerCharCode = state.src.charCodeAt(posAfterMarker - 1); // Start list - listTokIdx = state.tokens.length; + const listTokIdx = state.tokens.length; if (isOrdered) { token = state.push('ordered_list_open', 'ol', 1); @@ -196,27 +173,29 @@ export default function list(state, startLine, endLine, silent) { token = state.push('bullet_list_open', 'ul', 1); } - token.map = listLines = [ nextLine, 0 ]; + const listLines = [ nextLine, 0 ]; + token.map = listLines; token.markup = String.fromCharCode(markerCharCode); // // Iterate list items // - prevEmptyEnd = false; - terminatorRules = state.md.block.ruler.getRules('list'); + let prevEmptyEnd = false; + const terminatorRules = state.md.block.ruler.getRules('list'); - oldParentType = state.parentType; + const oldParentType = state.parentType; state.parentType = 'list'; while (nextLine < endLine) { pos = posAfterMarker; max = state.eMarks[nextLine]; - initial = offset = state.sCount[nextLine] + posAfterMarker - (state.bMarks[nextLine] + state.tShift[nextLine]); + const initial = state.sCount[nextLine] + posAfterMarker - (state.bMarks[nextLine] + state.tShift[nextLine]); + let offset = initial; while (pos < max) { - ch = state.src.charCodeAt(pos); + const ch = state.src.charCodeAt(pos); if (ch === 0x09) { offset += 4 - (offset + state.bsCount[nextLine]) % 4; @@ -229,7 +208,8 @@ export default function list(state, startLine, endLine, silent) { pos++; } - contentStart = pos; + const contentStart = pos; + let indentAfterMarker; if (contentStart >= max) { // trimming space in "- \n 3" case, indent is 1 here @@ -244,26 +224,27 @@ export default function list(state, startLine, endLine, silent) { // " - test" // ^^^^^ - calculating total length of this thing - indent = initial + indentAfterMarker; + const indent = initial + indentAfterMarker; // Run subparser & write tokens token = state.push('list_item_open', 'li', 1); token.markup = String.fromCharCode(markerCharCode); - token.map = itemLines = [ nextLine, 0 ]; + const itemLines = [ nextLine, 0 ]; + token.map = itemLines; if (isOrdered) { token.info = state.src.slice(start, posAfterMarker - 1); } // change current state, then restore it after parser subcall - oldTight = state.tight; - oldTShift = state.tShift[nextLine]; - oldSCount = state.sCount[nextLine]; + const oldTight = state.tight; + const oldTShift = state.tShift[nextLine]; + const oldSCount = state.sCount[nextLine]; // - example list // ^ listIndent position will be here // ^ blkIndent position will be here // - oldListIndent = state.listIndent; + const oldListIndent = state.listIndent; state.listIndent = state.blkIndent; state.blkIndent = indent; @@ -315,8 +296,8 @@ export default function list(state, startLine, endLine, silent) { if (state.sCount[nextLine] - state.blkIndent >= 4) { break; } // fail if terminating block found - terminate = false; - for (i = 0, l = terminatorRules.length; i < l; i++) { + let terminate = false; + for (let i = 0, l = terminatorRules.length; i < l; i++) { if (terminatorRules[i](state, nextLine, endLine, true)) { terminate = true; break; diff --git a/lib/rules_block/paragraph.mjs b/lib/rules_block/paragraph.mjs index 5f6e1b2..462b07c 100644 --- a/lib/rules_block/paragraph.mjs +++ b/lib/rules_block/paragraph.mjs @@ -1,11 +1,9 @@ // Paragraph export default function paragraph(state, startLine, endLine) { - var content, terminate, i, l, token, oldParentType, - nextLine = startLine + 1, - terminatorRules = state.md.block.ruler.getRules('paragraph'); - - oldParentType = state.parentType; + const terminatorRules = state.md.block.ruler.getRules('paragraph'); + const oldParentType = state.parentType; + let nextLine = startLine + 1; state.parentType = 'paragraph'; // jump line-by-line until empty one or EOF @@ -18,8 +16,8 @@ export default function paragraph(state, startLine, endLine) { if (state.sCount[nextLine] < 0) { continue; } // Some tags can terminate paragraph without empty line. - terminate = false; - for (i = 0, l = terminatorRules.length; i < l; i++) { + let terminate = false; + for (let i = 0, l = terminatorRules.length; i < l; i++) { if (terminatorRules[i](state, nextLine, endLine, true)) { terminate = true; break; @@ -28,19 +26,19 @@ export default function paragraph(state, startLine, endLine) { if (terminate) { break; } } - content = state.getLines(startLine, nextLine, state.blkIndent, false).trim(); + const content = state.getLines(startLine, nextLine, state.blkIndent, false).trim(); state.line = nextLine; - token = state.push('paragraph_open', 'p', 1); - token.map = [ startLine, state.line ]; + const token_o = state.push('paragraph_open', 'p', 1); + token_o.map = [ startLine, state.line ]; - token = state.push('inline', '', 0); - token.content = content; - token.map = [ startLine, state.line ]; - token.children = []; + const token_i = state.push('inline', '', 0); + token_i.content = content; + token_i.map = [ startLine, state.line ]; + token_i.children = []; - token = state.push('paragraph_close', 'p', -1); + state.push('paragraph_close', 'p', -1); state.parentType = oldParentType; diff --git a/lib/rules_block/reference.mjs b/lib/rules_block/reference.mjs index 9ba5e3c..7bab1d9 100644 --- a/lib/rules_block/reference.mjs +++ b/lib/rules_block/reference.mjs @@ -1,26 +1,11 @@ import { isSpace, normalizeReference } from '../common/utils.mjs'; export default function reference(state, startLine, _endLine, silent) { - var ch, - destEndPos, - destEndLineNo, - endLine, - href, - i, - l, - label, - labelEnd, - oldParentType, - res, - start, - str, - terminate, - terminatorRules, - title, - lines = 0, - pos = state.bMarks[startLine] + state.tShift[startLine], - max = state.eMarks[startLine], - nextLine = startLine + 1; + let lines = 0; + + let pos = state.bMarks[startLine] + state.tShift[startLine]; + let max = state.eMarks[startLine]; + let nextLine = startLine + 1; // if it's indented more than 3 spaces, it should be a code block if (state.sCount[startLine] - state.blkIndent >= 4) { return false; } @@ -38,12 +23,12 @@ export default function reference(state, startLine, _endLine, silent) { } } - endLine = state.lineMax; + const endLine = state.lineMax; // jump line-by-line until empty one or EOF - terminatorRules = state.md.block.ruler.getRules('reference'); + const terminatorRules = state.md.block.ruler.getRules('reference'); - oldParentType = state.parentType; + const oldParentType = state.parentType; state.parentType = 'reference'; for (; nextLine < endLine && !state.isEmpty(nextLine); nextLine++) { @@ -55,8 +40,8 @@ export default function reference(state, startLine, _endLine, silent) { if (state.sCount[nextLine] < 0) { continue; } // Some tags can terminate paragraph without empty line. - terminate = false; - for (i = 0, l = terminatorRules.length; i < l; i++) { + let terminate = false; + for (let i = 0, l = terminatorRules.length; i < l; i++) { if (terminatorRules[i](state, nextLine, endLine, true)) { terminate = true; break; @@ -65,11 +50,12 @@ export default function reference(state, startLine, _endLine, silent) { if (terminate) { break; } } - str = state.getLines(startLine, nextLine, state.blkIndent, false).trim(); + const str = state.getLines(startLine, nextLine, state.blkIndent, false).trim(); max = str.length; + let labelEnd = -1; for (pos = 1; pos < max; pos++) { - ch = str.charCodeAt(pos); + const ch = str.charCodeAt(pos); if (ch === 0x5B /* [ */) { return false; } else if (ch === 0x5D /* ] */) { @@ -90,7 +76,7 @@ export default function reference(state, startLine, _endLine, silent) { // [label]: destination 'title' // ^^^ skip optional whitespace here for (pos = labelEnd + 2; pos < max; pos++) { - ch = str.charCodeAt(pos); + const ch = str.charCodeAt(pos); if (ch === 0x0A) { lines++; } else if (isSpace(ch)) { @@ -102,24 +88,24 @@ export default function reference(state, startLine, _endLine, silent) { // [label]: destination 'title' // ^^^^^^^^^^^ parse this - res = state.md.helpers.parseLinkDestination(str, pos, max); - if (!res.ok) { return false; } + const destRes = state.md.helpers.parseLinkDestination(str, pos, max); + if (!destRes.ok) { return false; } - href = state.md.normalizeLink(res.str); + const href = state.md.normalizeLink(destRes.str); if (!state.md.validateLink(href)) { return false; } - pos = res.pos; - lines += res.lines; + pos = destRes.pos; + lines += destRes.lines; // save cursor state, we could require to rollback later - destEndPos = pos; - destEndLineNo = lines; + const destEndPos = pos; + const destEndLineNo = lines; // [label]: destination 'title' // ^^^ skipping those spaces - start = pos; + const start = pos; for (; pos < max; pos++) { - ch = str.charCodeAt(pos); + const ch = str.charCodeAt(pos); if (ch === 0x0A) { lines++; } else if (isSpace(ch)) { @@ -131,11 +117,13 @@ export default function reference(state, startLine, _endLine, silent) { // [label]: destination 'title' // ^^^^^^^ parse this - res = state.md.helpers.parseLinkTitle(str, pos, max); - if (pos < max && start !== pos && res.ok) { - title = res.str; - pos = res.pos; - lines += res.lines; + const titleRes = state.md.helpers.parseLinkTitle(str, pos, max); + let title; + + if (pos < max && start !== pos && titleRes.ok) { + title = titleRes.str; + pos = titleRes.pos; + lines += titleRes.lines; } else { title = ''; pos = destEndPos; @@ -144,7 +132,7 @@ export default function reference(state, startLine, _endLine, silent) { // skip trailing spaces until the rest of the line while (pos < max) { - ch = str.charCodeAt(pos); + const ch = str.charCodeAt(pos); if (!isSpace(ch)) { break; } pos++; } @@ -157,7 +145,7 @@ export default function reference(state, startLine, _endLine, silent) { pos = destEndPos; lines = destEndLineNo; while (pos < max) { - ch = str.charCodeAt(pos); + const ch = str.charCodeAt(pos); if (!isSpace(ch)) { break; } pos++; } @@ -169,7 +157,7 @@ export default function reference(state, startLine, _endLine, silent) { return false; } - label = normalizeReference(str.slice(1, labelEnd)); + const label = normalizeReference(str.slice(1, labelEnd)); if (!label) { // CommonMark 0.20 disallows empty labels return false; diff --git a/lib/rules_block/state_block.mjs b/lib/rules_block/state_block.mjs index 5a5dcb3..728770c 100644 --- a/lib/rules_block/state_block.mjs +++ b/lib/rules_block/state_block.mjs @@ -5,8 +5,6 @@ import { isSpace } from '../common/utils.mjs'; function StateBlock(src, md, env, tokens) { - var ch, s, start, pos, len, indent, offset, indent_found; - this.src = src; // link to parser instance @@ -54,11 +52,10 @@ function StateBlock(src, md, env, tokens) { // Create caches // Generate markers. - s = this.src; - indent_found = false; + const s = this.src; - for (start = pos = indent = offset = 0, len = s.length; pos < len; pos++) { - ch = s.charCodeAt(pos); + for (let start = 0, pos = 0, indent = 0, offset = 0, len = s.length, indent_found = false; pos < len; pos++) { + const ch = s.charCodeAt(pos); if (!indent_found) { if (isSpace(ch)) { @@ -103,7 +100,7 @@ function StateBlock(src, md, env, tokens) { // Push new token to "stream". // StateBlock.prototype.push = function (type, tag, nesting) { - var token = new Token(type, tag, nesting); + const token = new Token(type, tag, nesting); token.block = true; if (nesting < 0) this.level--; // closing tag @@ -119,7 +116,7 @@ StateBlock.prototype.isEmpty = function isEmpty(line) { }; StateBlock.prototype.skipEmptyLines = function skipEmptyLines(from) { - for (var max = this.lineMax; from < max; from++) { + for (let max = this.lineMax; from < max; from++) { if (this.bMarks[from] + this.tShift[from] < this.eMarks[from]) { break; } @@ -129,10 +126,8 @@ StateBlock.prototype.skipEmptyLines = function skipEmptyLines(from) { // Skip spaces from given position. StateBlock.prototype.skipSpaces = function skipSpaces(pos) { - var ch; - - for (var max = this.src.length; pos < max; pos++) { - ch = this.src.charCodeAt(pos); + for (let max = this.src.length; pos < max; pos++) { + const ch = this.src.charCodeAt(pos); if (!isSpace(ch)) { break; } } return pos; @@ -150,7 +145,7 @@ StateBlock.prototype.skipSpacesBack = function skipSpacesBack(pos, min) { // Skip char codes from given position StateBlock.prototype.skipChars = function skipChars(pos, code) { - for (var max = this.src.length; pos < max; pos++) { + for (let max = this.src.length; pos < max; pos++) { if (this.src.charCodeAt(pos) !== code) { break; } } return pos; @@ -168,18 +163,17 @@ StateBlock.prototype.skipCharsBack = function skipCharsBack(pos, code, min) { // cut lines range from source. StateBlock.prototype.getLines = function getLines(begin, end, indent, keepLastLF) { - var i, lineIndent, ch, first, last, queue, lineStart, - line = begin; - if (begin >= end) { return ''; } - queue = new Array(end - begin); + const queue = new Array(end - begin); - for (i = 0; line < end; line++, i++) { - lineIndent = 0; - lineStart = first = this.bMarks[line]; + for (let i = 0, line = begin; line < end; line++, i++) { + let lineIndent = 0; + const lineStart = this.bMarks[line]; + let first = lineStart; + let last; if (line + 1 < end || keepLastLF) { // No need for bounds check because we have fake entry on tail. @@ -189,7 +183,7 @@ StateBlock.prototype.getLines = function getLines(begin, end, indent, keepLastLF } while (first < last && lineIndent < indent) { - ch = this.src.charCodeAt(first); + const ch = this.src.charCodeAt(first); if (isSpace(ch)) { if (ch === 0x09) { diff --git a/lib/rules_block/table.mjs b/lib/rules_block/table.mjs index 88d4b45..5907f8c 100644 --- a/lib/rules_block/table.mjs +++ b/lib/rules_block/table.mjs @@ -3,22 +3,21 @@ import { isSpace } from '../common/utils.mjs'; function getLine(state, line) { - var pos = state.bMarks[line] + state.tShift[line], - max = state.eMarks[line]; + const pos = state.bMarks[line] + state.tShift[line], + max = state.eMarks[line]; return state.src.slice(pos, max); } function escapedSplit(str) { - var result = [], - pos = 0, - max = str.length, - ch, - isEscaped = false, - lastPos = 0, - current = ''; + const result = []; + const max = str.length; - ch = str.charCodeAt(pos); + let pos = 0; + let ch = str.charCodeAt(pos); + let isEscaped = false; + let lastPos = 0; + let current = ''; while (pos < max) { if (ch === 0x7c/* | */) { @@ -47,14 +46,10 @@ function escapedSplit(str) { export default function table(state, startLine, endLine, silent) { - var ch, lineText, pos, i, l, nextLine, columns, columnCount, token, - aligns, t, tableLines, tbodyLines, oldParentType, terminate, - terminatorRules, firstCh, secondCh; - // should have at least two lines if (startLine + 2 > endLine) { return false; } - nextLine = startLine + 1; + let nextLine = startLine + 1; if (state.sCount[nextLine] < state.blkIndent) { return false; } @@ -65,15 +60,15 @@ export default function table(state, startLine, endLine, silent) { // and no other characters are allowed but spaces; // basically, this is the equivalent of /^[-:|][-:|\s]*$/ regexp - pos = state.bMarks[nextLine] + state.tShift[nextLine]; + let pos = state.bMarks[nextLine] + state.tShift[nextLine]; if (pos >= state.eMarks[nextLine]) { return false; } - firstCh = state.src.charCodeAt(pos++); + const firstCh = state.src.charCodeAt(pos++); if (firstCh !== 0x7C/* | */ && firstCh !== 0x2D/* - */ && firstCh !== 0x3A/* : */) { return false; } if (pos >= state.eMarks[nextLine]) { return false; } - secondCh = state.src.charCodeAt(pos++); + const secondCh = state.src.charCodeAt(pos++); if (secondCh !== 0x7C/* | */ && secondCh !== 0x2D/* - */ && secondCh !== 0x3A/* : */ && !isSpace(secondCh)) { return false; } @@ -83,19 +78,18 @@ export default function table(state, startLine, endLine, silent) { if (firstCh === 0x2D/* - */ && isSpace(secondCh)) { return false; } while (pos < state.eMarks[nextLine]) { - ch = state.src.charCodeAt(pos); + const ch = state.src.charCodeAt(pos); if (ch !== 0x7C/* | */ && ch !== 0x2D/* - */ && ch !== 0x3A/* : */ && !isSpace(ch)) { return false; } pos++; } - lineText = getLine(state, startLine + 1); - - columns = lineText.split('|'); - aligns = []; - for (i = 0; i < columns.length; i++) { - t = columns[i].trim(); + let lineText = getLine(state, startLine + 1); + let columns = lineText.split('|'); + const aligns = []; + for (let i = 0; i < columns.length; i++) { + const t = columns[i].trim(); if (!t) { // allow empty columns before and after table, but not in between columns; // e.g. allow ` |---| `, disallow ` ---||--- ` @@ -125,48 +119,51 @@ export default function table(state, startLine, endLine, silent) { // header row will define an amount of columns in the entire table, // and align row should be exactly the same (the rest of the rows can differ) - columnCount = columns.length; + const columnCount = columns.length; if (columnCount === 0 || columnCount !== aligns.length) { return false; } if (silent) { return true; } - oldParentType = state.parentType; + const oldParentType = state.parentType; state.parentType = 'table'; // use 'blockquote' lists for termination because it's // the most similar to tables - terminatorRules = state.md.block.ruler.getRules('blockquote'); + const terminatorRules = state.md.block.ruler.getRules('blockquote'); - token = state.push('table_open', 'table', 1); - token.map = tableLines = [ startLine, 0 ]; + const token_to = state.push('table_open', 'table', 1); + const tableLines = [ startLine, 0 ]; + token_to.map = tableLines; - token = state.push('thead_open', 'thead', 1); - token.map = [ startLine, startLine + 1 ]; + const token_tho = state.push('thead_open', 'thead', 1); + token_tho.map = [ startLine, startLine + 1 ]; - token = state.push('tr_open', 'tr', 1); - token.map = [ startLine, startLine + 1 ]; + const token_htro = state.push('tr_open', 'tr', 1); + token_htro.map = [ startLine, startLine + 1 ]; - for (i = 0; i < columns.length; i++) { - token = state.push('th_open', 'th', 1); + for (let i = 0; i < columns.length; i++) { + const token_ho = state.push('th_open', 'th', 1); if (aligns[i]) { - token.attrs = [ [ 'style', 'text-align:' + aligns[i] ] ]; + token_ho.attrs = [ [ 'style', 'text-align:' + aligns[i] ] ]; } - token = state.push('inline', '', 0); - token.content = columns[i].trim(); - token.children = []; + const token_il = state.push('inline', '', 0); + token_il.content = columns[i].trim(); + token_il.children = []; - token = state.push('th_close', 'th', -1); + state.push('th_close', 'th', -1); } - token = state.push('tr_close', 'tr', -1); - token = state.push('thead_close', 'thead', -1); + state.push('tr_close', 'tr', -1); + state.push('thead_close', 'thead', -1); + + let tbodyLines; for (nextLine = startLine + 2; nextLine < endLine; nextLine++) { if (state.sCount[nextLine] < state.blkIndent) { break; } - terminate = false; - for (i = 0, l = terminatorRules.length; i < l; i++) { + let terminate = false; + for (let i = 0, l = terminatorRules.length; i < l; i++) { if (terminatorRules[i](state, nextLine, endLine, true)) { terminate = true; break; @@ -182,34 +179,34 @@ export default function table(state, startLine, endLine, silent) { if (columns.length && columns[columns.length - 1] === '') columns.pop(); if (nextLine === startLine + 2) { - token = state.push('tbody_open', 'tbody', 1); - token.map = tbodyLines = [ startLine + 2, 0 ]; + const token_tbo = state.push('tbody_open', 'tbody', 1); + token_tbo.map = tbodyLines = [ startLine + 2, 0 ]; } - token = state.push('tr_open', 'tr', 1); - token.map = [ nextLine, nextLine + 1 ]; + const token_tro = state.push('tr_open', 'tr', 1); + token_tro.map = [ nextLine, nextLine + 1 ]; - for (i = 0; i < columnCount; i++) { - token = state.push('td_open', 'td', 1); + for (let i = 0; i < columnCount; i++) { + const token_tdo = state.push('td_open', 'td', 1); if (aligns[i]) { - token.attrs = [ [ 'style', 'text-align:' + aligns[i] ] ]; + token_tdo.attrs = [ [ 'style', 'text-align:' + aligns[i] ] ]; } - token = state.push('inline', '', 0); - token.content = columns[i] ? columns[i].trim() : ''; - token.children = []; + const token_il = state.push('inline', '', 0); + token_il.content = columns[i] ? columns[i].trim() : ''; + token_il.children = []; - token = state.push('td_close', 'td', -1); + state.push('td_close', 'td', -1); } - token = state.push('tr_close', 'tr', -1); + state.push('tr_close', 'tr', -1); } if (tbodyLines) { - token = state.push('tbody_close', 'tbody', -1); + state.push('tbody_close', 'tbody', -1); tbodyLines[1] = nextLine; } - token = state.push('table_close', 'table', -1); + state.push('table_close', 'table', -1); tableLines[1] = nextLine; state.parentType = oldParentType; diff --git a/lib/rules_core/block.mjs b/lib/rules_core/block.mjs index 62fa0bb..13d41e3 100644 --- a/lib/rules_core/block.mjs +++ b/lib/rules_core/block.mjs @@ -1,5 +1,5 @@ export default function block(state) { - var token; + let token; if (state.inlineMode) { token = new state.Token('inline', '', 0); diff --git a/lib/rules_core/inline.mjs b/lib/rules_core/inline.mjs index 5c00ef0..c74ba8e 100644 --- a/lib/rules_core/inline.mjs +++ b/lib/rules_core/inline.mjs @@ -1,9 +1,9 @@ export default function inline(state) { - var tokens = state.tokens, tok, i, l; + const tokens = state.tokens; // Parse inlines - for (i = 0, l = tokens.length; i < l; i++) { - tok = tokens[i]; + for (let i = 0, l = tokens.length; i < l; i++) { + const tok = tokens[i]; if (tok.type === 'inline') { state.md.inline.parse(tok.content, state.md, state.env, tok.children); } diff --git a/lib/rules_core/linkify.mjs b/lib/rules_core/linkify.mjs index 8d1e265..2912f18 100644 --- a/lib/rules_core/linkify.mjs +++ b/lib/rules_core/linkify.mjs @@ -15,27 +15,24 @@ function isLinkClose(str) { export default function linkify(state) { - var i, j, l, tokens, token, currentToken, nodes, ln, text, pos, lastPos, - level, htmlLinkLevel, url, fullUrl, urlText, - blockTokens = state.tokens, - links; + const blockTokens = state.tokens; if (!state.md.options.linkify) { return; } - for (j = 0, l = blockTokens.length; j < l; j++) { + for (let j = 0, l = blockTokens.length; j < l; j++) { if (blockTokens[j].type !== 'inline' || !state.md.linkify.pretest(blockTokens[j].content)) { continue; } - tokens = blockTokens[j].children; + let tokens = blockTokens[j].children; - htmlLinkLevel = 0; + let htmlLinkLevel = 0; // We scan from the end, to keep position when new tags added. // Use reversed logic in links start/end match - for (i = tokens.length - 1; i >= 0; i--) { - currentToken = tokens[i]; + for (let i = tokens.length - 1; i >= 0; i--) { + const currentToken = tokens[i]; // Skip content of markdown links if (currentToken.type === 'link_close') { @@ -59,13 +56,13 @@ export default function linkify(state) { if (currentToken.type === 'text' && state.md.linkify.test(currentToken.content)) { - text = currentToken.content; - links = state.md.linkify.match(text); + const text = currentToken.content; + let links = state.md.linkify.match(text); // Now split string to nodes - nodes = []; - level = currentToken.level; - lastPos = 0; + const nodes = []; + let level = currentToken.level; + let lastPos = 0; // forbid escape sequence at the start of the string, // this avoids http\://example.com/ from being linkified as @@ -77,12 +74,12 @@ export default function linkify(state) { links = links.slice(1); } - for (ln = 0; ln < links.length; ln++) { - url = links[ln].url; - fullUrl = state.md.normalizeLink(url); + for (let ln = 0; ln < links.length; ln++) { + const url = links[ln].url; + const fullUrl = state.md.normalizeLink(url); if (!state.md.validateLink(fullUrl)) { continue; } - urlText = links[ln].text; + let urlText = links[ln].text; // Linkifier might send raw hostnames like "example.com", where url // starts with domain name. So we prepend http:// in those cases, @@ -96,37 +93,37 @@ export default function linkify(state) { urlText = state.md.normalizeLinkText(urlText); } - pos = links[ln].index; + const pos = links[ln].index; if (pos > lastPos) { - token = new state.Token('text', '', 0); + const token = new state.Token('text', '', 0); token.content = text.slice(lastPos, pos); token.level = level; nodes.push(token); } - token = new state.Token('link_open', 'a', 1); - token.attrs = [ [ 'href', fullUrl ] ]; - token.level = level++; - token.markup = 'linkify'; - token.info = 'auto'; - nodes.push(token); + const token_o = new state.Token('link_open', 'a', 1); + token_o.attrs = [ [ 'href', fullUrl ] ]; + token_o.level = level++; + token_o.markup = 'linkify'; + token_o.info = 'auto'; + nodes.push(token_o); - token = new state.Token('text', '', 0); - token.content = urlText; - token.level = level; - nodes.push(token); + const token_t = new state.Token('text', '', 0); + token_t.content = urlText; + token_t.level = level; + nodes.push(token_t); - token = new state.Token('link_close', 'a', -1); - token.level = --level; - token.markup = 'linkify'; - token.info = 'auto'; - nodes.push(token); + const token_c = new state.Token('link_close', 'a', -1); + token_c.level = --level; + token_c.markup = 'linkify'; + token_c.info = 'auto'; + nodes.push(token_c); lastPos = links[ln].lastIndex; } if (lastPos < text.length) { - token = new state.Token('text', '', 0); + const token = new state.Token('text', '', 0); token.content = text.slice(lastPos); token.level = level; nodes.push(token); diff --git a/lib/rules_core/normalize.mjs b/lib/rules_core/normalize.mjs index 64b68e0..6db69cd 100644 --- a/lib/rules_core/normalize.mjs +++ b/lib/rules_core/normalize.mjs @@ -2,12 +2,12 @@ // https://spec.commonmark.org/0.29/#line-ending -var NEWLINES_RE = /\r\n?|\n/g; -var NULL_RE = /\0/g; +const NEWLINES_RE = /\r\n?|\n/g; +const NULL_RE = /\0/g; export default function normalize(state) { - var str; + let str; // Normalize newlines str = state.src.replace(NEWLINES_RE, '\n'); diff --git a/lib/rules_core/replacements.mjs b/lib/rules_core/replacements.mjs index e41a6f4..a07b7c9 100644 --- a/lib/rules_core/replacements.mjs +++ b/lib/rules_core/replacements.mjs @@ -13,14 +13,14 @@ // - fractionals 1/2, 1/4, 3/4 -> ½, ¼, ¾ // - multiplications 2 x 4 -> 2 × 4 -var RARE_RE = /\+-|\.\.|\?\?\?\?|!!!!|,,|--/; +const RARE_RE = /\+-|\.\.|\?\?\?\?|!!!!|,,|--/; // Workaround for phantomjs - need regex without /g flag, // or root check will fail every second time -var SCOPED_ABBR_TEST_RE = /\((c|tm|r)\)/i; +const SCOPED_ABBR_TEST_RE = /\((c|tm|r)\)/i; -var SCOPED_ABBR_RE = /\((c|tm|r)\)/ig; -var SCOPED_ABBR = { +const SCOPED_ABBR_RE = /\((c|tm|r)\)/ig; +const SCOPED_ABBR = { c: '©', r: '®', tm: '™' @@ -31,7 +31,7 @@ function replaceFn(match, name) { } function replace_scoped(inlineTokens) { - var i, token, inside_autolink = 0; + let i, token, inside_autolink = 0; for (i = inlineTokens.length - 1; i >= 0; i--) { token = inlineTokens[i]; @@ -51,7 +51,7 @@ function replace_scoped(inlineTokens) { } function replace_rare(inlineTokens) { - var i, token, inside_autolink = 0; + let i, token, inside_autolink = 0; for (i = inlineTokens.length - 1; i >= 0; i--) { token = inlineTokens[i]; @@ -84,7 +84,7 @@ function replace_rare(inlineTokens) { export default function replace(state) { - var blkIdx; + let blkIdx; if (!state.md.options.typographer) { return; } diff --git a/lib/rules_core/smartquotes.mjs b/lib/rules_core/smartquotes.mjs index 45a7b12..35b7561 100644 --- a/lib/rules_core/smartquotes.mjs +++ b/lib/rules_core/smartquotes.mjs @@ -3,9 +3,9 @@ import { isWhiteSpace, isPunctChar, isMdAsciiPunct } from '../common/utils.mjs'; -var QUOTE_TEST_RE = /['"]/; -var QUOTE_RE = /['"]/g; -var APOSTROPHE = '\u2019'; /* ’ */ +const QUOTE_TEST_RE = /['"]/; +const QUOTE_RE = /['"]/g; +const APOSTROPHE = '\u2019'; /* ’ */ function replaceAt(str, index, ch) { @@ -13,16 +13,14 @@ function replaceAt(str, index, ch) { } function process_inlines(tokens, state) { - var i, token, text, t, pos, max, thisLevel, item, lastChar, nextChar, - isLastPunctChar, isNextPunctChar, isLastWhiteSpace, isNextWhiteSpace, - canOpen, canClose, j, isSingle, stack, openQuote, closeQuote; + let j; - stack = []; + const stack = []; - for (i = 0; i < tokens.length; i++) { - token = tokens[i]; + for (let i = 0; i < tokens.length; i++) { + const token = tokens[i]; - thisLevel = tokens[i].level; + const thisLevel = tokens[i].level; for (j = stack.length - 1; j >= 0; j--) { if (stack[j].level <= thisLevel) { break; } @@ -31,25 +29,26 @@ function process_inlines(tokens, state) { if (token.type !== 'text') { continue; } - text = token.content; - pos = 0; - max = text.length; + let text = token.content; + let pos = 0; + let max = text.length; /*eslint no-labels:0,block-scoped-var:0*/ OUTER: while (pos < max) { QUOTE_RE.lastIndex = pos; - t = QUOTE_RE.exec(text); + const t = QUOTE_RE.exec(text); if (!t) { break; } - canOpen = canClose = true; + let canOpen = true; + let canClose = true; pos = t.index + 1; - isSingle = (t[0] === "'"); + const isSingle = (t[0] === "'"); // Find previous character, // default to space if it's the beginning of the line // - lastChar = 0x20; + let lastChar = 0x20; if (t.index - 1 >= 0) { lastChar = text.charCodeAt(t.index - 1); @@ -66,7 +65,7 @@ function process_inlines(tokens, state) { // Find next character, // default to space if it's the end of the line // - nextChar = 0x20; + let nextChar = 0x20; if (pos < max) { nextChar = text.charCodeAt(pos); @@ -80,11 +79,11 @@ function process_inlines(tokens, state) { } } - isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctChar(String.fromCharCode(lastChar)); - isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctChar(String.fromCharCode(nextChar)); + const isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctChar(String.fromCharCode(lastChar)); + const isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctChar(String.fromCharCode(nextChar)); - isLastWhiteSpace = isWhiteSpace(lastChar); - isNextWhiteSpace = isWhiteSpace(nextChar); + const isLastWhiteSpace = isWhiteSpace(lastChar); + const isNextWhiteSpace = isWhiteSpace(nextChar); if (isNextWhiteSpace) { canOpen = false; @@ -132,11 +131,13 @@ function process_inlines(tokens, state) { if (canClose) { // this could be a closing quote, rewind the stack to get a match for (j = stack.length - 1; j >= 0; j--) { - item = stack[j]; + let item = stack[j]; if (stack[j].level < thisLevel) { break; } if (item.single === isSingle && stack[j].level === thisLevel) { item = stack[j]; + let openQuote; + let closeQuote; if (isSingle) { openQuote = state.md.options.quotes[2]; closeQuote = state.md.options.quotes[3]; @@ -181,11 +182,9 @@ function process_inlines(tokens, state) { export default function smartquotes(state) { /*eslint max-depth:0*/ - var blkIdx; - if (!state.md.options.typographer) { return; } - for (blkIdx = state.tokens.length - 1; blkIdx >= 0; blkIdx--) { + for (let blkIdx = state.tokens.length - 1; blkIdx >= 0; blkIdx--) { if (state.tokens[blkIdx].type !== 'inline' || !QUOTE_TEST_RE.test(state.tokens[blkIdx].content)) { diff --git a/lib/rules_core/text_join.mjs b/lib/rules_core/text_join.mjs index 83c245f..14de9e2 100644 --- a/lib/rules_core/text_join.mjs +++ b/lib/rules_core/text_join.mjs @@ -7,14 +7,15 @@ // export default function text_join(state) { - var j, l, tokens, curr, max, last, - blockTokens = state.tokens; + let curr, last; + const blockTokens = state.tokens; + const l = blockTokens.length; - for (j = 0, l = blockTokens.length; j < l; j++) { + for (let j = 0; j < l; j++) { if (blockTokens[j].type !== 'inline') continue; - tokens = blockTokens[j].children; - max = tokens.length; + const tokens = blockTokens[j].children; + const max = tokens.length; for (curr = 0; curr < max; curr++) { if (tokens[curr].type === 'text_special') { diff --git a/lib/rules_inline/autolink.mjs b/lib/rules_inline/autolink.mjs index ed16432..1035d13 100644 --- a/lib/rules_inline/autolink.mjs +++ b/lib/rules_inline/autolink.mjs @@ -1,46 +1,45 @@ // Process autolinks '' /*eslint max-len:0*/ -var EMAIL_RE = /^([a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)$/; -var AUTOLINK_RE = /^([a-zA-Z][a-zA-Z0-9+.\-]{1,31}):([^<>\x00-\x20]*)$/; +const EMAIL_RE = /^([a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)$/; +const AUTOLINK_RE = /^([a-zA-Z][a-zA-Z0-9+.\-]{1,31}):([^<>\x00-\x20]*)$/; export default function autolink(state, silent) { - var url, fullUrl, token, ch, start, max, - pos = state.pos; + let pos = state.pos; if (state.src.charCodeAt(pos) !== 0x3C/* < */) { return false; } - start = state.pos; - max = state.posMax; + const start = state.pos; + const max = state.posMax; for (;;) { if (++pos >= max) return false; - ch = state.src.charCodeAt(pos); + const ch = state.src.charCodeAt(pos); if (ch === 0x3C /* < */) return false; if (ch === 0x3E /* > */) break; } - url = state.src.slice(start + 1, pos); + const url = state.src.slice(start + 1, pos); if (AUTOLINK_RE.test(url)) { - fullUrl = state.md.normalizeLink(url); + const fullUrl = state.md.normalizeLink(url); if (!state.md.validateLink(fullUrl)) { return false; } if (!silent) { - token = state.push('link_open', 'a', 1); - token.attrs = [ [ 'href', fullUrl ] ]; - token.markup = 'autolink'; - token.info = 'auto'; + const token_o = state.push('link_open', 'a', 1); + token_o.attrs = [ [ 'href', fullUrl ] ]; + token_o.markup = 'autolink'; + token_o.info = 'auto'; - token = state.push('text', '', 0); - token.content = state.md.normalizeLinkText(url); + const token_t = state.push('text', '', 0); + token_t.content = state.md.normalizeLinkText(url); - token = state.push('link_close', 'a', -1); - token.markup = 'autolink'; - token.info = 'auto'; + const token_c = state.push('link_close', 'a', -1); + token_c.markup = 'autolink'; + token_c.info = 'auto'; } state.pos += url.length + 2; @@ -48,21 +47,21 @@ export default function autolink(state, silent) { } if (EMAIL_RE.test(url)) { - fullUrl = state.md.normalizeLink('mailto:' + url); + const fullUrl = state.md.normalizeLink('mailto:' + url); if (!state.md.validateLink(fullUrl)) { return false; } if (!silent) { - token = state.push('link_open', 'a', 1); - token.attrs = [ [ 'href', fullUrl ] ]; - token.markup = 'autolink'; - token.info = 'auto'; + const token_o = state.push('link_open', 'a', 1); + token_o.attrs = [ [ 'href', fullUrl ] ]; + token_o.markup = 'autolink'; + token_o.info = 'auto'; - token = state.push('text', '', 0); - token.content = state.md.normalizeLinkText(url); + const token_t = state.push('text', '', 0); + token_t.content = state.md.normalizeLinkText(url); - token = state.push('link_close', 'a', -1); - token.markup = 'autolink'; - token.info = 'auto'; + const token_c = state.push('link_close', 'a', -1); + token_c.markup = 'autolink'; + token_c.info = 'auto'; } state.pos += url.length + 2; diff --git a/lib/rules_inline/backticks.mjs b/lib/rules_inline/backticks.mjs index bbfdc55..2b6a910 100644 --- a/lib/rules_inline/backticks.mjs +++ b/lib/rules_inline/backticks.mjs @@ -1,21 +1,20 @@ // Parse backticks export default function backtick(state, silent) { - var start, max, marker, token, matchStart, matchEnd, openerLength, closerLength, - pos = state.pos, - ch = state.src.charCodeAt(pos); + let pos = state.pos; + const ch = state.src.charCodeAt(pos); if (ch !== 0x60/* ` */) { return false; } - start = pos; + const start = pos; pos++; - max = state.posMax; + const max = state.posMax; // scan marker length while (pos < max && state.src.charCodeAt(pos) === 0x60/* ` */) { pos++; } - marker = state.src.slice(start, pos); - openerLength = marker.length; + const marker = state.src.slice(start, pos); + const openerLength = marker.length; if (state.backticksScanned && (state.backticks[openerLength] || 0) <= start) { if (!silent) state.pending += marker; @@ -23,7 +22,8 @@ export default function backtick(state, silent) { return true; } - matchEnd = pos; + let matchEnd = pos; + let matchStart; // Nothing found in the cache, scan until the end of the line (or until marker is found) while ((matchStart = state.src.indexOf('`', matchEnd)) !== -1) { @@ -32,13 +32,13 @@ export default function backtick(state, silent) { // scan marker length while (matchEnd < max && state.src.charCodeAt(matchEnd) === 0x60/* ` */) { matchEnd++; } - closerLength = matchEnd - matchStart; + const closerLength = matchEnd - matchStart; if (closerLength === openerLength) { // Found matching closer length. if (!silent) { - token = state.push('code_inline', 'code', 0); - token.markup = marker; + const token = state.push('code_inline', 'code', 0); + token.markup = marker; token.content = state.src.slice(pos, matchStart) .replace(/\n/g, ' ') .replace(/^ (.+) $/, '$1'); diff --git a/lib/rules_inline/balance_pairs.mjs b/lib/rules_inline/balance_pairs.mjs index 2756e9a..1078f9d 100644 --- a/lib/rules_inline/balance_pairs.mjs +++ b/lib/rules_inline/balance_pairs.mjs @@ -2,20 +2,18 @@ // function processDelimiters(delimiters) { - var closerIdx, openerIdx, closer, opener, minOpenerIdx, newMinOpenerIdx, - isOddMatch, lastJump, - openersBottom = {}, - max = delimiters.length; + const openersBottom = {}; + const max = delimiters.length; if (!max) return; // headerIdx is the first delimiter of the current (where closer is) delimiter run - var headerIdx = 0; - var lastTokenIdx = -2; // needs any value lower than -1 - var jumps = []; + let headerIdx = 0; + let lastTokenIdx = -2; // needs any value lower than -1 + const jumps = []; - for (closerIdx = 0; closerIdx < max; closerIdx++) { - closer = delimiters[closerIdx]; + for (let closerIdx = 0; closerIdx < max; closerIdx++) { + const closer = delimiters[closerIdx]; jumps.push(0); @@ -45,20 +43,20 @@ function processDelimiters(delimiters) { openersBottom[closer.marker] = [ -1, -1, -1, -1, -1, -1 ]; } - minOpenerIdx = openersBottom[closer.marker][(closer.open ? 3 : 0) + (closer.length % 3)]; + const minOpenerIdx = openersBottom[closer.marker][(closer.open ? 3 : 0) + (closer.length % 3)]; - openerIdx = headerIdx - jumps[headerIdx] - 1; + let openerIdx = headerIdx - jumps[headerIdx] - 1; - newMinOpenerIdx = openerIdx; + let newMinOpenerIdx = openerIdx; for (; openerIdx > minOpenerIdx; openerIdx -= jumps[openerIdx] + 1) { - opener = delimiters[openerIdx]; + const opener = delimiters[openerIdx]; if (opener.marker !== closer.marker) continue; if (opener.open && opener.end < 0) { - isOddMatch = false; + let isOddMatch = false; // from spec: // @@ -80,7 +78,7 @@ function processDelimiters(delimiters) { // the entire sequence in future checks. This is required to make // sure algorithm has linear complexity (see *_*_*_*_*_... case). // - lastJump = openerIdx > 0 && !delimiters[openerIdx - 1].open ? + const lastJump = openerIdx > 0 && !delimiters[openerIdx - 1].open ? jumps[openerIdx - 1] + 1 : 0; @@ -114,13 +112,12 @@ function processDelimiters(delimiters) { export default function link_pairs(state) { - var curr, - tokens_meta = state.tokens_meta, - max = state.tokens_meta.length; + const tokens_meta = state.tokens_meta; + const max = state.tokens_meta.length; processDelimiters(state.delimiters); - for (curr = 0; curr < max; curr++) { + for (let curr = 0; curr < max; curr++) { if (tokens_meta[curr] && tokens_meta[curr].delimiters) { processDelimiters(tokens_meta[curr].delimiters); } diff --git a/lib/rules_inline/emphasis.mjs b/lib/rules_inline/emphasis.mjs index b55aa26..310dd5d 100644 --- a/lib/rules_inline/emphasis.mjs +++ b/lib/rules_inline/emphasis.mjs @@ -4,18 +4,17 @@ // Insert each marker as a separate text token, and add it to delimiter list // function emphasis_tokenize(state, silent) { - var i, scanned, token, - start = state.pos, - marker = state.src.charCodeAt(start); + const start = state.pos; + const marker = state.src.charCodeAt(start); if (silent) { return false; } if (marker !== 0x5F /* _ */ && marker !== 0x2A /* * */) { return false; } - scanned = state.scanDelims(state.pos, marker === 0x2A); + const scanned = state.scanDelims(state.pos, marker === 0x2A); - for (i = 0; i < scanned.length; i++) { - token = state.push('text', '', 0); + for (let i = 0; i < scanned.length; i++) { + const token = state.push('text', '', 0); token.content = String.fromCharCode(marker); state.delimiters.push({ @@ -51,16 +50,10 @@ function emphasis_tokenize(state, silent) { function postProcess(state, delimiters) { - var i, - startDelim, - endDelim, - token, - ch, - isStrong, - max = delimiters.length; + const max = delimiters.length; - for (i = max - 1; i >= 0; i--) { - startDelim = delimiters[i]; + for (let i = max - 1; i >= 0; i--) { + const startDelim = delimiters[i]; if (startDelim.marker !== 0x5F/* _ */ && startDelim.marker !== 0x2A/* * */) { continue; @@ -71,14 +64,14 @@ function postProcess(state, delimiters) { continue; } - endDelim = delimiters[startDelim.end]; + const endDelim = delimiters[startDelim.end]; // If the previous delimiter has the same marker and is adjacent to this one, // merge those into one strong delimiter. // // `whatever` -> `whatever` // - isStrong = i > 0 && + const isStrong = i > 0 && delimiters[i - 1].end === startDelim.end + 1 && // check that first two markers match and adjacent delimiters[i - 1].marker === startDelim.marker && @@ -86,21 +79,21 @@ function postProcess(state, delimiters) { // check that last two markers are adjacent (we can safely assume they match) delimiters[startDelim.end + 1].token === endDelim.token + 1; - ch = String.fromCharCode(startDelim.marker); + const ch = String.fromCharCode(startDelim.marker); - token = state.tokens[startDelim.token]; - token.type = isStrong ? 'strong_open' : 'em_open'; - token.tag = isStrong ? 'strong' : 'em'; - token.nesting = 1; - token.markup = isStrong ? ch + ch : ch; - token.content = ''; + const token_o = state.tokens[startDelim.token]; + token_o.type = isStrong ? 'strong_open' : 'em_open'; + token_o.tag = isStrong ? 'strong' : 'em'; + token_o.nesting = 1; + token_o.markup = isStrong ? ch + ch : ch; + token_o.content = ''; - token = state.tokens[endDelim.token]; - token.type = isStrong ? 'strong_close' : 'em_close'; - token.tag = isStrong ? 'strong' : 'em'; - token.nesting = -1; - token.markup = isStrong ? ch + ch : ch; - token.content = ''; + const token_c = state.tokens[endDelim.token]; + token_c.type = isStrong ? 'strong_close' : 'em_close'; + token_c.tag = isStrong ? 'strong' : 'em'; + token_c.nesting = -1; + token_c.markup = isStrong ? ch + ch : ch; + token_c.content = ''; if (isStrong) { state.tokens[delimiters[i - 1].token].content = ''; @@ -114,13 +107,12 @@ function postProcess(state, delimiters) { // Walk through delimiter list and replace text tokens with tags // function emphasis_post_process(state) { - var curr, - tokens_meta = state.tokens_meta, - max = state.tokens_meta.length; + const tokens_meta = state.tokens_meta; + const max = state.tokens_meta.length; postProcess(state, state.delimiters); - for (curr = 0; curr < max; curr++) { + for (let curr = 0; curr < max; curr++) { if (tokens_meta[curr] && tokens_meta[curr].delimiters) { postProcess(state, tokens_meta[curr].delimiters); } diff --git a/lib/rules_inline/entity.mjs b/lib/rules_inline/entity.mjs index 38d05d9..dc3b9bf 100644 --- a/lib/rules_inline/entity.mjs +++ b/lib/rules_inline/entity.mjs @@ -4,26 +4,27 @@ import { decodeHTML } from 'entities'; import { isValidEntityCode, fromCodePoint } from '../common/utils.mjs'; -var DIGITAL_RE = /^&#((?:x[a-f0-9]{1,6}|[0-9]{1,7}));/i; -var NAMED_RE = /^&([a-z][a-z0-9]{1,31});/i; +const DIGITAL_RE = /^&#((?:x[a-f0-9]{1,6}|[0-9]{1,7}));/i; +const NAMED_RE = /^&([a-z][a-z0-9]{1,31});/i; export default function entity(state, silent) { - var ch, code, match, decoded, token, pos = state.pos, max = state.posMax; + const pos = state.pos; + const max = state.posMax; if (state.src.charCodeAt(pos) !== 0x26/* & */) return false; if (pos + 1 >= max) return false; - ch = state.src.charCodeAt(pos + 1); + const ch = state.src.charCodeAt(pos + 1); if (ch === 0x23 /* # */) { - match = state.src.slice(pos).match(DIGITAL_RE); + const match = state.src.slice(pos).match(DIGITAL_RE); if (match) { if (!silent) { - code = match[1][0].toLowerCase() === 'x' ? parseInt(match[1].slice(1), 16) : parseInt(match[1], 10); + const code = match[1][0].toLowerCase() === 'x' ? parseInt(match[1].slice(1), 16) : parseInt(match[1], 10); - token = state.push('text_special', '', 0); + const token = state.push('text_special', '', 0); token.content = isValidEntityCode(code) ? fromCodePoint(code) : fromCodePoint(0xFFFD); token.markup = match[0]; token.info = 'entity'; @@ -32,12 +33,12 @@ export default function entity(state, silent) { return true; } } else { - match = state.src.slice(pos).match(NAMED_RE); + const match = state.src.slice(pos).match(NAMED_RE); if (match) { - decoded = decodeHTML(match[0]); + const decoded = decodeHTML(match[0]); if (decoded !== match[0]) { if (!silent) { - token = state.push('text_special', '', 0); + const token = state.push('text_special', '', 0); token.content = decoded; token.markup = match[0]; token.info = 'entity'; diff --git a/lib/rules_inline/escape.mjs b/lib/rules_inline/escape.mjs index 3ee00d1..fb664a5 100644 --- a/lib/rules_inline/escape.mjs +++ b/lib/rules_inline/escape.mjs @@ -2,16 +2,17 @@ import { isSpace } from '../common/utils.mjs'; -var ESCAPED = []; +const ESCAPED = []; -for (var i = 0; i < 256; i++) { ESCAPED.push(0); } +for (let i = 0; i < 256; i++) { ESCAPED.push(0); } '\\!"#$%&\'()*+,./:;<=>?@[]^_`{|}~-' .split('').forEach(function (ch) { ESCAPED[ch.charCodeAt(0)] = 1; }); export default function escape(state, silent) { - var ch1, ch2, origStr, escapedStr, token, pos = state.pos, max = state.posMax; + let pos = state.pos; + const max = state.posMax; if (state.src.charCodeAt(pos) !== 0x5C/* \ */) return false; pos++; @@ -19,7 +20,7 @@ export default function escape(state, silent) { // '\' at the end of the inline block if (pos >= max) return false; - ch1 = state.src.charCodeAt(pos); + let ch1 = state.src.charCodeAt(pos); if (ch1 === 0x0A) { if (!silent) { @@ -38,10 +39,10 @@ export default function escape(state, silent) { return true; } - escapedStr = state.src[pos]; + let escapedStr = state.src[pos]; if (ch1 >= 0xD800 && ch1 <= 0xDBFF && pos + 1 < max) { - ch2 = state.src.charCodeAt(pos + 1); + const ch2 = state.src.charCodeAt(pos + 1); if (ch2 >= 0xDC00 && ch2 <= 0xDFFF) { escapedStr += state.src[pos + 1]; @@ -49,10 +50,10 @@ export default function escape(state, silent) { } } - origStr = '\\' + escapedStr; + const origStr = '\\' + escapedStr; if (!silent) { - token = state.push('text_special', '', 0); + const token = state.push('text_special', '', 0); if (ch1 < 256 && ESCAPED[ch1] !== 0) { token.content = escapedStr; diff --git a/lib/rules_inline/fragments_join.mjs b/lib/rules_inline/fragments_join.mjs index 3f321df..9b21fc3 100644 --- a/lib/rules_inline/fragments_join.mjs +++ b/lib/rules_inline/fragments_join.mjs @@ -8,10 +8,10 @@ // export default function fragments_join(state) { - var curr, last, - level = 0, - tokens = state.tokens, - max = state.tokens.length; + let curr, last, + level = 0; + const tokens = state.tokens; + const max = state.tokens.length; for (curr = last = 0; curr < max; curr++) { // re-calculate levels after emphasis/strikethrough turns some text nodes diff --git a/lib/rules_inline/html_inline.mjs b/lib/rules_inline/html_inline.mjs index c5ac486..d2eb332 100644 --- a/lib/rules_inline/html_inline.mjs +++ b/lib/rules_inline/html_inline.mjs @@ -13,26 +13,24 @@ function isLinkClose(str) { function isLetter(ch) { /*eslint no-bitwise:0*/ - var lc = ch | 0x20; // to lower case + const lc = ch | 0x20; // to lower case return (lc >= 0x61/* a */) && (lc <= 0x7a/* z */); } export default function html_inline(state, silent) { - var ch, match, max, token, - pos = state.pos; - if (!state.md.options.html) { return false; } // Check start - max = state.posMax; + const max = state.posMax; + const pos = state.pos; if (state.src.charCodeAt(pos) !== 0x3C/* < */ || pos + 2 >= max) { return false; } // Quick fail on second char - ch = state.src.charCodeAt(pos + 1); + const ch = state.src.charCodeAt(pos + 1); if (ch !== 0x21/* ! */ && ch !== 0x3F/* ? */ && ch !== 0x2F/* / */ && @@ -40,11 +38,11 @@ export default function html_inline(state, silent) { return false; } - match = state.src.slice(pos).match(HTML_TAG_RE); + const match = state.src.slice(pos).match(HTML_TAG_RE); if (!match) { return false; } if (!silent) { - token = state.push('html_inline', '', 0); + const token = state.push('html_inline', '', 0); token.content = match[0]; if (isLinkOpen(token.content)) state.linkLevel++; diff --git a/lib/rules_inline/image.mjs b/lib/rules_inline/image.mjs index 8ca1d74..76f584a 100644 --- a/lib/rules_inline/image.mjs +++ b/lib/rules_inline/image.mjs @@ -4,28 +4,23 @@ import { normalizeReference, isSpace } from '../common/utils.mjs'; export default function image(state, silent) { - var attrs, - code, + let code, content, label, - labelEnd, - labelStart, pos, ref, res, title, - token, - tokens, start, - href = '', - oldPos = state.pos, - max = state.posMax; + href = ''; + const oldPos = state.pos; + const max = state.posMax; if (state.src.charCodeAt(state.pos) !== 0x21/* ! */) { return false; } if (state.src.charCodeAt(state.pos + 1) !== 0x5B/* [ */) { return false; } - labelStart = state.pos + 2; - labelEnd = state.md.helpers.parseLinkLabel(state, state.pos + 1, false); + const labelStart = state.pos + 2; + const labelEnd = state.md.helpers.parseLinkLabel(state, state.pos + 1, false); // parser failed to find ']', so it's not a valid link if (labelEnd < 0) { return false; } @@ -126,17 +121,19 @@ export default function image(state, silent) { if (!silent) { content = state.src.slice(labelStart, labelEnd); + const tokens = []; state.md.inline.parse( content, state.md, state.env, - tokens = [] + tokens ); - token = state.push('image', 'img', 0); - token.attrs = attrs = [ [ 'src', href ], [ 'alt', '' ] ]; + const token = state.push('image', 'img', 0); + const attrs = [ [ 'src', href ], [ 'alt', '' ] ]; + token.attrs = attrs; token.children = tokens; - token.content = content; + token.content = content; if (title) { attrs.push([ 'title', title ]); diff --git a/lib/rules_inline/link.mjs b/lib/rules_inline/link.mjs index 475a6c7..713afe5 100644 --- a/lib/rules_inline/link.mjs +++ b/lib/rules_inline/link.mjs @@ -3,31 +3,26 @@ import { normalizeReference, isSpace } from '../common/utils.mjs'; export default function link(state, silent) { - var attrs, - code, + let code, label, - labelEnd, - labelStart, - pos, res, ref, - token, href = '', title = '', - oldPos = state.pos, - max = state.posMax, start = state.pos, parseReference = true; if (state.src.charCodeAt(state.pos) !== 0x5B/* [ */) { return false; } - labelStart = state.pos + 1; - labelEnd = state.md.helpers.parseLinkLabel(state, state.pos, true); + const oldPos = state.pos; + const max = state.posMax; + const labelStart = state.pos + 1; + const labelEnd = state.md.helpers.parseLinkLabel(state, state.pos, true); // parser failed to find ']', so it's not a valid link if (labelEnd < 0) { return false; } - pos = labelEnd + 1; + let pos = labelEnd + 1; if (pos < max && state.src.charCodeAt(pos) === 0x28/* ( */) { // // Inline link @@ -127,8 +122,9 @@ export default function link(state, silent) { state.pos = labelStart; state.posMax = labelEnd; - token = state.push('link_open', 'a', 1); - token.attrs = attrs = [ [ 'href', href ] ]; + const token_o = state.push('link_open', 'a', 1); + const attrs = [ [ 'href', href ] ]; + token_o.attrs = attrs; if (title) { attrs.push([ 'title', title ]); } @@ -137,7 +133,7 @@ export default function link(state, silent) { state.md.inline.tokenize(state); state.linkLevel--; - token = state.push('link_close', 'a', -1); + state.push('link_close', 'a', -1); } state.pos = pos; diff --git a/lib/rules_inline/linkify.mjs b/lib/rules_inline/linkify.mjs index 991890f..1c03750 100644 --- a/lib/rules_inline/linkify.mjs +++ b/lib/rules_inline/linkify.mjs @@ -1,32 +1,30 @@ // Process links like https://example.org/ // RFC3986: scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) -var SCHEME_RE = /(?:^|[^a-z0-9.+-])([a-z][a-z0-9.+-]*)$/i; +const SCHEME_RE = /(?:^|[^a-z0-9.+-])([a-z][a-z0-9.+-]*)$/i; export default function linkify(state, silent) { - var pos, max, match, proto, link, url, fullUrl, token; - if (!state.md.options.linkify) return false; if (state.linkLevel > 0) return false; - pos = state.pos; - max = state.posMax; + const pos = state.pos; + const max = state.posMax; if (pos + 3 > max) return false; if (state.src.charCodeAt(pos) !== 0x3A/* : */) return false; if (state.src.charCodeAt(pos + 1) !== 0x2F/* / */) return false; if (state.src.charCodeAt(pos + 2) !== 0x2F/* / */) return false; - match = state.pending.match(SCHEME_RE); + const match = state.pending.match(SCHEME_RE); if (!match) return false; - proto = match[1]; + const proto = match[1]; - link = state.md.linkify.matchAtStart(state.src.slice(pos - proto.length)); + const link = state.md.linkify.matchAtStart(state.src.slice(pos - proto.length)); if (!link) return false; - url = link.url; + let url = link.url; // invalid link, but still detected by linkify somehow; // need to check to prevent infinite loop below @@ -35,23 +33,23 @@ export default function linkify(state, silent) { // disallow '*' at the end of the link (conflicts with emphasis) url = url.replace(/\*+$/, ''); - fullUrl = state.md.normalizeLink(url); + const fullUrl = state.md.normalizeLink(url); if (!state.md.validateLink(fullUrl)) return false; if (!silent) { state.pending = state.pending.slice(0, -proto.length); - token = state.push('link_open', 'a', 1); - token.attrs = [ [ 'href', fullUrl ] ]; - token.markup = 'linkify'; - token.info = 'auto'; + const token_o = state.push('link_open', 'a', 1); + token_o.attrs = [ [ 'href', fullUrl ] ]; + token_o.markup = 'linkify'; + token_o.info = 'auto'; - token = state.push('text', '', 0); - token.content = state.md.normalizeLinkText(url); + const token_t = state.push('text', '', 0); + token_t.content = state.md.normalizeLinkText(url); - token = state.push('link_close', 'a', -1); - token.markup = 'linkify'; - token.info = 'auto'; + const token_c = state.push('link_close', 'a', -1); + token_c.markup = 'linkify'; + token_c.info = 'auto'; } state.pos += url.length - proto.length; diff --git a/lib/rules_inline/newline.mjs b/lib/rules_inline/newline.mjs index 562818a..a19c24c 100644 --- a/lib/rules_inline/newline.mjs +++ b/lib/rules_inline/newline.mjs @@ -3,12 +3,12 @@ import { isSpace } from '../common/utils.mjs'; export default function newline(state, silent) { - var pmax, max, ws, pos = state.pos; + let pos = state.pos; if (state.src.charCodeAt(pos) !== 0x0A/* \n */) { return false; } - pmax = state.pending.length - 1; - max = state.posMax; + const pmax = state.pending.length - 1; + const max = state.posMax; // ' \n' -> hardbreak // Lookup in pending chars is bad practice! Don't copy to other rules! @@ -18,7 +18,7 @@ export default function newline(state, silent) { if (pmax >= 0 && state.pending.charCodeAt(pmax) === 0x20) { if (pmax >= 1 && state.pending.charCodeAt(pmax - 1) === 0x20) { // Find whitespaces tail of pending chars. - ws = pmax - 1; + let ws = pmax - 1; while (ws >= 1 && state.pending.charCodeAt(ws - 1) === 0x20) ws--; state.pending = state.pending.slice(0, ws); diff --git a/lib/rules_inline/state_inline.mjs b/lib/rules_inline/state_inline.mjs index 45ac55d..339b9f6 100644 --- a/lib/rules_inline/state_inline.mjs +++ b/lib/rules_inline/state_inline.mjs @@ -39,7 +39,7 @@ function StateInline(src, md, env, outTokens) { // Flush pending text // StateInline.prototype.pushPending = function () { - var token = new Token('text', '', 0); + const token = new Token('text', '', 0); token.content = this.pending; token.level = this.pendingLevel; this.tokens.push(token); @@ -56,8 +56,8 @@ StateInline.prototype.push = function (type, tag, nesting) { this.pushPending(); } - var token = new Token(type, tag, nesting); - var token_meta = null; + const token = new Token(type, tag, nesting); + let token_meta = null; if (nesting < 0) { // closing tag @@ -89,29 +89,28 @@ StateInline.prototype.push = function (type, tag, nesting) { // - 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); + let can_open, can_close; + let left_flanking = true; + let right_flanking = true; + const max = this.posMax; + const marker = this.src.charCodeAt(start); // treat beginning of the line as a whitespace - lastChar = start > 0 ? this.src.charCodeAt(start - 1) : 0x20; + const lastChar = start > 0 ? this.src.charCodeAt(start - 1) : 0x20; + let pos = start; while (pos < max && this.src.charCodeAt(pos) === marker) { pos++; } - count = pos - start; + const count = pos - start; // treat end of the line as a whitespace - nextChar = pos < max ? this.src.charCodeAt(pos) : 0x20; + const nextChar = pos < max ? this.src.charCodeAt(pos) : 0x20; - isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctChar(String.fromCharCode(lastChar)); - isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctChar(String.fromCharCode(nextChar)); + const isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctChar(String.fromCharCode(lastChar)); + const isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctChar(String.fromCharCode(nextChar)); - isLastWhiteSpace = isWhiteSpace(lastChar); - isNextWhiteSpace = isWhiteSpace(nextChar); + const isLastWhiteSpace = isWhiteSpace(lastChar); + const isNextWhiteSpace = isWhiteSpace(nextChar); if (isNextWhiteSpace) { left_flanking = false; diff --git a/lib/rules_inline/strikethrough.mjs b/lib/rules_inline/strikethrough.mjs index 1ef52c1..72c1cd7 100644 --- a/lib/rules_inline/strikethrough.mjs +++ b/lib/rules_inline/strikethrough.mjs @@ -4,27 +4,28 @@ // Insert each marker as a separate text token, and add it to delimiter list // function strikethrough_tokenize(state, silent) { - var i, scanned, token, len, ch, - start = state.pos, - marker = state.src.charCodeAt(start); + const start = state.pos; + const marker = state.src.charCodeAt(start); if (silent) { return false; } if (marker !== 0x7E/* ~ */) { return false; } - scanned = state.scanDelims(state.pos, true); - len = scanned.length; - ch = String.fromCharCode(marker); + const scanned = state.scanDelims(state.pos, true); + let len = scanned.length; + const ch = String.fromCharCode(marker); if (len < 2) { return false; } + let token; + if (len % 2) { token = state.push('text', '', 0); token.content = ch; len--; } - for (i = 0; i < len; i += 2) { + for (let i = 0; i < len; i += 2) { token = state.push('text', '', 0); token.content = ch + ch; @@ -45,15 +46,12 @@ function strikethrough_tokenize(state, silent) { function postProcess(state, delimiters) { - var i, j, - startDelim, - endDelim, - token, - loneMarkers = [], - max = delimiters.length; + let token; + const loneMarkers = []; + const max = delimiters.length; - for (i = 0; i < max; i++) { - startDelim = delimiters[i]; + for (let i = 0; i < max; i++) { + const startDelim = delimiters[i]; if (startDelim.marker !== 0x7E/* ~ */) { continue; @@ -63,7 +61,7 @@ function postProcess(state, delimiters) { continue; } - endDelim = delimiters[startDelim.end]; + const endDelim = delimiters[startDelim.end]; token = state.tokens[startDelim.token]; token.type = 's_open'; @@ -93,8 +91,8 @@ function postProcess(state, delimiters) { // So, we have to move all those markers after subsequent s_close tags. // while (loneMarkers.length) { - i = loneMarkers.pop(); - j = i + 1; + const i = loneMarkers.pop(); + let j = i + 1; while (j < state.tokens.length && state.tokens[j].type === 's_close') { j++; @@ -114,13 +112,12 @@ function postProcess(state, delimiters) { // Walk through delimiter list and replace text tokens with tags // function strikethrough_postProcess(state) { - var curr, - tokens_meta = state.tokens_meta, - max = state.tokens_meta.length; + const tokens_meta = state.tokens_meta; + const max = state.tokens_meta.length; postProcess(state, state.delimiters); - for (curr = 0; curr < max; curr++) { + for (let curr = 0; curr < max; curr++) { if (tokens_meta[curr] && tokens_meta[curr].delimiters) { postProcess(state, tokens_meta[curr].delimiters); } diff --git a/lib/rules_inline/text.mjs b/lib/rules_inline/text.mjs index a1d162f..e7f04b9 100644 --- a/lib/rules_inline/text.mjs +++ b/lib/rules_inline/text.mjs @@ -40,7 +40,7 @@ function isTerminatorChar(ch) { } export default function text(state, silent) { - var pos = state.pos; + let pos = state.pos; while (pos < state.posMax && !isTerminatorChar(state.src.charCodeAt(pos))) { pos++; diff --git a/lib/token.mjs b/lib/token.mjs index bdccefc..5822d21 100644 --- a/lib/token.mjs +++ b/lib/token.mjs @@ -120,13 +120,11 @@ function Token(type, tag, nesting) { * Search attribute index by name. **/ Token.prototype.attrIndex = function attrIndex(name) { - var attrs, i, len; - if (!this.attrs) { return -1; } - attrs = this.attrs; + const attrs = this.attrs; - for (i = 0, len = attrs.length; i < len; i++) { + for (let i = 0, len = attrs.length; i < len; i++) { if (attrs[i][0] === name) { return i; } } return -1; @@ -153,8 +151,8 @@ Token.prototype.attrPush = function attrPush(attrData) { * Set `name` attribute to `value`. Override old value if exists. **/ Token.prototype.attrSet = function attrSet(name, value) { - var idx = this.attrIndex(name), - attrData = [ name, value ]; + const idx = this.attrIndex(name), + attrData = [ name, value ]; if (idx < 0) { this.attrPush(attrData); @@ -170,7 +168,8 @@ Token.prototype.attrSet = function attrSet(name, value) { * Get the value of attribute `name`, or null if it does not exist. **/ Token.prototype.attrGet = function attrGet(name) { - var idx = this.attrIndex(name), value = null; + const idx = this.attrIndex(name); + let value = null; if (idx >= 0) { value = this.attrs[idx][1]; } @@ -185,7 +184,7 @@ Token.prototype.attrGet = function attrGet(name) { * exists. Useful to operate with token classes. **/ Token.prototype.attrJoin = function attrJoin(name, value) { - var idx = this.attrIndex(name); + const idx = this.attrIndex(name); if (idx < 0) { this.attrPush([ name, value ]); diff --git a/support/demo_template/index.mjs b/support/demo_template/index.mjs index af2f5a7..4668c96 100644 --- a/support/demo_template/index.mjs +++ b/support/demo_template/index.mjs @@ -16,9 +16,9 @@ import md_sub from 'markdown-it-sub'; import md_sup from 'markdown-it-sup'; -var mdHtml, mdSrc, permalink, scrollMap; +let mdHtml, mdSrc, permalink, scrollMap; -var defaults = { +const defaults = { html: false, // Enable HTML tags in source xhtmlOut: false, // Use '/' to close single tags (
) breaks: false, // Convert '\n' in paragraphs into
@@ -33,7 +33,7 @@ var defaults = { }; defaults.highlight = function (str, lang) { - var esc = mdHtml.utils.escapeHtml; + const esc = mdHtml.utils.escapeHtml; try { if (!defaults._highlight) { @@ -48,7 +48,7 @@ defaults.highlight = function (str, lang) { } else if (lang === 'auto') { - var result = hljs.highlightAuto(str); + const result = hljs.highlightAuto(str); /*eslint-disable no-console*/ console.log('highlight language: ' + result.language + ', relevance: ' + result.relevance); @@ -121,7 +121,7 @@ function mdInit() { // - We track only headings and paragraphs on first level. That's enough. // - Footnotes content causes jumps. Level limit filter it automatically. function injectLineNumbers(tokens, idx, options, env, slf) { - var line; + let line; if (tokens[idx].map && tokens[idx].level === 0) { line = tokens[idx].map[0]; tokens[idx].attrJoin('class', 'line'); @@ -142,7 +142,7 @@ function setHighlightedlContent(selector, content, lang) { } function updateResult() { - var source = $('.source').val(); + const source = $('.source').val(); // Update only active view to avoid slowdowns // (debug & src view with highlighting are a bit slow) @@ -182,11 +182,9 @@ function updateResult() { // That's a bit dirty to process each line everytime, but ok for demo. // Optimizations are required only for big texts. function buildScrollMap() { - var i, offset, nonEmptyList, pos, a, b, lineHeightMap, linesCount, - acc, sourceLikeDiv, textarea = $('.source'), - _scrollMap; + const textarea = $('.source'); - sourceLikeDiv = $('
').css({ + const sourceLikeDiv = $('
').css({ position: 'absolute', visibility: 'hidden', height: 'auto', @@ -197,15 +195,13 @@ function buildScrollMap() { 'white-space': textarea.css('white-space') }).appendTo('body'); - offset = $('.result-html').scrollTop() - $('.result-html').offset().top; - _scrollMap = []; - nonEmptyList = []; - lineHeightMap = []; + const offset = $('.result-html').scrollTop() - $('.result-html').offset().top; + const _scrollMap = []; + const nonEmptyList = []; + const lineHeightMap = []; - acc = 0; + let acc = 0; textarea.val().split('\n').forEach(function (str) { - var h, lh; - lineHeightMap.push(acc); if (str.length === 0) { @@ -214,21 +210,22 @@ function buildScrollMap() { } sourceLikeDiv.text(str); - h = parseFloat(sourceLikeDiv.css('height')); - lh = parseFloat(sourceLikeDiv.css('line-height')); + const h = parseFloat(sourceLikeDiv.css('height')); + const lh = parseFloat(sourceLikeDiv.css('line-height')); acc += Math.round(h / lh); }); sourceLikeDiv.remove(); lineHeightMap.push(acc); - linesCount = acc; + const linesCount = acc; - for (i = 0; i < linesCount; i++) { _scrollMap.push(-1); } + for (let i = 0; i < linesCount; i++) { _scrollMap.push(-1); } nonEmptyList.push(0); _scrollMap[0] = 0; $('.line').each(function (n, el) { - var $el = $(el), t = $el.data('line'); + const $el = $(el); + let t = $el.data('line'); if (t === '') { return; } t = lineHeightMap[t]; if (t !== 0) { nonEmptyList.push(t); } @@ -238,15 +235,15 @@ function buildScrollMap() { nonEmptyList.push(linesCount); _scrollMap[linesCount] = $('.result-html')[0].scrollHeight; - pos = 0; - for (i = 1; i < linesCount; i++) { + let pos = 0; + for (let i = 1; i < linesCount; i++) { if (_scrollMap[i] !== -1) { pos++; continue; } - a = nonEmptyList[pos]; - b = nonEmptyList[pos + 1]; + const a = nonEmptyList[pos]; + const b = nonEmptyList[pos + 1]; _scrollMap[i] = Math.round((_scrollMap[b] * (i - a) + _scrollMap[a] * (b - i)) / (b - a)); } @@ -254,40 +251,36 @@ function buildScrollMap() { } // Synchronize scroll position from source to result -var syncResultScroll = _.debounce(function () { - var textarea = $('.source'), - lineHeight = parseFloat(textarea.css('line-height')), - lineNo, posTo; +const syncResultScroll = _.debounce(function () { + const textarea = $('.source'); + const lineHeight = parseFloat(textarea.css('line-height')); - lineNo = Math.floor(textarea.scrollTop() / lineHeight); + const lineNo = Math.floor(textarea.scrollTop() / lineHeight); if (!scrollMap) { scrollMap = buildScrollMap(); } - posTo = scrollMap[lineNo]; + const posTo = scrollMap[lineNo]; $('.result-html').stop(true).animate({ scrollTop: posTo }, 100, 'linear'); }, 50, { maxWait: 50 }); // Synchronize scroll position from result to source -var syncSrcScroll = _.debounce(function () { - var resultHtml = $('.result-html'), - scrollTop = resultHtml.scrollTop(), - textarea = $('.source'), - lineHeight = parseFloat(textarea.css('line-height')), - lines, - i, - line; +const syncSrcScroll = _.debounce(function () { + const resultHtml = $('.result-html'); + const scrollTop = resultHtml.scrollTop(); + const textarea = $('.source'); + const lineHeight = parseFloat(textarea.css('line-height')); if (!scrollMap) { scrollMap = buildScrollMap(); } - lines = Object.keys(scrollMap); + const lines = Object.keys(scrollMap); if (lines.length < 1) { return; } - line = lines[0]; + let line = lines[0]; - for (i = 1; i < lines.length; i++) { + for (let i = 1; i < lines.length; i++) { if (scrollMap[lines[i]] < scrollTop) { line = lines[i]; continue; @@ -306,7 +299,7 @@ function loadPermalink() { if (!location.hash) { return; } - var cfg, opts; + let cfg; try { @@ -330,7 +323,7 @@ function loadPermalink() { return; } - opts = _.isObject(cfg.defaults) ? cfg.defaults : {}; + const opts = _.isObject(cfg.defaults) ? cfg.defaults : {}; // copy config to defaults, but only if key exists // and value has the same type @@ -376,16 +369,16 @@ $(function () { _.forOwn(defaults, function (val, key) { if (key === 'highlight') { return; } - var el = document.getElementById(key); + const el = document.getElementById(key); if (!el) { return; } - var $el = $(el); + const $el = $(el); if (_.isBoolean(val)) { $el.prop('checked', val); $el.on('change', function () { - var value = Boolean($el.prop('checked')); + const value = Boolean($el.prop('checked')); setOptionClass(key, value); defaults[key] = value; mdInit(); @@ -428,7 +421,7 @@ $(function () { }); $(document).on('click', '[data-result-as]', function (event) { - var view = $(this).data('resultAs'); + const view = $(this).data('resultAs'); if (view) { setResultView(view); // only to update permalink diff --git a/support/specsplit.mjs b/support/specsplit.mjs index 520423c..afe8142 100755 --- a/support/specsplit.mjs +++ b/support/specsplit.mjs @@ -9,7 +9,7 @@ import argparse from 'argparse'; import markdownit from '../index.mjs'; -var cli = new argparse.ArgumentParser({ +const cli = new argparse.ArgumentParser({ add_help: true }); @@ -29,7 +29,7 @@ cli.add_argument('-o', '--output', { default: '-' }); -var options = cli.parse_args(); +const options = cli.parse_args(); //////////////////////////////////////////////////////////////////////////////// @@ -43,7 +43,7 @@ function readFile(filename, encoding, callback) { if (options.file === '-') { // read from stdin - var chunks = []; + const chunks = []; process.stdin.on('data', function (chunk) { chunks.push(chunk); @@ -61,8 +61,8 @@ function readFile(filename, encoding, callback) { //////////////////////////////////////////////////////////////////////////////// readFile(options.spec, 'utf8', function (error, input) { - var good = [], bad = [], - markdown = markdownit('commonmark'); + const good = [], bad = [], + markdown = markdownit('commonmark'); if (error) { if (error.code === 'ENOENT') { @@ -82,11 +82,11 @@ readFile(options.spec, 'utf8', function (error, input) { token.info.trim() === 'example'; }) .forEach(function (token) { - var arr = token.content.split(/^\.\s*?$/m, 2); - var md = arr[0]; - var html = arr[1].replace(/^\n/, ''); + const arr = token.content.split(/^\.\s*?$/m, 2); + const md = arr[0]; + const html = arr[1].replace(/^\n/, ''); - var result = { + const result = { md: md, html: html, line: token.map[0], @@ -106,12 +106,12 @@ readFile(options.spec, 'utf8', function (error, input) { } }); - var out = []; + const out = []; if (!options.type) { out.push(`CM spec stat: passed samples - ${good.length}, failed samples - ${bad.length}`); } else { - var data = options.type === 'good' ? good : bad; + const data = options.type === 'good' ? good : bad; data.forEach(function (sample) { out.push( diff --git a/test/babelmark-responder.mjs b/test/babelmark-responder.mjs index a15f55e..d9f382e 100644 --- a/test/babelmark-responder.mjs +++ b/test/babelmark-responder.mjs @@ -5,10 +5,10 @@ import { setTimeout as sleep } from 'node:timers/promises'; describe('babelmark responder app', function () { - var app; + let app; - var PORT = 5005; - var request = supertest('http://127.0.0.1:' + PORT); + const PORT = 5005; + const request = supertest('http://127.0.0.1:' + PORT); before(async () => { app = execFile( diff --git a/test/commonmark.mjs b/test/commonmark.mjs index 4e23cea..620255c 100644 --- a/test/commonmark.mjs +++ b/test/commonmark.mjs @@ -14,7 +14,7 @@ function generate(path, md) { load(path, function (data) { data.meta = data.meta || {}; - var desc = data.meta.desc || relative(path, data.file); + const desc = data.meta.desc || relative(path, data.file); (data.meta.skip ? describe.skip : describe)(desc, function () { data.fixtures.forEach(function (fixture) { @@ -28,7 +28,7 @@ function generate(path, md) { describe('CommonMark', function () { - var md = markdownit('commonmark'); + const md = markdownit('commonmark'); generate(fileURLToPath(new URL('fixtures/commonmark/good.txt', import.meta.url)), md); }); diff --git a/test/markdown-it.mjs b/test/markdown-it.mjs index a808871..225967c 100644 --- a/test/markdown-it.mjs +++ b/test/markdown-it.mjs @@ -4,7 +4,7 @@ import markdownit from '../index.mjs'; describe('markdown-it', function () { - var md = markdownit({ + const md = markdownit({ html: true, langPrefix: '', typographer: true, diff --git a/test/misc.mjs b/test/misc.mjs index 4d6865c..0bed349 100644 --- a/test/misc.mjs +++ b/test/misc.mjs @@ -11,12 +11,12 @@ describe('API', function () { }); // options should override preset - var md = markdownit('commonmark', { html: false }); + const md = markdownit('commonmark', { html: false }); assert.strictEqual(md.render(''), '

<!-- -->

\n'); }); it('configure coverage', function () { - var md = markdownit(); + const md = markdownit(); // conditions coverage md.configure({}); @@ -28,11 +28,11 @@ describe('API', function () { }); it('plugin', function () { - var succeeded = false; + let succeeded = false; function plugin(slf, opts) { if (opts === 'bar') { succeeded = true; } } - var md = markdownit(); + const md = markdownit(); md.use(plugin, 'foo'); assert.strictEqual(succeeded, false); @@ -41,7 +41,7 @@ describe('API', function () { }); it('highlight', function () { - var md = markdownit({ + const md = markdownit({ highlight: function (str) { return '
==' + str + '==
'; } @@ -51,7 +51,7 @@ describe('API', function () { }); it('highlight escape by default', function () { - var md = markdownit({ + const md = markdownit({ highlight: function () { return ''; } @@ -61,7 +61,7 @@ describe('API', function () { }); it('highlight arguments', function () { - var md = markdownit({ + const md = markdownit({ highlight: function (str, lang, attrs) { assert.strictEqual(lang, 'a'); assert.strictEqual(attrs, 'b c d'); @@ -73,7 +73,7 @@ describe('API', function () { }); it('force hardbreaks', function () { - var md = markdownit({ breaks: true }); + const md = markdownit({ breaks: true }); assert.strictEqual(md.render('a\nb'), '

a
\nb

\n'); md.set({ xhtmlOut: true }); @@ -81,7 +81,7 @@ describe('API', function () { }); it('xhtmlOut enabled', function () { - var md = markdownit({ xhtmlOut: true }); + const md = markdownit({ xhtmlOut: true }); assert.strictEqual(md.render('---'), '
\n'); assert.strictEqual(md.render('![]()'), '

\n'); @@ -89,7 +89,7 @@ describe('API', function () { }); it('xhtmlOut disabled', function () { - var md = markdownit(); + const md = markdownit(); assert.strictEqual(md.render('---'), '
\n'); assert.strictEqual(md.render('![]()'), '

\n'); @@ -97,9 +97,9 @@ describe('API', function () { }); it('bulk enable/disable rules in different chains', function () { - var md = markdownit(); + const md = markdownit(); - var was = { + const was = { core: md.core.ruler.getRules('').length, block: md.block.ruler.getRules('').length, inline: md.inline.ruler.getRules('').length @@ -108,7 +108,7 @@ describe('API', function () { // Disable 2 rule in each chain & compare result md.disable([ 'block', 'inline', 'code', 'fence', 'emphasis', 'entity' ]); - var now = { + const now = { core: md.core.ruler.getRules('').length + 2, block: md.block.ruler.getRules('').length + 2, inline: md.inline.ruler.getRules('').length + 2 @@ -119,7 +119,7 @@ describe('API', function () { // Enable the same rules back md.enable([ 'block', 'inline', 'code', 'fence', 'emphasis', 'entity' ]); - var back = { + const back = { core: md.core.ruler.getRules('').length, block: md.block.ruler.getRules('').length, inline: md.inline.ruler.getRules('').length @@ -129,7 +129,7 @@ describe('API', function () { }); it('bulk enable/disable with errors control', function () { - var md = markdownit(); + const md = markdownit(); assert.throws(function () { md.enable([ 'link', 'code', 'invalid' ]); @@ -146,7 +146,7 @@ describe('API', function () { }); it('bulk enable/disable should understand strings', function () { - var md = markdownit(); + const md = markdownit(); md.disable('emphasis'); assert(md.renderInline('_foo_'), '_foo_'); @@ -156,7 +156,7 @@ describe('API', function () { }); it('input type check', function () { - var md = markdownit(); + const md = markdownit(); assert.throws( function () { md.render(null); }, @@ -170,7 +170,7 @@ describe('API', function () { describe('Plugins', function () { it('should not loop infinitely if all rules are disabled', function () { - var md = markdownit(); + const md = markdownit(); md.inline.ruler.enableOnly([]); md.inline.ruler2.enableOnly([]); @@ -180,7 +180,7 @@ describe('Plugins', function () { }); it('should not loop infinitely if inline rule doesn\'t increment pos', function () { - var md = markdownit(); + const md = markdownit(); md.inline.ruler.after('text', 'custom', function (state/*, silent*/) { if (state.src.charCodeAt(state.pos) !== 0x40/* @ */) return false; @@ -192,10 +192,10 @@ describe('Plugins', function () { }); it('should not loop infinitely if block rule doesn\'t increment pos', function () { - var md = markdownit(); + const md = markdownit(); md.block.ruler.before('paragraph', 'custom', function (state, startLine/*, endLine, silent*/) { - var pos = state.bMarks[startLine] + state.tShift[startLine]; + const pos = state.bMarks[startLine] + state.tShift[startLine]; if (state.src.charCodeAt(pos) !== 0x40/* @ */) return false; return true; }, { alt: [ 'paragraph' ] }); @@ -209,13 +209,13 @@ describe('Plugins', function () { describe('Misc', function () { it('Should replace NULL characters', function () { - var md = markdownit(); + const md = markdownit(); assert.strictEqual(md.render('foo\u0000bar'), '

foo\uFFFDbar

\n'); }); it('Should correctly parse strings without tailing \\n', function () { - var md = markdownit(); + const md = markdownit(); assert.strictEqual(md.render('123'), '

123

\n'); assert.strictEqual(md.render('123\n'), '

123

\n'); @@ -225,19 +225,19 @@ describe('Misc', function () { }); it('Should quickly exit on empty string', function () { - var md = markdownit(); + const md = markdownit(); assert.strictEqual(md.render(''), ''); }); it('Should parse inlines only', function () { - var md = markdownit(); + const md = markdownit(); assert.strictEqual(md.renderInline('a *b* c'), 'a b c'); }); it('Renderer should have pluggable inline and block rules', function () { - var md = markdownit(); + const md = markdownit(); md.renderer.rules.em_open = function () { return ''; }; md.renderer.rules.em_close = function () { return ''; }; @@ -248,7 +248,7 @@ describe('Misc', function () { }); it('Zero preset should disable everything', function () { - var md = markdownit('zero'); + const md = markdownit('zero'); assert.strictEqual(md.render('___foo___'), '

___foo___

\n'); assert.strictEqual(md.renderInline('___foo___'), '___foo___'); @@ -260,13 +260,13 @@ describe('Misc', function () { }); it('Should correctly check block termination rules when those are disabled (#13)', function () { - var md = markdownit('zero'); + const md = markdownit('zero'); assert.strictEqual(md.render('foo\nbar'), '

foo\nbar

\n'); }); it('Should render link target attr', function () { - var md = markdownit() + const md = markdownit() .use(forInline, 'target', 'link_open', function (tokens, idx) { tokens[idx].attrs.push([ 'target', '_blank' ]); }); @@ -275,7 +275,7 @@ describe('Misc', function () { }); it('Should normalize CR to LF', function () { - var md = markdownit(); + const md = markdownit(); assert.strictEqual( md.render('# test\r\r - hello\r - world\r'), @@ -284,7 +284,7 @@ describe('Misc', function () { }); it('Should normalize CR+LF to LF', function () { - var md = markdownit(); + const md = markdownit(); assert.strictEqual( md.render('# test\r\n\r\n - hello\r\n - world\r\n'), @@ -293,7 +293,7 @@ describe('Misc', function () { }); it('Should escape surrogate pairs (coverage)', function () { - var md = markdownit(); + const md = markdownit(); assert.strictEqual(md.render('\\\uD835\uDC9C'), '

\\\uD835\uDC9C

\n'); assert.strictEqual(md.render('\\\uD835x'), '

\\\uD835x

\n'); @@ -305,7 +305,7 @@ describe('Misc', function () { describe('Url normalization', function () { it('Should be overridable', function () { - var md = markdownit({ linkify: true }); + const md = markdownit({ linkify: true }); md.normalizeLink = function (url) { assert(url.match(/example\.com/), 'wrong url passed'); @@ -330,7 +330,7 @@ describe('Url normalization', function () { describe('Links validation', function () { it('Override validator, disable everything', function () { - var md = markdownit({ linkify: true }); + const md = markdownit({ linkify: true }); md.validateLink = function () { return false; }; @@ -348,7 +348,7 @@ describe('Links validation', function () { describe('maxNesting', function () { it('Block parser should not nest above limit', function () { - var md = markdownit({ maxNesting: 2 }); + const md = markdownit({ maxNesting: 2 }); assert.strictEqual( md.render('>foo\n>>bar\n>>>baz'), '
\n

foo

\n
\n
\n' @@ -356,7 +356,7 @@ describe('maxNesting', function () { }); it('Inline parser should not nest above limit', function () { - var md = markdownit({ maxNesting: 1 }); + const md = markdownit({ maxNesting: 1 }); assert.strictEqual( md.render('[`foo`]()'), '

`foo`

\n' @@ -364,7 +364,7 @@ describe('maxNesting', function () { }); it('Inline nesting coverage', function () { - var md = markdownit({ maxNesting: 2 }); + const md = markdownit({ maxNesting: 2 }); assert.strictEqual( md.render('[[[[[[[[[[[[[[[[[[foo]()'), '

[[[[[[[[[[[[[[[[[[foo]()

\n' @@ -375,7 +375,7 @@ describe('maxNesting', function () { describe('smartquotes', function () { - var md = markdownit({ + const md = markdownit({ typographer: true, // all strings have different length to make sure @@ -408,14 +408,14 @@ describe('smartquotes', function () { describe('Ordered list info', function () { - var md = markdownit(); + const md = markdownit(); function type_filter(tokens, type) { return tokens.filter(function (t) { return t.type === type; }); } it('Should mark ordered list item tokens with info', function () { - var tokens = md.parse('1. Foo\n2. Bar\n20. Fuzz'); + let tokens = md.parse('1. Foo\n2. Bar\n20. Fuzz'); assert.strictEqual(type_filter(tokens, 'ordered_list_open').length, 1); tokens = type_filter(tokens, 'list_item_open'); assert.strictEqual(tokens.length, 3); @@ -444,10 +444,10 @@ describe('Ordered list info', function () { describe('Token attributes', function () { it('.attrJoin', function () { - var md = markdownit(); + const md = markdownit(); - var tokens = md.parse('```'), - t = tokens[0]; + const tokens = md.parse('```'), + t = tokens[0]; t.attrJoin('class', 'foo'); t.attrJoin('class', 'bar'); @@ -459,10 +459,10 @@ describe('Token attributes', function () { }); it('.attrSet', function () { - var md = markdownit(); + const md = markdownit(); - var tokens = md.parse('```'), - t = tokens[0]; + const tokens = md.parse('```'), + t = tokens[0]; t.attrSet('class', 'foo'); @@ -480,10 +480,10 @@ describe('Token attributes', function () { }); it('.attrGet', function () { - var md = markdownit(); + const md = markdownit(); - var tokens = md.parse('```'), - t = tokens[0]; + const tokens = md.parse('```'), + t = tokens[0]; assert.strictEqual(t.attrGet('myattr'), null); diff --git a/test/ruler.mjs b/test/ruler.mjs index d5f6b7a..e5ba586 100644 --- a/test/ruler.mjs +++ b/test/ruler.mjs @@ -4,13 +4,13 @@ import Ruler from '../lib/ruler.mjs'; describe('Ruler', function () { it('should replace rule (.at)', function () { - var ruler = new Ruler(); - var res = 0; + const ruler = new Ruler(); + let res = 0; ruler.push('test', function foo() { res = 1; }); ruler.at('test', function bar() { res = 2; }); - var rules = ruler.getRules(''); + const rules = ruler.getRules(''); assert.strictEqual(rules.length, 1); rules[0](); @@ -19,14 +19,14 @@ describe('Ruler', function () { it('should inject before/after rule', function () { - var ruler = new Ruler(); - var res = 0; + const ruler = new Ruler(); + let res = 0; ruler.push('test', function foo() { res = 1; }); ruler.before('test', 'before_test', function fooBefore() { res = -10; }); ruler.after('test', 'after_test', function fooAfter() { res = 10; }); - var rules = ruler.getRules(''); + const rules = ruler.getRules(''); assert.strictEqual(rules.length, 3); rules[0](); @@ -39,7 +39,8 @@ describe('Ruler', function () { it('should enable/disable rule', function () { - var rules, ruler = new Ruler(); + const ruler = new Ruler(); + let rules; ruler.push('test', function foo() {}); ruler.push('test2', function bar() {}); @@ -64,7 +65,8 @@ describe('Ruler', function () { it('should enable/disable multiple rule', function () { - var rules, ruler = new Ruler(); + const ruler = new Ruler(); + let rules; ruler.push('test', function foo() {}); ruler.push('test2', function bar() {}); @@ -79,19 +81,20 @@ describe('Ruler', function () { it('should enable rules by whitelist', function () { - var rules, ruler = new Ruler(); + const ruler = new Ruler(); ruler.push('test', function foo() {}); ruler.push('test2', function bar() {}); ruler.enableOnly('test'); - rules = ruler.getRules(''); + const rules = ruler.getRules(''); assert.strictEqual(rules.length, 1); }); it('should support multiple chains', function () { - var rules, ruler = new Ruler(); + const ruler = new Ruler(); + let rules; ruler.push('test', function foo() {}); ruler.push('test2', function bar() {}, { alt: [ 'alt1' ] }); @@ -107,7 +110,7 @@ describe('Ruler', function () { it('should fail on invalid rule name', function () { - var ruler = new Ruler(); + const ruler = new Ruler(); ruler.push('test', function foo() {}); @@ -130,7 +133,7 @@ describe('Ruler', function () { it('should not fail on invalid rule name in silent mode', function () { - var ruler = new Ruler(); + const ruler = new Ruler(); ruler.push('test', function foo() {}); diff --git a/test/token.mjs b/test/token.mjs index 26c3e54..5dba48c 100644 --- a/test/token.mjs +++ b/test/token.mjs @@ -5,7 +5,7 @@ import Token from '../lib/token.mjs'; describe('Token', function () { it('attr', function () { - var t = new Token('test_token', 'tok', 1); + const t = new Token('test_token', 'tok', 1); assert.strictEqual(t.attrs, null); assert.equal(t.attrIndex('foo'), -1); diff --git a/test/utils.mjs b/test/utils.mjs index 5f3139f..13fdd74 100644 --- a/test/utils.mjs +++ b/test/utils.mjs @@ -5,14 +5,14 @@ import utils from '../lib/common/utils.mjs'; describe('Utils', function () { it('fromCodePoint', function () { - var fromCodePoint = utils.fromCodePoint; + const fromCodePoint = utils.fromCodePoint; assert.strictEqual(fromCodePoint(0x20), ' '); assert.strictEqual(fromCodePoint(0x1F601), '😁'); }); it('isValidEntityCode', function () { - var isValidEntityCode = utils.isValidEntityCode; + const isValidEntityCode = utils.isValidEntityCode; assert.strictEqual(isValidEntityCode(0x20), true); assert.strictEqual(isValidEntityCode(0xD800), false); @@ -38,7 +38,7 @@ describe('Utils', function () { });*/ it('assign', function () { - var assign = utils.assign; + const assign = utils.assign; assert.deepEqual(assign({ a: 1 }, null, { b: 2 }), { a: 1, b: 2 }); assert.throws(function () { @@ -47,13 +47,13 @@ describe('Utils', function () { }); it('escapeRE', function () { - var escapeRE = utils.escapeRE; + const escapeRE = utils.escapeRE; assert.strictEqual(escapeRE(' .?*+^$[]\\(){}|-'), ' \\.\\?\\*\\+\\^\\$\\[\\]\\\\\\(\\)\\{\\}\\|\\-'); }); it('isWhiteSpace', function () { - var isWhiteSpace = utils.isWhiteSpace; + const isWhiteSpace = utils.isWhiteSpace; assert.strictEqual(isWhiteSpace(0x2000), true); assert.strictEqual(isWhiteSpace(0x09), true); @@ -62,7 +62,7 @@ describe('Utils', function () { }); it('isMdAsciiPunct', function () { - var isMdAsciiPunct = utils.isMdAsciiPunct; + const isMdAsciiPunct = utils.isMdAsciiPunct; assert.strictEqual(isMdAsciiPunct(0x30), false); @@ -72,7 +72,7 @@ describe('Utils', function () { }); it('unescapeMd', function () { - var unescapeMd = utils.unescapeMd; + const unescapeMd = utils.unescapeMd; assert.strictEqual(unescapeMd('\\foo'), '\\foo'); assert.strictEqual(unescapeMd('foo'), 'foo');