1 | 'use strict';
|
2 |
|
3 | var htmlparser = require('htmlparser2')
|
4 | , md = require('@textlint/markdown-to-ast');
|
5 |
|
6 | function addLinenos(lines, headers) {
|
7 | var current = 0, line;
|
8 |
|
9 | return headers.map(function (x) {
|
10 | for (var lineno = current; lineno < lines.length; lineno++) {
|
11 | line = lines[lineno];
|
12 | if (new RegExp(x.text[0]).test(line)) {
|
13 | current = lineno;
|
14 | x.line = lineno;
|
15 | x.name = x.text.join('');
|
16 | return x
|
17 | }
|
18 | }
|
19 |
|
20 |
|
21 |
|
22 | x.line = ++current;
|
23 | x.name = x.text.join('');
|
24 | return x
|
25 | })
|
26 | }
|
27 |
|
28 | function rankify(headers, max) {
|
29 | return headers
|
30 | .map(function (x) {
|
31 | x.rank = parseInt(x.tag.slice(1), 10);
|
32 | return x;
|
33 | })
|
34 | .filter(function (x) {
|
35 | return x.rank <= max;
|
36 | })
|
37 | }
|
38 |
|
39 | var go = module.exports = function (lines, maxHeaderLevel) {
|
40 | var source = md.parse(lines.join('\n'))
|
41 | .children
|
42 | .filter(function(node) {
|
43 | return node.type === md.Syntax.HtmlBlock || node.type === md.Syntax.Html;
|
44 | })
|
45 | .map(function (node) {
|
46 | return node.raw;
|
47 | })
|
48 | .join('\n');
|
49 |
|
50 |
|
51 | var headers = [], grabbing = [], text = [];
|
52 |
|
53 | var parser = new htmlparser.Parser({
|
54 | onopentag: function (name, attr) {
|
55 |
|
56 | if (grabbing[grabbing.length - 1] === 'pre') return;
|
57 |
|
58 | if (name === 'pre' || (/h\d/).test(name)) {
|
59 | grabbing.push(name);
|
60 | }
|
61 | },
|
62 | ontext: function (text_) {
|
63 |
|
64 | if (grabbing.length === 0 ||
|
65 | grabbing[grabbing.length - 1] === 'pre') return;
|
66 |
|
67 | text.push(text_);
|
68 | },
|
69 | onclosetag: function (name) {
|
70 | if (grabbing.length === 0) return;
|
71 | if (grabbing[grabbing.length - 1] === name) {
|
72 | var tag = grabbing.pop();
|
73 | headers.push({ text: text, tag: tag });
|
74 | text = [];
|
75 | }
|
76 | }
|
77 | },
|
78 | { decodeEntities: true })
|
79 |
|
80 | parser.write(source);
|
81 | parser.end();
|
82 |
|
83 | headers = addLinenos(lines, headers)
|
84 |
|
85 | headers = rankify(headers, maxHeaderLevel);
|
86 | return headers;
|
87 | }
|