1 | import { DocSection, DocNodeKind, DocParagraph } from '../nodes';
|
2 | /**
|
3 | * The ParagraphSplitter is a secondary stage that runs after the NodeParser has constructed
|
4 | * the DocComment. It splits DocParagraph nodes into multiple paragraphs by looking for
|
5 | * paragraph delimiters. Following CommonMark conventions, paragraphs are delimited by
|
6 | * one or more blank lines. (These lines end with SoftBreak nodes.) The blank lines are
|
7 | * not discarded. Instead, they are attached to the preceding paragraph. If the DocParagraph
|
8 | * starts with blank lines, they are preserved to avoid creating a paragraph containing only
|
9 | * whitespace.
|
10 | */
|
11 | var ParagraphSplitter = /** @class */ (function () {
|
12 | function ParagraphSplitter() {
|
13 | }
|
14 | /**
|
15 | * Split all paragraphs belonging to the provided subtree.
|
16 | */
|
17 | ParagraphSplitter.splitParagraphs = function (node) {
|
18 | if (node instanceof DocSection) {
|
19 | ParagraphSplitter.splitParagraphsForSection(node);
|
20 | // (We don't recurse here, since sections cannot contain subsections)
|
21 | }
|
22 | else {
|
23 | for (var _i = 0, _a = node.getChildNodes(); _i < _a.length; _i++) {
|
24 | var childNode = _a[_i];
|
25 | ParagraphSplitter.splitParagraphs(childNode);
|
26 | }
|
27 | }
|
28 | };
|
29 | /**
|
30 | * Split all paragraphs belonging to the provided DocSection.
|
31 | */
|
32 | ParagraphSplitter.splitParagraphsForSection = function (docSection) {
|
33 | var inputNodes = docSection.nodes;
|
34 | var outputNodes = [];
|
35 | for (var _i = 0, inputNodes_1 = inputNodes; _i < inputNodes_1.length; _i++) {
|
36 | var oldNode = inputNodes_1[_i];
|
37 | if (oldNode.kind === DocNodeKind.Paragraph) {
|
38 | ParagraphSplitter._splitParagraph(oldNode, outputNodes);
|
39 | }
|
40 | else {
|
41 | outputNodes.push(oldNode);
|
42 | }
|
43 | }
|
44 | // Replace the inputNodes with the outputNodes
|
45 | docSection.clearNodes();
|
46 | docSection.appendNodes(outputNodes);
|
47 | };
|
48 | ParagraphSplitter._splitParagraph = function (oldParagraph, outputNodes) {
|
49 | var inputParagraphNodes = oldParagraph.nodes;
|
50 | var currentParagraph = new DocParagraph({ configuration: oldParagraph.configuration });
|
51 | outputNodes.push(currentParagraph);
|
52 | var state = 0 /* Start */;
|
53 | var currentIndex = 0;
|
54 | while (currentIndex < inputParagraphNodes.length) {
|
55 | // Scan forwards to the end of the line
|
56 | var isBlankLine = true;
|
57 | var lineEndIndex = currentIndex; // non-inclusive
|
58 | do {
|
59 | var node = inputParagraphNodes[lineEndIndex++];
|
60 | if (node.kind === DocNodeKind.SoftBreak) {
|
61 | break;
|
62 | }
|
63 | if (isBlankLine) {
|
64 | if (!this._isWhitespace(node)) {
|
65 | isBlankLine = false;
|
66 | }
|
67 | }
|
68 | } while (lineEndIndex < inputParagraphNodes.length);
|
69 | // At this point, the line and SoftBreak will be in inputParagraphNodes.slice(currentIndex, lineEndIndex)
|
70 | switch (state) {
|
71 | case 0 /* Start */:
|
72 | // We're skipping any blank lines that start the first paragraph
|
73 | if (!isBlankLine) {
|
74 | state = 1 /* AwaitingTrailer */;
|
75 | }
|
76 | break;
|
77 | case 1 /* AwaitingTrailer */:
|
78 | // We already saw some content, so now we're looking for a blank line that starts the trailer
|
79 | // at the end of this paragraph
|
80 | if (isBlankLine) {
|
81 | state = 2 /* ReadingTrailer */;
|
82 | }
|
83 | break;
|
84 | case 2 /* ReadingTrailer */:
|
85 | // We already found the trailer, so now we're looking for a non-blank line that will
|
86 | // begin a new paragraph
|
87 | if (!isBlankLine) {
|
88 | // Start a new paragraph
|
89 | currentParagraph = new DocParagraph({ configuration: oldParagraph.configuration });
|
90 | outputNodes.push(currentParagraph);
|
91 | state = 1 /* AwaitingTrailer */;
|
92 | }
|
93 | break;
|
94 | }
|
95 | // Append the line onto the current paragraph
|
96 | for (var i = currentIndex; i < lineEndIndex; ++i) {
|
97 | currentParagraph.appendNode(inputParagraphNodes[i]);
|
98 | }
|
99 | currentIndex = lineEndIndex;
|
100 | }
|
101 | };
|
102 | ParagraphSplitter._isWhitespace = function (node) {
|
103 | switch (node.kind) {
|
104 | case DocNodeKind.PlainText:
|
105 | var docPlainText = node;
|
106 | return ParagraphSplitter._whitespaceRegExp.test(docPlainText.text);
|
107 | default:
|
108 | return false;
|
109 | }
|
110 | };
|
111 | ParagraphSplitter._whitespaceRegExp = /^\s*$/;
|
112 | return ParagraphSplitter;
|
113 | }());
|
114 | export { ParagraphSplitter };
|
115 | //# sourceMappingURL=ParagraphSplitter.js.map |
\ | No newline at end of file |