Skip to content

Commit a37983f

Browse files
astelmach01UziTechstyfle
authored
fix: cache list indentation regexes (#3969)
* Cache list indentation regexes * Handle zero indent in cached regexes * Update src/rules.ts Co-authored-by: Steven <steven@ceriously.com> --------- Co-authored-by: Tony Brix <tony@brix.ninja> Co-authored-by: Steven <steven@ceriously.com>
1 parent d38b8c2 commit a37983f

2 files changed

Lines changed: 39 additions & 6 deletions

File tree

src/rules.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
const noopTest = { exec: () => null } as unknown as RegExp;
22

3+
function cachedIndentRegex(createRegex: (indent: number) => RegExp) {
4+
const cache: RegExp[] = [];
5+
return (indent: number) => {
6+
const cacheIndex = Math.max(0, Math.min(3, indent - 1));
7+
let regex = cache[cacheIndex];
8+
if (!regex) {
9+
regex = createRegex(cacheIndex);
10+
cache[cacheIndex] = regex;
11+
}
12+
return regex;
13+
};
14+
}
15+
316
function edit(regex: string | RegExp, opt = '') {
417
let source = typeof regex === 'string' ? regex : regex.source;
518
const obj = {
@@ -78,12 +91,12 @@ export const other = {
7891
notSpaceStart: /^\S*/,
7992
endingNewline: /\n$/,
8093
listItemRegex: (bull: string) => new RegExp(`^( {0,3}${bull})((?:[\t ][^\\n]*)?(?:\\n|$))`),
81-
nextBulletRegex: (indent: number) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ \t][^\\n]*)?(?:\\n|$))`),
82-
hrRegex: (indent: number) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`),
83-
fencesBeginRegex: (indent: number) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:\`\`\`|~~~)`),
84-
headingBeginRegex: (indent: number) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}#`),
85-
htmlBeginRegex: (indent: number) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}<(?:[a-z].*>|!--)`, 'i'),
86-
blockquoteBeginRegex: (indent: number) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}>`),
94+
nextBulletRegex: cachedIndentRegex((indent: number) => new RegExp(`^ {0,${indent}}(?:[*+-]|\\d{1,9}[.)])((?:[ \t][^\\n]*)?(?:\\n|$))`)),
95+
hrRegex: cachedIndentRegex((indent: number) => new RegExp(`^ {0,${indent}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`)),
96+
fencesBeginRegex: cachedIndentRegex((indent: number) => new RegExp(`^ {0,${indent}}(?:\`\`\`|~~~)`)),
97+
headingBeginRegex: cachedIndentRegex((indent: number) => new RegExp(`^ {0,${indent}}#`)),
98+
htmlBeginRegex: cachedIndentRegex((indent: number) => new RegExp(`^ {0,${indent}}<(?:[a-z].*>|!--)`, 'i')),
99+
blockquoteBeginRegex: cachedIndentRegex((indent: number) => new RegExp(`^ {0,${indent}}>`)),
87100
};
88101

89102
/**

test/unit/Lexer.test.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,26 @@ function expectInlineTokens({ md, options, tokens, links = {} }) {
2626
}
2727

2828
describe('Lexer', () => {
29+
describe('rules', () => {
30+
it('should create indentation regexes for zero indent', () => {
31+
const {
32+
nextBulletRegex,
33+
hrRegex,
34+
fencesBeginRegex,
35+
headingBeginRegex,
36+
htmlBeginRegex,
37+
blockquoteBeginRegex,
38+
} = new Lexer().tokenizer.rules.other;
39+
40+
assert.ok(nextBulletRegex(0).test('- item\n'));
41+
assert.ok(hrRegex(0).test('---\n'));
42+
assert.ok(fencesBeginRegex(0).test('```'));
43+
assert.ok(headingBeginRegex(0).test('# heading'));
44+
assert.ok(htmlBeginRegex(0).test('<div>'));
45+
assert.ok(blockquoteBeginRegex(0).test('> quote'));
46+
});
47+
});
48+
2949
describe('paragraph', () => {
3050
it('space between paragraphs', () => {
3151
expectTokens({

0 commit comments

Comments
 (0)