@xyd-js/content 0.1.0-xyd.8 → 0.1.0-xyd.97

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 (92) hide show
  1. package/CHANGELOG.md +1157 -0
  2. package/ISSUES.md +1 -0
  3. package/LICENSE +21 -0
  4. package/TODO.md +2 -0
  5. package/dist/index.d.ts +24 -5
  6. package/dist/index.js +212 -566
  7. package/dist/index.js.map +1 -1
  8. package/dist/md.d.ts +69 -0
  9. package/dist/md.js +23396 -0
  10. package/dist/md.js.map +1 -0
  11. package/dist/mdToc-NBBxMJ4l.d.ts +12 -0
  12. package/dist/vite.d.ts +103 -9
  13. package/dist/vite.js +19992 -170
  14. package/dist/vite.js.map +1 -1
  15. package/package.json +26 -7
  16. package/packages/md/index.ts +17 -8
  17. package/packages/md/plugins/component-directives/index.ts +3 -0
  18. package/packages/md/plugins/component-directives/mdComponentDirective.ts +524 -0
  19. package/packages/md/plugins/component-directives/types.ts +1 -0
  20. package/packages/md/plugins/component-directives/utils.ts +27 -0
  21. package/packages/md/plugins/composer/__fixtures__/1.single-example/input.md +7 -0
  22. package/packages/md/plugins/composer/__fixtures__/1.single-example/output.json +63 -0
  23. package/packages/md/plugins/composer/__fixtures__/2.single-example-with-name/input.md +7 -0
  24. package/packages/md/plugins/composer/__fixtures__/2.single-example-with-name/output.json +63 -0
  25. package/packages/md/plugins/composer/__fixtures__/3.multiple-examples/input.md +15 -0
  26. package/packages/md/plugins/composer/__fixtures__/3.multiple-examples/output.json +122 -0
  27. package/packages/md/plugins/composer/__fixtures__/4.example-groups/input.md +23 -0
  28. package/packages/md/plugins/composer/__fixtures__/4.example-groups/output.json +184 -0
  29. package/packages/md/plugins/composer/__tests__/mdComposer.test.ts +41 -0
  30. package/packages/md/plugins/composer/__tests__/testHelpers.ts +48 -0
  31. package/packages/md/plugins/composer/index.ts +1 -0
  32. package/packages/md/plugins/composer/mdComposer.ts +146 -0
  33. package/packages/md/plugins/developer-writing/index.ts +3 -0
  34. package/packages/md/plugins/developer-writing/mdCodeRehype.ts +78 -0
  35. package/packages/md/plugins/functions/__fixtures__/external.ts +4 -0
  36. package/packages/md/plugins/functions/__fixtures__/test.js +11 -0
  37. package/packages/md/plugins/functions/__fixtures__/test.py +9 -0
  38. package/packages/md/plugins/functions/__fixtures__/test.ts +18 -0
  39. package/packages/md/plugins/functions/__tests__/mdFunctionImportCode.test.ts +295 -0
  40. package/packages/md/plugins/functions/__tests__/parseFunctionCall.test.ts +47 -0
  41. package/packages/md/plugins/functions/__tests__/testHelpers.ts +71 -0
  42. package/packages/md/plugins/functions/index.ts +11 -0
  43. package/packages/md/plugins/functions/mdFunctionChangelog.ts +124 -0
  44. package/packages/md/plugins/functions/mdFunctionImportCode.ts +83 -0
  45. package/packages/md/plugins/functions/mdFunctionUniform.ts +79 -0
  46. package/packages/md/plugins/functions/types.ts +6 -0
  47. package/packages/md/plugins/functions/uniformProcessor.ts +349 -0
  48. package/packages/md/plugins/functions/utils.ts +423 -0
  49. package/packages/md/plugins/index.ts +56 -9
  50. package/packages/md/plugins/mdCode.ts +67 -0
  51. package/packages/md/plugins/mdHeadingId.ts +47 -0
  52. package/packages/md/plugins/mdPage.ts +35 -0
  53. package/packages/md/plugins/{md-themeSettings.ts → mdThemeSettings.ts} +8 -0
  54. package/packages/md/plugins/mdToc.ts +224 -0
  55. package/packages/md/plugins/meta/index.ts +1 -0
  56. package/packages/md/plugins/meta/mdMeta.ts +189 -0
  57. package/packages/md/plugins/output-variables/__fixtures__/1.simple/input.md +22 -0
  58. package/packages/md/plugins/output-variables/__fixtures__/1.simple/output.json +191 -0
  59. package/packages/md/plugins/output-variables/__fixtures__/2.multiple-vars/input.md +21 -0
  60. package/packages/md/plugins/output-variables/__fixtures__/2.multiple-vars/output.json +127 -0
  61. package/packages/md/plugins/output-variables/__tests__/index.test.ts +28 -0
  62. package/packages/md/plugins/output-variables/__tests__/testHelpers.ts +36 -0
  63. package/packages/md/plugins/output-variables/index.ts +1 -0
  64. package/packages/md/plugins/output-variables/lib/const.ts +4 -0
  65. package/packages/md/plugins/output-variables/lib/factoryAttributes.ts +350 -0
  66. package/packages/md/plugins/output-variables/lib/factoryLabel.ts +135 -0
  67. package/packages/md/plugins/output-variables/lib/factoryName.ts +59 -0
  68. package/packages/md/plugins/output-variables/lib/index.ts +21 -0
  69. package/packages/md/plugins/output-variables/lib/outputVarsContainer.ts +328 -0
  70. package/packages/md/plugins/output-variables/lib/util.ts +494 -0
  71. package/packages/md/plugins/output-variables/remarkOutputVars.ts +22 -0
  72. package/packages/md/plugins/rehypeHeading.ts +50 -0
  73. package/packages/md/plugins/types.ts +15 -0
  74. package/packages/md/plugins/utils/componentLike.ts +72 -0
  75. package/packages/md/plugins/utils/index.ts +2 -0
  76. package/packages/md/plugins/utils/mdParameters.test.ts +114 -0
  77. package/packages/md/plugins/utils/mdParameters.ts +249 -0
  78. package/packages/md/plugins/utils/mdastTypes.ts +42 -0
  79. package/packages/md/search/index.ts +251 -0
  80. package/packages/md/search/types.ts +36 -0
  81. package/packages/vite/index.ts +8 -2
  82. package/src/fs.ts +51 -36
  83. package/src/index.ts +4 -4
  84. package/src/navigation.ts +50 -38
  85. package/src/types.ts +8 -0
  86. package/tsconfig.json +31 -8
  87. package/tsup.config.ts +2 -0
  88. package/vitest.config.ts +17 -0
  89. package/packages/md/plugins/md-code.ts +0 -15
  90. package/packages/md/plugins/md-codegroup.ts +0 -36
  91. package/packages/md/plugins/md-page.ts +0 -22
  92. package/packages/md/plugins/md-toc.ts +0 -133
@@ -0,0 +1,127 @@
1
+ {
2
+ "type": "root",
3
+ "children": [
4
+ {
5
+ "type": "outputVars",
6
+ "name": "example",
7
+ "attributes": {},
8
+ "children": [
9
+ {
10
+ "type": "code",
11
+ "lang": "bash",
12
+ "meta": "npm",
13
+ "value": "npm i -g xyd-js",
14
+ "position": {
15
+ "start": {
16
+ "line": 2,
17
+ "column": 3,
18
+ "offset": 13
19
+ },
20
+ "end": {
21
+ "line": 4,
22
+ "column": 6,
23
+ "offset": 48
24
+ }
25
+ }
26
+ },
27
+ {
28
+ "type": "code",
29
+ "lang": "bash",
30
+ "meta": "yarn",
31
+ "value": "yarn global add xyd-js",
32
+ "position": {
33
+ "start": {
34
+ "line": 6,
35
+ "column": 3,
36
+ "offset": 52
37
+ },
38
+ "end": {
39
+ "line": 8,
40
+ "column": 6,
41
+ "offset": 95
42
+ }
43
+ }
44
+ },
45
+ {
46
+ "type": "code",
47
+ "lang": "bash",
48
+ "meta": "pnpm",
49
+ "value": "pnpm add -g xyd-js",
50
+ "position": {
51
+ "start": {
52
+ "line": 10,
53
+ "column": 3,
54
+ "offset": 99
55
+ },
56
+ "end": {
57
+ "line": 12,
58
+ "column": 6,
59
+ "offset": 138
60
+ }
61
+ }
62
+ }
63
+ ],
64
+ "position": {
65
+ "start": {
66
+ "line": 1,
67
+ "column": 1,
68
+ "offset": 0
69
+ },
70
+ "end": {
71
+ "line": 13,
72
+ "column": 4,
73
+ "offset": 142
74
+ }
75
+ }
76
+ },
77
+ {
78
+ "type": "outputVars",
79
+ "name": "example2",
80
+ "attributes": {},
81
+ "children": [
82
+ {
83
+ "type": "code",
84
+ "lang": "tsx",
85
+ "meta": null,
86
+ "value": "function() {\n return <div> Hello World </div>\n}",
87
+ "position": {
88
+ "start": {
89
+ "line": 16,
90
+ "column": 3,
91
+ "offset": 158
92
+ },
93
+ "end": {
94
+ "line": 20,
95
+ "column": 6,
96
+ "offset": 225
97
+ }
98
+ }
99
+ }
100
+ ],
101
+ "position": {
102
+ "start": {
103
+ "line": 15,
104
+ "column": 1,
105
+ "offset": 144
106
+ },
107
+ "end": {
108
+ "line": 21,
109
+ "column": 4,
110
+ "offset": 229
111
+ }
112
+ }
113
+ }
114
+ ],
115
+ "position": {
116
+ "start": {
117
+ "line": 1,
118
+ "column": 1,
119
+ "offset": 0
120
+ },
121
+ "end": {
122
+ "line": 22,
123
+ "column": 1,
124
+ "offset": 230
125
+ }
126
+ }
127
+ }
@@ -0,0 +1,28 @@
1
+ import { describe, it } from 'vitest';
2
+
3
+ import { testFixture } from './testHelpers';
4
+
5
+ const tests = [
6
+ {
7
+ name: "1.simple",
8
+ description: "A simple example of output variables",
9
+ input: "1.simple/input.md",
10
+ output: "1.simple/output.json"
11
+ },
12
+ {
13
+ name: "2.multiple-vars",
14
+ description: "A example of multiple output variables",
15
+ input: "2.multiple-vars/input.md",
16
+ output: "2.multiple-vars/output.json"
17
+ }
18
+
19
+ ]
20
+
21
+ describe("outputVars", () => {
22
+ tests.forEach((test) => {
23
+ it(`[${test.name}]: ${test.description}`, async () => {
24
+ await testFixture(test.name);
25
+ });
26
+ });
27
+ });
28
+
@@ -0,0 +1,36 @@
1
+ import path from 'node:path';
2
+ import fs from 'node:fs';
3
+
4
+ import { remark } from 'remark'
5
+ import { expect } from 'vitest';
6
+
7
+ import { remarkOutputVars } from '../remarkOutputVars';
8
+
9
+ const fixturesDir = path.resolve(__dirname, '../__fixtures__');
10
+
11
+ // Helper function to run a test with a specific fixture
12
+ export async function testFixture(fixtureName: string) {
13
+ const input = readFixture(`${fixtureName}/input.md`);
14
+ const expectedOutput = readFixtureOutput(`${fixtureName}/output.json`);
15
+
16
+ const result = await processMarkdown(input)
17
+ expect(result).toEqual(expectedOutput);
18
+ }
19
+
20
+ // Helper function to read fixture files
21
+ function readFixture(name: string) {
22
+ const fixturePath = path.join(fixturesDir, name);
23
+ return fs.readFileSync(fixturePath, "utf8");
24
+ }
25
+
26
+ // Helper function to read fixture output
27
+ function readFixtureOutput(name: string) {
28
+ const fixturePath = path.join(fixturesDir, name);
29
+ return JSON.parse(fs.readFileSync(fixturePath, "utf8"));
30
+ }
31
+
32
+ function processMarkdown(input: string) {
33
+ return remark()
34
+ .use(remarkOutputVars)
35
+ .parse(input)
36
+ }
@@ -0,0 +1 @@
1
+ export { remarkOutputVars as outputVars } from './remarkOutputVars'
@@ -0,0 +1,4 @@
1
+ import { codes } from 'micromark-util-symbol'
2
+
3
+ export const PRIMARY_SYMBOL = codes.lessThan
4
+ export const PRIMARY_SYMBOL_STR = '>'
@@ -0,0 +1,350 @@
1
+ /**
2
+ * @import {Code, Effects, State, TokenType} from 'micromark-util-types'
3
+ */
4
+
5
+ import {ok as assert} from 'devlop'
6
+ import {factorySpace} from 'micromark-factory-space'
7
+ import {factoryWhitespace} from 'micromark-factory-whitespace'
8
+ import {
9
+ markdownLineEnding,
10
+ markdownLineEndingOrSpace,
11
+ markdownSpace,
12
+ unicodePunctuation,
13
+ unicodeWhitespace
14
+ } from 'micromark-util-character'
15
+ import {codes, types} from 'micromark-util-symbol'
16
+
17
+ import { PRIMARY_SYMBOL } from './const'
18
+
19
+ /**
20
+ * @param {Effects} effects
21
+ * @param {State} ok
22
+ * @param {State} nok
23
+ * @param {TokenType} attributesType
24
+ * @param {TokenType} attributesMarkerType
25
+ * @param {TokenType} attributeType
26
+ * @param {TokenType} attributeIdType
27
+ * @param {TokenType} attributeClassType
28
+ * @param {TokenType} attributeNameType
29
+ * @param {TokenType} attributeInitializerType
30
+ * @param {TokenType} attributeValueLiteralType
31
+ * @param {TokenType} attributeValueType
32
+ * @param {TokenType} attributeValueMarker
33
+ * @param {TokenType} attributeValueData
34
+ * @param {boolean | undefined} [disallowEol=false]
35
+ */
36
+ export function factoryAttributes(
37
+ effects,
38
+ ok,
39
+ nok,
40
+ attributesType,
41
+ attributesMarkerType,
42
+ attributeType,
43
+ attributeIdType,
44
+ attributeClassType,
45
+ attributeNameType,
46
+ attributeInitializerType,
47
+ attributeValueLiteralType,
48
+ attributeValueType,
49
+ attributeValueMarker,
50
+ attributeValueData,
51
+ disallowEol
52
+ ) {
53
+ /** @type {TokenType} */
54
+ let type
55
+ /** @type {Code | undefined} */
56
+ let marker
57
+
58
+ return start
59
+
60
+ /** @type {State} */
61
+ function start(code) {
62
+ assert(code === codes.leftCurlyBrace, 'expected `{`')
63
+ effects.enter(attributesType)
64
+ effects.enter(attributesMarkerType)
65
+ effects.consume(code)
66
+ effects.exit(attributesMarkerType)
67
+ return between
68
+ }
69
+
70
+ /** @type {State} */
71
+ function between(code) {
72
+ if (code === codes.numberSign) {
73
+ type = attributeIdType
74
+ return shortcutStart(code)
75
+ }
76
+
77
+ if (code === codes.dot) {
78
+ type = attributeClassType
79
+ return shortcutStart(code)
80
+ }
81
+
82
+ if (disallowEol && markdownSpace(code)) {
83
+ return factorySpace(effects, between, types.whitespace)(code)
84
+ }
85
+
86
+ if (!disallowEol && markdownLineEndingOrSpace(code)) {
87
+ return factoryWhitespace(effects, between)(code)
88
+ }
89
+
90
+ if (
91
+ code === codes.eof ||
92
+ markdownLineEnding(code) ||
93
+ unicodeWhitespace(code) ||
94
+ (unicodePunctuation(code) &&
95
+ code !== codes.dash &&
96
+ code !== codes.underscore)
97
+ ) {
98
+ return end(code)
99
+ }
100
+
101
+ effects.enter(attributeType)
102
+ effects.enter(attributeNameType)
103
+ effects.consume(code)
104
+ return name
105
+ }
106
+
107
+ /** @type {State} */
108
+ function shortcutStart(code) {
109
+ // Assume it’s registered.
110
+ const markerType = /** @type {TokenType} */ (type + 'Marker')
111
+ effects.enter(attributeType)
112
+ effects.enter(type)
113
+ effects.enter(markerType)
114
+ effects.consume(code)
115
+ effects.exit(markerType)
116
+ return shortcutStartAfter
117
+ }
118
+
119
+ /** @type {State} */
120
+ function shortcutStartAfter(code) {
121
+ if (
122
+ code === codes.eof ||
123
+ code === codes.quotationMark ||
124
+ code === codes.numberSign ||
125
+ code === codes.apostrophe ||
126
+ code === codes.dot ||
127
+ code === codes.lessThan ||
128
+ code === codes.equalsTo ||
129
+ code === codes.greaterThan ||
130
+ code === codes.graveAccent ||
131
+ code === codes.rightCurlyBrace ||
132
+ markdownLineEndingOrSpace(code)
133
+ ) {
134
+ return nok(code)
135
+ }
136
+
137
+ // Assume it’s registered.
138
+ const valueType = /** @type {TokenType} */ (type + 'Value')
139
+ effects.enter(valueType)
140
+ effects.consume(code)
141
+ return shortcut
142
+ }
143
+
144
+ /** @type {State} */
145
+ function shortcut(code) {
146
+ if (
147
+ code === codes.eof ||
148
+ code === codes.quotationMark ||
149
+ code === codes.apostrophe ||
150
+ code === codes.lessThan ||
151
+ code === codes.equalsTo ||
152
+ code === codes.greaterThan ||
153
+ code === codes.graveAccent
154
+ ) {
155
+ return nok(code)
156
+ }
157
+
158
+ if (
159
+ code === codes.numberSign ||
160
+ code === codes.dot ||
161
+ code === codes.rightCurlyBrace ||
162
+ markdownLineEndingOrSpace(code)
163
+ ) {
164
+ // Assume it’s registered.
165
+ const valueType = /** @type {TokenType} */ (type + 'Value')
166
+ effects.exit(valueType)
167
+ effects.exit(type)
168
+ effects.exit(attributeType)
169
+ return between(code)
170
+ }
171
+
172
+ effects.consume(code)
173
+ return shortcut
174
+ }
175
+
176
+ /** @type {State} */
177
+ function name(code) {
178
+ if (
179
+ code === codes.eof ||
180
+ markdownLineEnding(code) ||
181
+ unicodeWhitespace(code) ||
182
+ (unicodePunctuation(code) &&
183
+ code !== codes.dash &&
184
+ code !== codes.dot &&
185
+ code !== PRIMARY_SYMBOL &&
186
+ code !== codes.underscore)
187
+ ) {
188
+ effects.exit(attributeNameType)
189
+
190
+ if (disallowEol && markdownSpace(code)) {
191
+ return factorySpace(effects, nameAfter, types.whitespace)(code)
192
+ }
193
+
194
+ if (!disallowEol && markdownLineEndingOrSpace(code)) {
195
+ return factoryWhitespace(effects, nameAfter)(code)
196
+ }
197
+
198
+ return nameAfter(code)
199
+ }
200
+
201
+ effects.consume(code)
202
+ return name
203
+ }
204
+
205
+ /** @type {State} */
206
+ function nameAfter(code) {
207
+ if (code === codes.equalsTo) {
208
+ effects.enter(attributeInitializerType)
209
+ effects.consume(code)
210
+ effects.exit(attributeInitializerType)
211
+ return valueBefore
212
+ }
213
+
214
+ // Attribute w/o value.
215
+ effects.exit(attributeType)
216
+ return between(code)
217
+ }
218
+
219
+ /** @type {State} */
220
+ function valueBefore(code) {
221
+ if (
222
+ code === codes.eof ||
223
+ code === codes.lessThan ||
224
+ code === codes.equalsTo ||
225
+ code === codes.greaterThan ||
226
+ code === codes.graveAccent ||
227
+ code === codes.rightCurlyBrace ||
228
+ (disallowEol && markdownLineEnding(code))
229
+ ) {
230
+ return nok(code)
231
+ }
232
+
233
+ if (code === codes.quotationMark || code === codes.apostrophe) {
234
+ effects.enter(attributeValueLiteralType)
235
+ effects.enter(attributeValueMarker)
236
+ effects.consume(code)
237
+ effects.exit(attributeValueMarker)
238
+ marker = code
239
+ return valueQuotedStart
240
+ }
241
+
242
+ if (disallowEol && markdownSpace(code)) {
243
+ return factorySpace(effects, valueBefore, types.whitespace)(code)
244
+ }
245
+
246
+ if (!disallowEol && markdownLineEndingOrSpace(code)) {
247
+ return factoryWhitespace(effects, valueBefore)(code)
248
+ }
249
+
250
+ effects.enter(attributeValueType)
251
+ effects.enter(attributeValueData)
252
+ effects.consume(code)
253
+ marker = undefined
254
+ return valueUnquoted
255
+ }
256
+
257
+ /** @type {State} */
258
+ function valueUnquoted(code) {
259
+ if (
260
+ code === codes.eof ||
261
+ code === codes.quotationMark ||
262
+ code === codes.apostrophe ||
263
+ code === codes.lessThan ||
264
+ code === codes.equalsTo ||
265
+ code === codes.greaterThan ||
266
+ code === codes.graveAccent
267
+ ) {
268
+ return nok(code)
269
+ }
270
+
271
+ if (code === codes.rightCurlyBrace || markdownLineEndingOrSpace(code)) {
272
+ effects.exit(attributeValueData)
273
+ effects.exit(attributeValueType)
274
+ effects.exit(attributeType)
275
+ return between(code)
276
+ }
277
+
278
+ effects.consume(code)
279
+ return valueUnquoted
280
+ }
281
+
282
+ /** @type {State} */
283
+ function valueQuotedStart(code) {
284
+ if (code === marker) {
285
+ effects.enter(attributeValueMarker)
286
+ effects.consume(code)
287
+ effects.exit(attributeValueMarker)
288
+ effects.exit(attributeValueLiteralType)
289
+ effects.exit(attributeType)
290
+ return valueQuotedAfter
291
+ }
292
+
293
+ effects.enter(attributeValueType)
294
+ return valueQuotedBetween(code)
295
+ }
296
+
297
+ /** @type {State} */
298
+ function valueQuotedBetween(code) {
299
+ if (code === marker) {
300
+ effects.exit(attributeValueType)
301
+ return valueQuotedStart(code)
302
+ }
303
+
304
+ if (code === codes.eof) {
305
+ return nok(code)
306
+ }
307
+
308
+ // Note: blank lines can’t exist in content.
309
+ if (markdownLineEnding(code)) {
310
+ return disallowEol
311
+ ? nok(code)
312
+ : factoryWhitespace(effects, valueQuotedBetween)(code)
313
+ }
314
+
315
+ effects.enter(attributeValueData)
316
+ effects.consume(code)
317
+ return valueQuoted
318
+ }
319
+
320
+ /** @type {State} */
321
+ function valueQuoted(code) {
322
+ if (code === marker || code === codes.eof || markdownLineEnding(code)) {
323
+ effects.exit(attributeValueData)
324
+ return valueQuotedBetween(code)
325
+ }
326
+
327
+ effects.consume(code)
328
+ return valueQuoted
329
+ }
330
+
331
+ /** @type {State} */
332
+ function valueQuotedAfter(code) {
333
+ return code === codes.rightCurlyBrace || markdownLineEndingOrSpace(code)
334
+ ? between(code)
335
+ : end(code)
336
+ }
337
+
338
+ /** @type {State} */
339
+ function end(code) {
340
+ if (code === codes.rightCurlyBrace) {
341
+ effects.enter(attributesMarkerType)
342
+ effects.consume(code)
343
+ effects.exit(attributesMarkerType)
344
+ effects.exit(attributesType)
345
+ return ok
346
+ }
347
+
348
+ return nok(code)
349
+ }
350
+ }
@@ -0,0 +1,135 @@
1
+ /**
2
+ * @import {Code, Effects, State, Token, TokenType} from 'micromark-util-types'
3
+ */
4
+
5
+ import {ok as assert} from 'devlop'
6
+ import {markdownLineEnding} from 'micromark-util-character'
7
+ import {codes, constants, types} from 'micromark-util-symbol'
8
+
9
+ // This is a fork of:
10
+ // <https://github.com/micromark/micromark/tree/main/packages/micromark-factory-label>
11
+ // to allow empty labels, balanced brackets (such as for nested directives),
12
+ // text instead of strings, and optionally disallows EOLs.
13
+
14
+ /**
15
+ * @param {Effects} effects
16
+ * @param {State} ok
17
+ * @param {State} nok
18
+ * @param {TokenType} type
19
+ * @param {TokenType} markerType
20
+ * @param {TokenType} stringType
21
+ * @param {boolean | undefined} [disallowEol=false]
22
+ */
23
+ export function factoryLabel(
24
+ effects,
25
+ ok,
26
+ nok,
27
+ type,
28
+ markerType,
29
+ stringType,
30
+ disallowEol
31
+ ) {
32
+ let size = 0
33
+ let balance = 0
34
+ /** @type {Token | undefined} */
35
+ let previous
36
+
37
+ return start
38
+
39
+ /** @type {State} */
40
+ function start(code) {
41
+ assert(code === codes.leftSquareBracket, 'expected `[`')
42
+ effects.enter(type)
43
+ effects.enter(markerType)
44
+ effects.consume(code)
45
+ effects.exit(markerType)
46
+ return afterStart
47
+ }
48
+
49
+ /** @type {State} */
50
+ function afterStart(code) {
51
+ if (code === codes.rightSquareBracket) {
52
+ effects.enter(markerType)
53
+ effects.consume(code)
54
+ effects.exit(markerType)
55
+ effects.exit(type)
56
+ return ok
57
+ }
58
+
59
+ effects.enter(stringType)
60
+ return lineStart(code)
61
+ }
62
+
63
+ /** @type {State} */
64
+ function lineStart(code) {
65
+ if (code === codes.rightSquareBracket && !balance) {
66
+ return atClosingBrace(code)
67
+ }
68
+
69
+ const token = effects.enter(types.chunkText, {
70
+ _contentTypeTextTrailing: true,
71
+ contentType: constants.contentTypeText,
72
+ previous
73
+ })
74
+ if (previous) previous.next = token
75
+ previous = token
76
+ return data(code)
77
+ }
78
+
79
+ /** @type {State} */
80
+ function data(code) {
81
+ if (code === codes.eof || size > constants.linkReferenceSizeMax) {
82
+ return nok(code)
83
+ }
84
+
85
+ if (
86
+ code === codes.leftSquareBracket &&
87
+ ++balance > constants.linkResourceDestinationBalanceMax
88
+ ) {
89
+ return nok(code)
90
+ }
91
+
92
+ if (code === codes.rightSquareBracket && !balance--) {
93
+ effects.exit(types.chunkText)
94
+ return atClosingBrace(code)
95
+ }
96
+
97
+ if (markdownLineEnding(code)) {
98
+ if (disallowEol) {
99
+ return nok(code)
100
+ }
101
+
102
+ effects.consume(code)
103
+ effects.exit(types.chunkText)
104
+ return lineStart
105
+ }
106
+
107
+ effects.consume(code)
108
+ return code === codes.backslash ? dataEscape : data
109
+ }
110
+
111
+ /** @type {State} */
112
+ function dataEscape(code) {
113
+ if (
114
+ code === codes.leftSquareBracket ||
115
+ code === codes.backslash ||
116
+ code === codes.rightSquareBracket
117
+ ) {
118
+ effects.consume(code)
119
+ size++
120
+ return data
121
+ }
122
+
123
+ return data(code)
124
+ }
125
+
126
+ /** @type {State} */
127
+ function atClosingBrace(code) {
128
+ effects.exit(stringType)
129
+ effects.enter(markerType)
130
+ effects.consume(code)
131
+ effects.exit(markerType)
132
+ effects.exit(type)
133
+ return ok
134
+ }
135
+ }