forked from ChromeDevTools/devtools-frontend
-
Notifications
You must be signed in to change notification settings - Fork 24
Expand file tree
/
Copy pathblock-parser.ts
More file actions
60 lines (51 loc) · 1.63 KB
/
Copy pathblock-parser.ts
File metadata and controls
60 lines (51 loc) · 1.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import { Line } from '../primitives.js';
const reTag = /^@\S+/;
/**
* Groups source lines in sections representing tags.
* First section is a block description if present. Last section captures lines starting with
* the last tag to the end of the block, including dangling closing marker.
* @param {Line[]} block souce lines making a single comment block
*/
export type Parser = (block: Line[]) => Line[][];
/**
* Predicate telling if string contains opening/closing escaping sequence
* @param {string} source raw source line
*/
export type Fencer = (source: string) => boolean;
/**
* `Parser` configuration options
*/
export interface Options {
// escaping sequence or predicate
fence: string | Fencer;
}
/**
* Creates configured `Parser`
* @param {Partial<Options>} options
*/
export default function getParser({
fence = '```',
}: Partial<Options> = {}): Parser {
const fencer = getFencer(fence);
const toggleFence = (source: string, isFenced: boolean): boolean =>
fencer(source) ? !isFenced : isFenced;
return function parseBlock(source: Line[]): Line[][] {
// start with description section
const sections: Line[][] = [[]];
let isFenced = false;
for (const line of source) {
if (reTag.test(line.tokens.description) && !isFenced) {
sections.push([line]);
} else {
sections[sections.length - 1].push(line);
}
isFenced = toggleFence(line.tokens.description, isFenced);
}
return sections;
};
}
function getFencer(fence: string | Fencer): Fencer {
if (typeof fence === 'string')
return (source: string) => source.split(fence).length % 2 === 0;
return fence;
}