@jianwen-lang/parser 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +44 -1
  2. package/dist/cli/render.js +75 -0
  3. package/dist/core/block/rules/attribute-line.d.ts +13 -0
  4. package/dist/core/block/rules/attribute-line.js +227 -0
  5. package/dist/core/block/rules/code-block.d.ts +2 -0
  6. package/dist/core/block/rules/code-block.js +73 -0
  7. package/dist/core/block/rules/code-fence.d.ts +15 -0
  8. package/dist/core/block/rules/code-fence.js +37 -0
  9. package/dist/core/block/rules/content-title.d.ts +12 -0
  10. package/dist/core/block/rules/content-title.js +70 -0
  11. package/dist/core/block/rules/footnotes.d.ts +9 -0
  12. package/dist/core/block/rules/footnotes.js +105 -0
  13. package/dist/core/block/rules/html.d.ts +7 -0
  14. package/dist/core/block/rules/html.js +48 -0
  15. package/dist/core/block/rules/image.d.ts +9 -0
  16. package/dist/core/block/rules/image.js +78 -0
  17. package/dist/core/block/rules/list.d.ts +3 -0
  18. package/dist/core/block/rules/list.js +275 -0
  19. package/dist/core/block/rules/paragraph.d.ts +6 -0
  20. package/dist/core/block/rules/paragraph.js +55 -0
  21. package/dist/core/block/rules/quote.d.ts +13 -0
  22. package/dist/core/block/rules/quote.js +104 -0
  23. package/dist/core/block/rules/table.d.ts +2 -0
  24. package/dist/core/block/rules/table.js +199 -0
  25. package/dist/core/block/runtime.d.ts +25 -0
  26. package/dist/core/block/runtime.js +125 -0
  27. package/dist/core/block/types.d.ts +2 -0
  28. package/dist/core/block-parser.js +186 -1321
  29. package/dist/core/parser.js +1 -1
  30. package/dist/html/convert.d.ts +10 -0
  31. package/dist/html/convert.js +23 -1
  32. package/dist/html/render/blocks.d.ts +15 -0
  33. package/dist/html/render/blocks.js +67 -13
  34. package/dist/html/render/html.d.ts +16 -0
  35. package/dist/html/render/html.js +53 -14
  36. package/dist/html/render/utils.d.ts +1 -0
  37. package/dist/html/theme/base/css.d.ts +1 -1
  38. package/dist/html/theme/base/css.js +50 -22
  39. package/dist/html/theme/dark/css.js +48 -0
  40. package/dist/html/theme/light/css.js +24 -0
  41. package/dist/html/theme/theme.d.ts +23 -1
  42. package/dist/html/theme/theme.js +242 -2
  43. package/package.json +5 -1
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.tryParseFootnotesBlock = tryParseFootnotesBlock;
4
+ exports.isFootnotesLine = isFootnotesLine;
5
+ const location_1 = require("../../location");
6
+ const lexer_1 = require("../../../lexer/lexer");
7
+ function tryParseFootnotesBlock(ctx) {
8
+ if (!isFootnotesLine(ctx.trimmedContent)) {
9
+ return null;
10
+ }
11
+ const rawLines = [ctx.lineInfo.raw];
12
+ const regionLines = [];
13
+ let jFoot = ctx.index + 1;
14
+ while (jFoot < ctx.lines.length) {
15
+ const nextRaw = ctx.lines[jFoot];
16
+ if (nextRaw === undefined) {
17
+ jFoot += 1;
18
+ continue;
19
+ }
20
+ const nextInfo = (0, lexer_1.getLineInfo)(nextRaw);
21
+ const nextTrimmed = nextInfo.content.trim();
22
+ if (nextTrimmed.length === 0) {
23
+ break;
24
+ }
25
+ rawLines.push(nextInfo.raw);
26
+ regionLines.push(nextInfo.content);
27
+ jFoot += 1;
28
+ }
29
+ const blockAttrs = ctx.buildBlockAttrs(ctx.lineInfo.tabCount);
30
+ let block;
31
+ if (ctx.pending.isDisabled) {
32
+ const disabled = {
33
+ type: 'disabledBlock',
34
+ raw: rawLines.join('\n'),
35
+ blockAttrs,
36
+ };
37
+ (0, location_1.setNodeLocation)(disabled, ctx.lineLocation);
38
+ block = disabled;
39
+ }
40
+ else {
41
+ const children = parseFootnoteDefs(regionLines, ctx.errors, ctx.parseBlocks);
42
+ const footnotesBlock = {
43
+ type: 'footnotes',
44
+ children,
45
+ blockAttrs,
46
+ };
47
+ (0, location_1.setNodeLocation)(footnotesBlock, ctx.lineLocation);
48
+ block = footnotesBlock;
49
+ }
50
+ ctx.commitBlock(block, blockAttrs);
51
+ return jFoot;
52
+ }
53
+ function isFootnotesLine(trimmed) {
54
+ return trimmed === '[footnotes]';
55
+ }
56
+ function parseFootnoteDefs(lines, errors, parseBlocks) {
57
+ const defs = [];
58
+ let i = 0;
59
+ while (i < lines.length) {
60
+ const raw = lines[i];
61
+ if (raw === undefined) {
62
+ i += 1;
63
+ continue;
64
+ }
65
+ const trimmed = raw.trim();
66
+ const match = trimmed.match(/^\[fn=([^\]]+)\]\s*$/);
67
+ if (!match) {
68
+ i += 1;
69
+ continue;
70
+ }
71
+ const idGroup = match[1];
72
+ if (!idGroup) {
73
+ i += 1;
74
+ continue;
75
+ }
76
+ const id = idGroup.trim();
77
+ i += 1;
78
+ const contentLines = [];
79
+ while (i < lines.length) {
80
+ const innerRaw = lines[i];
81
+ if (innerRaw === undefined) {
82
+ i += 1;
83
+ continue;
84
+ }
85
+ const innerTrimmed = innerRaw.trim();
86
+ if (innerTrimmed.length === 0) {
87
+ break;
88
+ }
89
+ if (/^\[fn=[^\]]+\]\s*$/.test(innerTrimmed)) {
90
+ break;
91
+ }
92
+ contentLines.push(innerRaw);
93
+ i += 1;
94
+ }
95
+ const contentSource = contentLines.join('\n');
96
+ const children = contentSource.length > 0 ? parseBlocks(contentSource, errors) : [];
97
+ const def = {
98
+ type: 'footnoteDef',
99
+ id,
100
+ children,
101
+ };
102
+ defs.push(def);
103
+ }
104
+ return defs;
105
+ }
@@ -0,0 +1,7 @@
1
+ import { BlockRuleContext } from './types';
2
+ interface HtmlBlockMatchResult {
3
+ source: string;
4
+ }
5
+ export declare function tryParseHtmlBlock(ctx: BlockRuleContext): number | null;
6
+ export declare function matchHtmlBlock(trimmed: string): HtmlBlockMatchResult | undefined;
7
+ export {};
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.tryParseHtmlBlock = tryParseHtmlBlock;
4
+ exports.matchHtmlBlock = matchHtmlBlock;
5
+ const location_1 = require("../../location");
6
+ function tryParseHtmlBlock(ctx) {
7
+ const htmlMatch = matchHtmlBlock(ctx.trimmedContent);
8
+ if (!htmlMatch) {
9
+ return null;
10
+ }
11
+ const blockAttrs = ctx.buildBlockAttrs(ctx.lineInfo.tabCount);
12
+ let block;
13
+ if (ctx.pending.isDisabled) {
14
+ const disabled = {
15
+ type: 'disabledBlock',
16
+ raw: ctx.lineInfo.raw,
17
+ blockAttrs,
18
+ };
19
+ (0, location_1.setNodeLocation)(disabled, ctx.lineLocation);
20
+ block = disabled;
21
+ }
22
+ else {
23
+ const htmlBlock = {
24
+ type: 'html',
25
+ source: htmlMatch.source,
26
+ blockAttrs,
27
+ };
28
+ (0, location_1.setNodeLocation)(htmlBlock, ctx.lineLocation);
29
+ block = htmlBlock;
30
+ }
31
+ ctx.commitBlock(block, blockAttrs);
32
+ return ctx.index + 1;
33
+ }
34
+ function matchHtmlBlock(trimmed) {
35
+ const m = trimmed.match(/^\[html\]\(([^)]+)\)\s*$/);
36
+ if (!m) {
37
+ return undefined;
38
+ }
39
+ const urlGroup = m[1];
40
+ if (urlGroup === undefined) {
41
+ return undefined;
42
+ }
43
+ const source = urlGroup.trim();
44
+ if (source.length === 0) {
45
+ return undefined;
46
+ }
47
+ return { source };
48
+ }
@@ -0,0 +1,9 @@
1
+ import { BlockRuleContext } from './types';
2
+ interface ImageBlockMatchResult {
3
+ url: string;
4
+ shape?: 'square' | 'rounded';
5
+ roundedRadius?: number;
6
+ }
7
+ export declare function tryParseImageBlock(ctx: BlockRuleContext): number | null;
8
+ export declare function matchImageBlock(trimmed: string): ImageBlockMatchResult | undefined;
9
+ export {};
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.tryParseImageBlock = tryParseImageBlock;
4
+ exports.matchImageBlock = matchImageBlock;
5
+ const location_1 = require("../../location");
6
+ function tryParseImageBlock(ctx) {
7
+ const imageMatch = matchImageBlock(ctx.trimmedContent);
8
+ if (!imageMatch) {
9
+ return null;
10
+ }
11
+ const blockAttrs = ctx.buildBlockAttrs(ctx.lineInfo.tabCount);
12
+ let block;
13
+ if (ctx.pending.isDisabled) {
14
+ const disabled = {
15
+ type: 'disabledBlock',
16
+ raw: ctx.lineInfo.raw,
17
+ blockAttrs,
18
+ };
19
+ (0, location_1.setNodeLocation)(disabled, ctx.lineLocation);
20
+ block = disabled;
21
+ }
22
+ else {
23
+ const image = {
24
+ type: 'image',
25
+ url: imageMatch.url,
26
+ shape: imageMatch.shape,
27
+ roundedRadius: imageMatch.roundedRadius,
28
+ blockAttrs,
29
+ };
30
+ (0, location_1.setNodeLocation)(image, ctx.lineLocation);
31
+ block = image;
32
+ }
33
+ ctx.commitBlock(block, blockAttrs);
34
+ return ctx.index + 1;
35
+ }
36
+ function matchImageBlock(trimmed) {
37
+ const m = trimmed.match(/^\[([^\]]+)\]\(([^)]+)\)\s*$/);
38
+ if (!m) {
39
+ return undefined;
40
+ }
41
+ const inside = m[1];
42
+ const urlGroup = m[2];
43
+ if (inside === undefined || urlGroup === undefined) {
44
+ return undefined;
45
+ }
46
+ const url = urlGroup.trim();
47
+ if (url.length === 0) {
48
+ return undefined;
49
+ }
50
+ const parts = inside
51
+ .split(',')
52
+ .map((part) => part.trim())
53
+ .filter((part) => part.length > 0);
54
+ if (!parts.includes('img')) {
55
+ return undefined;
56
+ }
57
+ let shape;
58
+ let roundedRadius;
59
+ for (const part of parts) {
60
+ if (part === 'rounded') {
61
+ shape = 'rounded';
62
+ continue;
63
+ }
64
+ if (part === 'square') {
65
+ shape = 'square';
66
+ continue;
67
+ }
68
+ const roundedMatch = part.match(/^rounded=([0-9.]+)$/);
69
+ if (roundedMatch && roundedMatch[1]) {
70
+ const num = parseFloat(roundedMatch[1]);
71
+ if (!isNaN(num) && num > 0) {
72
+ shape = 'rounded';
73
+ roundedRadius = num;
74
+ }
75
+ }
76
+ }
77
+ return { url, shape, roundedRadius };
78
+ }
@@ -0,0 +1,3 @@
1
+ import { BlockRuleContext } from './types';
2
+ export declare function tryParseListBlock(ctx: BlockRuleContext): number | null;
3
+ export declare function isListItemStart(content: string): boolean;
@@ -0,0 +1,275 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.tryParseListBlock = tryParseListBlock;
4
+ exports.isListItemStart = isListItemStart;
5
+ const location_1 = require("../../location");
6
+ const lexer_1 = require("../../../lexer/lexer");
7
+ const attribute_line_1 = require("./attribute-line");
8
+ const code_fence_1 = require("./code-fence");
9
+ function tryParseListBlock(ctx) {
10
+ const listFirstMatch = matchListItem(ctx.lineInfo.content, ctx.index + 1, ctx.lineInfo.tabCount + 1);
11
+ if (!listFirstMatch) {
12
+ return null;
13
+ }
14
+ const listMatches = [listFirstMatch];
15
+ const rawLines = [ctx.lineInfo.raw];
16
+ let jList = ctx.index + 1;
17
+ while (jList < ctx.lines.length) {
18
+ const nextRaw = ctx.lines[jList];
19
+ if (nextRaw === undefined) {
20
+ jList += 1;
21
+ continue;
22
+ }
23
+ const nextInfo = (0, lexer_1.getLineInfo)(nextRaw);
24
+ const nextTrimmed = nextInfo.content.trim();
25
+ if (nextTrimmed.length === 0) {
26
+ break;
27
+ }
28
+ if ((0, attribute_line_1.isAttributeOnlyLine)(nextTrimmed)) {
29
+ break;
30
+ }
31
+ const nextMatch = matchListItem(nextInfo.content, jList + 1, nextInfo.tabCount + 1);
32
+ if (!nextMatch) {
33
+ const codeFence = (0, code_fence_1.matchCodeFenceStart)(nextTrimmed);
34
+ const attrCodeFence = codeFence ? null : (0, code_fence_1.matchAttributedCodeFence)(nextTrimmed);
35
+ const effectiveFence = codeFence || attrCodeFence;
36
+ if (effectiveFence && listMatches.length > 0) {
37
+ const codeLines = [];
38
+ const fenceIndent = nextInfo.tabCount;
39
+ let kCode = jList + 1;
40
+ let codeClosed = false;
41
+ while (kCode < ctx.lines.length) {
42
+ const codeRaw = ctx.lines[kCode];
43
+ if (codeRaw === undefined) {
44
+ kCode += 1;
45
+ continue;
46
+ }
47
+ const codeInfo = (0, lexer_1.getLineInfo)(codeRaw);
48
+ const codeTrimmed = codeInfo.content.trim();
49
+ if ((0, code_fence_1.isCodeFenceEnd)(codeTrimmed)) {
50
+ codeClosed = true;
51
+ kCode += 1;
52
+ break;
53
+ }
54
+ let codeLine = codeRaw;
55
+ for (let t = 0; t < fenceIndent && codeLine.startsWith('\t'); t++) {
56
+ codeLine = codeLine.slice(1);
57
+ }
58
+ codeLines.push(codeLine);
59
+ kCode += 1;
60
+ }
61
+ if (codeClosed) {
62
+ const isHtmlBlock = attrCodeFence?.isHtml ?? false;
63
+ const codeBlock = {
64
+ type: 'code',
65
+ language: effectiveFence.language,
66
+ value: codeLines.join('\n'),
67
+ htmlLike: isHtmlBlock ? true : undefined,
68
+ };
69
+ (0, location_1.setNodeLocation)(codeBlock, { line: jList + 1, column: nextInfo.tabCount + 1 });
70
+ const lastItem = listMatches[listMatches.length - 1];
71
+ if (lastItem) {
72
+ if (!lastItem.childBlocks) {
73
+ lastItem.childBlocks = [];
74
+ }
75
+ lastItem.childBlocks.push(codeBlock);
76
+ }
77
+ jList = kCode;
78
+ continue;
79
+ }
80
+ }
81
+ break;
82
+ }
83
+ if (nextMatch.kind !== listFirstMatch.kind) {
84
+ break;
85
+ }
86
+ if (nextMatch.indent < listFirstMatch.indent) {
87
+ break;
88
+ }
89
+ listMatches.push(nextMatch);
90
+ rawLines.push(nextInfo.raw);
91
+ jList += 1;
92
+ }
93
+ const blockAttrs = ctx.buildBlockAttrs(ctx.lineInfo.tabCount);
94
+ let block;
95
+ if (ctx.pending.isDisabled) {
96
+ const disabled = {
97
+ type: 'disabledBlock',
98
+ raw: rawLines.join('\n'),
99
+ blockAttrs,
100
+ };
101
+ (0, location_1.setNodeLocation)(disabled, ctx.lineLocation);
102
+ block = disabled;
103
+ }
104
+ else {
105
+ const { items } = buildListItems(listMatches, 0, listFirstMatch.indent);
106
+ let listKind = listFirstMatch.kind;
107
+ const firstItem = items[0];
108
+ if (firstItem) {
109
+ listKind = firstItem.kind;
110
+ }
111
+ const listBlock = {
112
+ type: 'list',
113
+ kind: listKind,
114
+ orderedStyle: listKind === 'ordered' ? 'decimal' : undefined,
115
+ children: items,
116
+ blockAttrs,
117
+ };
118
+ (0, location_1.setNodeLocation)(listBlock, ctx.lineLocation);
119
+ block = listBlock;
120
+ }
121
+ ctx.commitBlock(block, blockAttrs);
122
+ return jList;
123
+ }
124
+ function isListItemStart(content) {
125
+ return matchListItem(content) !== undefined;
126
+ }
127
+ function matchListItem(content, line, column) {
128
+ const taskMatch = content.match(/^(-+)(\[(.|..)?\])(?:\s+(.*))?$/);
129
+ if (taskMatch) {
130
+ const dashes = taskMatch[1];
131
+ const markerGroup = taskMatch[2];
132
+ const markerInner = taskMatch[3];
133
+ const textGroup = taskMatch[4] || '';
134
+ if (!dashes || !markerGroup) {
135
+ return undefined;
136
+ }
137
+ const indent = dashes.length;
138
+ const taskStatus = mapTaskStatus(markerInner);
139
+ const text = textGroup.trimEnd();
140
+ const textColumn = getListTextColumn(column, taskMatch[0], textGroup);
141
+ return { kind: 'task', indent, taskStatus, text, line, column: textColumn };
142
+ }
143
+ const orderedMatch = content.match(/^(\d+(?:\.\d+)*)\.?\s*(\[(.|..)?\])?(?:\s+(.*))?$/);
144
+ if (orderedMatch) {
145
+ const ordinalGroup = orderedMatch[1];
146
+ const markerGroup = orderedMatch[2];
147
+ const markerInner = orderedMatch[3];
148
+ const textGroup = orderedMatch[4] || '';
149
+ if (!ordinalGroup) {
150
+ return undefined;
151
+ }
152
+ const ordinal = ordinalGroup;
153
+ const indent = ordinal.split('.').length;
154
+ const taskStatus = markerGroup ? mapTaskStatus(markerInner) : undefined;
155
+ const text = textGroup.trimEnd();
156
+ const textColumn = getListTextColumn(column, orderedMatch[0], textGroup);
157
+ return { kind: 'ordered', indent, ordinal, taskStatus, text, line, column: textColumn };
158
+ }
159
+ const foldableMatch = content.match(/^(\++)(\[(.|..)?\])?(?:\s+(.*))?$/);
160
+ if (foldableMatch) {
161
+ const pluses = foldableMatch[1];
162
+ const markerGroup = foldableMatch[2];
163
+ const markerInner = foldableMatch[3];
164
+ const textGroup = foldableMatch[4] || '';
165
+ if (!pluses) {
166
+ return undefined;
167
+ }
168
+ const indent = pluses.length;
169
+ const taskStatus = markerGroup ? mapTaskStatus(markerInner) : undefined;
170
+ const text = textGroup.trimEnd();
171
+ const textColumn = getListTextColumn(column, foldableMatch[0], textGroup);
172
+ return {
173
+ kind: 'foldable',
174
+ indent,
175
+ ordinal: ordinalFromIndent(indent),
176
+ taskStatus,
177
+ text,
178
+ line,
179
+ column: textColumn,
180
+ };
181
+ }
182
+ const bulletMatch = content.match(/^(-+)(?:\s+(.*))?$/);
183
+ if (bulletMatch) {
184
+ const dashes = bulletMatch[1];
185
+ const textGroup = bulletMatch[2] || '';
186
+ if (!dashes) {
187
+ return undefined;
188
+ }
189
+ const indent = dashes.length;
190
+ const text = textGroup.trimEnd();
191
+ const textColumn = getListTextColumn(column, bulletMatch[0], textGroup);
192
+ return { kind: 'bullet', indent, text, line, column: textColumn };
193
+ }
194
+ return undefined;
195
+ }
196
+ function getListTextColumn(baseColumn, matchText, rawText) {
197
+ if (baseColumn === undefined) {
198
+ return undefined;
199
+ }
200
+ const prefixLength = matchText.length - rawText.length;
201
+ return baseColumn + Math.max(0, prefixLength);
202
+ }
203
+ function mapTaskStatus(markerInner) {
204
+ if (!markerInner || markerInner === '') {
205
+ return 'unknown';
206
+ }
207
+ if (markerInner === 'o') {
208
+ return 'in_progress';
209
+ }
210
+ if (markerInner === 'x') {
211
+ return 'not_done';
212
+ }
213
+ if (markerInner === 'v') {
214
+ return 'done';
215
+ }
216
+ return 'unknown';
217
+ }
218
+ function ordinalFromIndent(indent) {
219
+ if (indent <= 0) {
220
+ return '1';
221
+ }
222
+ return Array(indent).fill('1').join('.');
223
+ }
224
+ function buildListItems(matches, startIndex, baseIndent) {
225
+ const items = [];
226
+ let index = startIndex;
227
+ while (index < matches.length) {
228
+ const current = matches[index];
229
+ if (!current) {
230
+ break;
231
+ }
232
+ if (current.indent < baseIndent) {
233
+ break;
234
+ }
235
+ if (current.indent > baseIndent) {
236
+ break;
237
+ }
238
+ const paragraph = {
239
+ type: 'paragraph',
240
+ children: [{ type: 'text', value: current.text }],
241
+ };
242
+ if (current.line !== undefined && current.column !== undefined) {
243
+ (0, location_1.setNodeLocation)(paragraph, {
244
+ line: current.line,
245
+ column: current.column,
246
+ });
247
+ }
248
+ const childrenBlocks = [paragraph];
249
+ if (current.childBlocks && current.childBlocks.length > 0) {
250
+ childrenBlocks.push(...current.childBlocks);
251
+ }
252
+ index += 1;
253
+ const next = matches[index];
254
+ if (next && next.indent > current.indent) {
255
+ const childResult = buildListItems(matches, index, next.indent);
256
+ childrenBlocks.push({
257
+ type: 'list',
258
+ kind: next.kind,
259
+ orderedStyle: next.kind === 'ordered' ? 'decimal' : undefined,
260
+ children: childResult.items,
261
+ });
262
+ index = childResult.nextIndex;
263
+ }
264
+ const item = {
265
+ type: 'listItem',
266
+ kind: current.kind,
267
+ ordinal: current.ordinal,
268
+ taskStatus: current.taskStatus,
269
+ indent: current.indent,
270
+ children: childrenBlocks,
271
+ };
272
+ items.push(item);
273
+ }
274
+ return { items, nextIndex: index };
275
+ }
@@ -0,0 +1,6 @@
1
+ import { BlockRuleContext } from './types';
2
+ interface ParagraphRuleContext extends BlockRuleContext {
3
+ shouldStopParagraph: (content: string, trimmed: string) => boolean;
4
+ }
5
+ export declare function tryParseParagraphBlock(ctx: ParagraphRuleContext): number;
6
+ export {};
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.tryParseParagraphBlock = tryParseParagraphBlock;
4
+ const location_1 = require("../../location");
5
+ const lexer_1 = require("../../../lexer/lexer");
6
+ const attribute_line_1 = require("./attribute-line");
7
+ function tryParseParagraphBlock(ctx) {
8
+ const blockRawLines = [ctx.lineInfo.raw];
9
+ const blockTextLines = [ctx.lineInfo.content];
10
+ let j = ctx.index + 1;
11
+ while (j < ctx.lines.length) {
12
+ const nextRaw = ctx.lines[j];
13
+ if (nextRaw === undefined) {
14
+ j += 1;
15
+ continue;
16
+ }
17
+ const nextInfo = (0, lexer_1.getLineInfo)(nextRaw);
18
+ const nextTrimmed = nextInfo.content.trim();
19
+ if (nextTrimmed.length === 0) {
20
+ break;
21
+ }
22
+ if ((0, attribute_line_1.isAttributeOnlyLine)(nextTrimmed)) {
23
+ break;
24
+ }
25
+ if (ctx.shouldStopParagraph(nextInfo.content, nextTrimmed)) {
26
+ break;
27
+ }
28
+ blockRawLines.push(nextInfo.raw);
29
+ blockTextLines.push(nextInfo.content);
30
+ j += 1;
31
+ }
32
+ const blockText = blockTextLines.join('\n');
33
+ const blockAttrs = ctx.buildBlockAttrs(ctx.lineInfo.tabCount);
34
+ let block;
35
+ if (ctx.pending.isDisabled) {
36
+ const disabled = {
37
+ type: 'disabledBlock',
38
+ raw: blockRawLines.join('\n'),
39
+ blockAttrs,
40
+ };
41
+ (0, location_1.setNodeLocation)(disabled, ctx.lineLocation);
42
+ block = disabled;
43
+ }
44
+ else {
45
+ const paragraph = {
46
+ type: 'paragraph',
47
+ children: [{ type: 'text', value: blockText }],
48
+ blockAttrs,
49
+ };
50
+ (0, location_1.setNodeLocation)(paragraph, ctx.lineLocation);
51
+ block = paragraph;
52
+ }
53
+ ctx.commitBlock(block, blockAttrs, { allowTag: !ctx.pending.isDisabled });
54
+ return j;
55
+ }
@@ -0,0 +1,13 @@
1
+ import { BlockNode } from '../../ast';
2
+ import { ParseError } from '../../errors';
3
+ import { BlockRuleContext } from './types';
4
+ interface QuoteRuleContext extends BlockRuleContext {
5
+ parseBlocks: (source: string, errors: ParseError[]) => BlockNode[];
6
+ }
7
+ interface QuoteMatchResult {
8
+ level: number;
9
+ text: string;
10
+ }
11
+ export declare function tryParseQuoteBlock(ctx: QuoteRuleContext): number | null;
12
+ export declare function matchQuote(content: string): QuoteMatchResult | undefined;
13
+ export {};