@markup-carve/carve-grammars 0.1.2

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.
@@ -0,0 +1,537 @@
1
+ /**
2
+ * Carve language definition for highlight.js
3
+ *
4
+ * Carve is a Djot-derived markup language with distinct inline delimiters:
5
+ * emphasis is /text/ (not _text_), underline is _text_, strikethrough is
6
+ * ~text~ (Djot uses ~ for subscript), subscript is ,text, and highlight is
7
+ * =text= (Djot uses {=text=}). Strong (*text*), superscript (^text^),
8
+ * insert ({+text+}) and delete ({-text-}) match Djot.
9
+ *
10
+ * This file is a UMD module so it works in every documented integration:
11
+ *
12
+ * - ESM: `import carve from 'carve-grammars/highlightjs/carve.js'` (resolved to
13
+ * the carve.mjs shim via the package `exports` map), then
14
+ * `hljs.registerLanguage('carve', carve)`.
15
+ * - Classic `<script src=".../highlightjs/carve.js">` after highlight.js: it
16
+ * self-registers against the global `hljs` (and exposes `globalThis.carveHljs`).
17
+ * - CommonJS contexts that load this file as CommonJS get the factory on
18
+ * `module.exports`.
19
+ *
20
+ * A top-level `export default` is intentionally NOT used: that would be a
21
+ * syntax error when the file is loaded as a classic browser script.
22
+ *
23
+ * @see https://github.com/markup-carve/carve for the Carve specification
24
+ */
25
+ (function (root, factory) {
26
+ var carve = factory();
27
+ if (typeof module === 'object' && module.exports) {
28
+ module.exports = carve;
29
+ }
30
+ if (root) {
31
+ // Exposed for the ESM shim (carve.mjs) and for classic <script> use.
32
+ root.carveHljs = carve;
33
+ if (root.hljs && typeof root.hljs.registerLanguage === 'function') {
34
+ root.hljs.registerLanguage('carve', carve);
35
+ }
36
+ }
37
+ }(typeof globalThis !== 'undefined' ? globalThis : this, function () {
38
+ 'use strict';
39
+ /**
40
+ * @param {object} [hljs] - the highlight.js instance (unused, kept for the
41
+ * standard language-definition signature).
42
+ * @returns {object} a highlight.js language definition.
43
+ */
44
+ return function carve(hljs) {
45
+ // Block attributes: {.class #id key=value} or boolean {reversed}
46
+ // Excludes special inline syntax like {= {+ {- {%
47
+ // The payload is STRICT (spec PART 9 S14): a class/id/key identifier may not
48
+ // start with a digit, so `{2=v}` stays literal text rather than scoping as
49
+ // an attribute block. An unquoted value may contain dots and colons.
50
+ const ATTR_ITEM = /(?:[.#][A-Za-z_][\w-]*|[A-Za-z_][\w:-]*(?:=(?:"(?:[^"\\\n]|\\.)*"|'(?:[^'\\\n]|\\.)*'|[^\s"'{}]+))?)/.source;
51
+ // Forced intraword family (PART 9 S22). Content may contain the delimiter
52
+ // (`{/a/b/}` is <em>a/b</em>), so the run ends at the closing `X}`. These
53
+ // must precede ATTRIBUTE, or `{_path_}` reads as a boolean attribute.
54
+ const FORCED_STRONG = { className: 'strong', begin: /\{\*(?=\S)/, end: /\*\}/, relevance: 5 };
55
+ const FORCED_EMPHASIS = { className: 'emphasis', begin: /\{\/(?=\S)/, end: /\/\}/, relevance: 5 };
56
+ const FORCED_UNDERLINE = { className: 'emphasis', begin: /\{_(?=\S)/, end: /_\}/, relevance: 5 };
57
+ const FORCED_STRIKE = { className: 'deletion', begin: /\{~(?=\S)(?!.*~>)/, end: /~\}/, relevance: 5 };
58
+
59
+ const ATTRIBUTE_EMPTY = {
60
+ className: 'attr',
61
+ // Valid only glued to a preceding `]` (`[x]{}`); a bare `{}` is literal.
62
+ begin: /(?<=\])\{\s*\}/,
63
+ relevance: 5,
64
+ };
65
+ const ATTRIBUTE = {
66
+ className: 'attr',
67
+ begin: new RegExp('\\{\\s*' + ATTR_ITEM + '(?:\\s+' + ATTR_ITEM + ')*\\s*\\}'),
68
+ relevance: 5,
69
+ };
70
+
71
+ // Headings: # to ######
72
+ const HEADING = {
73
+ className: 'section',
74
+ begin: /^#{1,6}\s/,
75
+ end: /$/,
76
+ relevance: 10,
77
+ };
78
+
79
+ // Emphasis (Carve): /text/ - the begin guard avoids URLs and paths
80
+ // (a/b, ://); the end is a closing slash not followed by word char/slash.
81
+ const EMPHASIS = {
82
+ className: 'emphasis',
83
+ begin: /(?<![\w:/])\/(?=\S)/,
84
+ end: /\/(?![\w/])/,
85
+ relevance: 0,
86
+ };
87
+
88
+ // Underline (Carve): _text_ - not in the middle of words
89
+ const UNDERLINE = {
90
+ className: 'emphasis',
91
+ begin: /(?<!\w)_(?!\s)/,
92
+ end: /_(?!\w)/,
93
+ relevance: 0,
94
+ };
95
+
96
+ // Strong: *text* - not in the middle of words, can contain emphasis.
97
+ // Excludes *[ which is abbreviation-definition syntax.
98
+ const STRONG = {
99
+ className: 'strong',
100
+ begin: /(?<!\w)\*(?![\s\[])/,
101
+ end: /\*(?!\w)/,
102
+ relevance: 0,
103
+ contains: [EMPHASIS, UNDERLINE],
104
+ };
105
+
106
+ // Highlight (Carve): =text= (single-char; intraword as {=text=})
107
+ const HIGHLIGHT = {
108
+ className: 'addition',
109
+ begin: /(?<![=\w])=(?=\S)/,
110
+ end: /=(?![=\w])/,
111
+ relevance: 3,
112
+ };
113
+
114
+ // Insert: {+text+}
115
+ const INSERT = {
116
+ className: 'addition',
117
+ begin: /\{\+/,
118
+ end: /\+\}/,
119
+ relevance: 5,
120
+ };
121
+
122
+ // Delete: {-text-}
123
+ const DELETE = {
124
+ className: 'deletion',
125
+ begin: /\{-/,
126
+ end: /-\}/,
127
+ relevance: 5,
128
+ };
129
+
130
+ // Strikethrough (Carve): ~text~ (Djot uses ~ for subscript instead)
131
+ const STRIKETHROUGH = {
132
+ className: 'deletion',
133
+ begin: /(?<!\w)~(?=\S)/,
134
+ end: /~(?!\w)/,
135
+ relevance: 2,
136
+ };
137
+
138
+ // Subscript (Carve): braced-only `{,text,}` - a bare `,` is literal text.
139
+ const SUBSCRIPT = {
140
+ className: 'built_in',
141
+ begin: /\{,(?=\S)/,
142
+ end: /,\}/,
143
+ relevance: 3,
144
+ };
145
+
146
+ // Superscript (Carve): braced-only `{^text^}` - a bare `^` is literal text.
147
+ const SUPERSCRIPT = {
148
+ className: 'built_in',
149
+ begin: /\{\^(?=\S)/,
150
+ end: /\^\}/,
151
+ relevance: 3,
152
+ };
153
+
154
+ // Math: $$`...`$$ (display) and $`...`$ (inline). Must precede the inline
155
+ // code modes - the leading $ keeps them from matching, but order is clearer.
156
+ const MATH_DISPLAY = {
157
+ className: 'string',
158
+ begin: /\$\$`+/,
159
+ end: /`+\$\$/,
160
+ relevance: 5,
161
+ };
162
+ const MATH_INLINE = {
163
+ className: 'string',
164
+ begin: /\$`+/,
165
+ end: /`+\$/,
166
+ relevance: 5,
167
+ };
168
+
169
+ // Inline code: `code` or ``code``. highlight.js has no begin->end
170
+ // backreference to match fence widths, so handle the two common widths
171
+ // explicitly - double backticks first, so an embedded single backtick
172
+ // (``a ` b``) does not close the span early.
173
+ const INLINE_CODE_DOUBLE = {
174
+ className: 'code',
175
+ begin: /``/,
176
+ end: /``/,
177
+ relevance: 0,
178
+ };
179
+ const INLINE_CODE_SINGLE = {
180
+ className: 'code',
181
+ begin: /`/,
182
+ end: /`/,
183
+ relevance: 0,
184
+ };
185
+
186
+ // Inline links: [text](url) with optional trailing attributes
187
+ const LINK = {
188
+ className: 'link',
189
+ begin: /\[[^\]]*\]\([^)]*\)(\{[^}]+\})?/,
190
+ relevance: 5,
191
+ };
192
+
193
+ // Autolinks: <https://...> or <mailto:...>
194
+ const AUTOLINK = {
195
+ className: 'link',
196
+ begin: /<(?:https?:\/\/|mailto:)[^>]+>/,
197
+ relevance: 5,
198
+ };
199
+
200
+ // Email autolinks: <user@example.com>
201
+ const EMAIL_AUTOLINK = {
202
+ className: 'link',
203
+ begin: /<[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}>/,
204
+ relevance: 5,
205
+ };
206
+
207
+ // Images: ![alt](url) with optional trailing attributes
208
+ const IMAGE = {
209
+ className: 'link',
210
+ begin: /!\[[^\]]*\]\([^)]*\)(\{[^}]+\})?/,
211
+ relevance: 5,
212
+ };
213
+
214
+ // Reference links: [text][ref] with optional trailing attributes
215
+ const REFERENCE_LINK = {
216
+ className: 'link',
217
+ begin: /\[[^\]]+\]\[[^\]]*\](\{[^}]+\})?/,
218
+ relevance: 5,
219
+ };
220
+
221
+ // Spans with attributes: [text]{.class} or [text]{#id}
222
+ const SPAN = {
223
+ className: 'string',
224
+ // Only the bracket run; the trailing `{...}` is left to ATTRIBUTE so it
225
+ // scopes as an attribute block rather than vanishing into the span.
226
+ begin: /\[[^\]]+\](?=\{)/,
227
+ relevance: 5,
228
+ };
229
+
230
+ // Reference definitions: [ref]: url
231
+ const REFERENCE_DEF = {
232
+ className: 'symbol',
233
+ begin: /^\[[^\]^\]]+\]:/,
234
+ end: /$/,
235
+ relevance: 10,
236
+ };
237
+
238
+ // Footnote references: [^note]
239
+ const FOOTNOTE_REF = {
240
+ className: 'symbol',
241
+ begin: /\[\^[^\]]+\]/,
242
+ relevance: 5,
243
+ };
244
+
245
+ // Citations (Tier-2 §22): [@key], [+@key], [@key, p.10], [@a; @b]
246
+ // A bracket whose content holds at least one `@key` with no trailing
247
+ // `(url)`, `[ref]`, or `{attrs}` suffix. The negative lookahead is handled
248
+ // by position in the contains array (SPAN and REFERENCE_LINK are checked
249
+ // first to claim those suffixed forms).
250
+ const CITATION = {
251
+ className: 'symbol',
252
+ begin: /\[\+?(?:[^\]@]*@[A-Za-z0-9_][A-Za-z0-9_.:#$%&+?<>~\/-]*[^\]]*)\](?!\(|\[|\{)/,
253
+ relevance: 8,
254
+ };
255
+
256
+ // Code callouts (Tier-2 §10): <n> markers trailing a code-fence line or
257
+ // leading a callout-list item.
258
+ const CODE_CALLOUT = {
259
+ className: 'symbol',
260
+ begin: /<\d+>/,
261
+ relevance: 5,
262
+ };
263
+
264
+ // Footnote definitions: [^note]: content
265
+ const FOOTNOTE_DEF = {
266
+ className: 'symbol',
267
+ begin: /^\[\^[^\]]+\]:/,
268
+ end: /$/,
269
+ relevance: 10,
270
+ };
271
+
272
+ // Abbreviation definitions: *[ABBR]: text
273
+ const ABBREVIATION_DEF = {
274
+ className: 'symbol',
275
+ begin: /^\*\[[^\]]+\]:/,
276
+ end: /$/,
277
+ relevance: 10,
278
+ };
279
+
280
+ // Blockquotes: > text
281
+ const BLOCKQUOTE = {
282
+ className: 'quote',
283
+ begin: /^>/,
284
+ end: /$/,
285
+ relevance: 0,
286
+ };
287
+
288
+ // Horizontal rules: --- or *** or ___
289
+ const HORIZONTAL_RULE = {
290
+ className: 'meta',
291
+ begin: /^(-{3,}|\*{3,}|_{3,})$/,
292
+ relevance: 10,
293
+ };
294
+
295
+ // Bullet list items: - or *
296
+ const LIST_BULLET = {
297
+ className: 'bullet',
298
+ // A marker line may carry several markers (`- - A`, corpus 103).
299
+ begin: /^[ \t]*(?:[-*][ \t]+)*[-*](?=\s)/,
300
+ relevance: 0,
301
+ };
302
+
303
+ // Numbered list items: decimal (1.), alpha (a. A.), roman (i. I.)
304
+ const LIST_NUMBER = {
305
+ className: 'bullet',
306
+ begin: /^[ \t]*(\d+[.)]|[a-zA-Z][.)]|[ivxlcdmIVXLCDM]+[.)])(?=\s)/,
307
+ relevance: 0,
308
+ };
309
+
310
+ // Task list items: - [ ] or - [x]
311
+ const TASK_LIST = {
312
+ className: 'bullet',
313
+ begin: /^[ \t]*[-*]\s\[[ xX_]\]/,
314
+ relevance: 5,
315
+ };
316
+
317
+ // Definition list terms: : term
318
+ const DEFINITION_TERM = {
319
+ className: 'title',
320
+ begin: /^: /,
321
+ end: /$/,
322
+ relevance: 5,
323
+ };
324
+
325
+ // Code fence opening: ``` or ~~~ with optional language
326
+ const CODE_FENCE_START = {
327
+ className: 'keyword',
328
+ begin: /^[`~]{3,}\s*[a-zA-Z]*$/,
329
+ relevance: 10,
330
+ };
331
+
332
+ // Code fence closing: ``` or ~~~
333
+ const CODE_FENCE_END = {
334
+ className: 'keyword',
335
+ begin: /^[`~]{3,}$/,
336
+ relevance: 10,
337
+ };
338
+
339
+ // Div block opening: ::: with optional type, "title", [label], or the
340
+ // | / \ layout tokens. Strict shapes only - unquoted or curly-quoted
341
+ // trailing text is a paragraph, not a fence, and must not highlight.
342
+ const DIV_BLOCK_START = {
343
+ className: 'keyword',
344
+ begin: /^:{3,}(?:[ \t]*(?:\||\\)|[ \t]*[a-zA-Z_][\w-]*(?:[ \t]+"[^"\n]*")?(?:[ \t]+\[[^\]\n]*\])?|[ \t]*\[[^\]\n]*\])?[ \t]*$/,
345
+ relevance: 10,
346
+ };
347
+
348
+ // Div block closing: :::
349
+ const DIV_BLOCK_END = {
350
+ className: 'keyword',
351
+ begin: /^:{3,}$/,
352
+ relevance: 10,
353
+ };
354
+
355
+ // Inline comments: {% comment %}
356
+ // Carve comments: `%%` to end of line, a `%%%` fenced block, and the
357
+ // CriticMarkup comment `{# ... #}`. (The previous rule here matched
358
+ // `{% ... %}`, which is Jinja/Liquid syntax and does not exist in Carve.)
359
+ const LINE_COMMENT = {
360
+ className: 'comment',
361
+ begin: /(?:^|(?<=\s))%%(?!%)/,
362
+ end: /$/,
363
+ relevance: 5,
364
+ };
365
+ const BLOCK_COMMENT = {
366
+ className: 'comment',
367
+ begin: /^%%%\s*$/,
368
+ end: /^%%%\s*$/,
369
+ relevance: 10,
370
+ };
371
+ const CRITIC_SUB = {
372
+ className: 'meta',
373
+ // The `~>` arrow is what distinguishes a substitution from a forced
374
+ // strikethrough (`{~gone~}`), so it is required here.
375
+ begin: /\{~(?=[^}\n]*~>)/,
376
+ end: /~\}/,
377
+ relevance: 10,
378
+ };
379
+ const CRITIC_COMMENT = {
380
+ className: 'comment',
381
+ // The closing `#}` is required, or this would swallow an attribute
382
+ // block whose id comes first (`{#id .class}`).
383
+ begin: /\{#(?=[^}\n]*#\})/,
384
+ end: /#\}/,
385
+ relevance: 5,
386
+ };
387
+
388
+ // Mentions and tags: @name / #name (a heading `#` is line-anchored and is
389
+ // matched earlier, so an inline `#tag` is unambiguous).
390
+ const MENTION = {
391
+ className: 'symbol',
392
+ begin: /(?<![\w@])@[A-Za-z0-9][\w-]*(?:\.[\w-]+)*/,
393
+ relevance: 5,
394
+ };
395
+ const TAG = {
396
+ className: 'symbol',
397
+ begin: /(?<![\w#])#[A-Za-z0-9][\w-]*(?:\.[\w-]+)*/,
398
+ relevance: 5,
399
+ };
400
+
401
+ // Table separator: |---|---|
402
+ const TABLE_SEPARATOR = {
403
+ className: 'meta',
404
+ begin: /^\|[-:| ]+\|$/,
405
+ relevance: 5,
406
+ };
407
+
408
+ // Line blocks: | text (for poetry) - must precede TABLE_ROW
409
+ const LINE_BLOCK = {
410
+ className: 'string',
411
+ begin: /^\| /,
412
+ end: /$/,
413
+ relevance: 3,
414
+ };
415
+
416
+ // Table rows: | cell | cell |
417
+ const TABLE_ROW = {
418
+ className: 'string',
419
+ begin: /^\|/,
420
+ end: /\|(\{[^}]*\})?$/,
421
+ relevance: 2,
422
+ };
423
+
424
+ // Captions: ^ caption text
425
+ const CAPTION = {
426
+ className: 'title',
427
+ begin: /^\^ /,
428
+ end: /$/,
429
+ relevance: 5,
430
+ };
431
+
432
+ // Raw format marker: {=html} or {=latex}
433
+ const RAW_FORMAT = {
434
+ className: 'meta',
435
+ begin: /\{=[a-zA-Z]+\}/,
436
+ relevance: 5,
437
+ };
438
+
439
+ // Escaped characters: \* \[ etc
440
+ const ESCAPE = {
441
+ className: 'symbol',
442
+ begin: /\\[!"#$%&'()*+,.\/:;<=>?@\[\\\]^_`{|}~-]/,
443
+ relevance: 0,
444
+ };
445
+
446
+ // Hard line break: \ at end of line
447
+ const HARD_BREAK = {
448
+ className: 'meta',
449
+ begin: /\\$/,
450
+ relevance: 2,
451
+ };
452
+
453
+ // Symbol shortcodes (e.g. emoji): :name: (parser shape - name starts
454
+ // alphanumeric, then word chars, `+` or `-`; no whitespace, so
455
+ // `a : b : c` stays text)
456
+ const SYMBOL = {
457
+ className: 'symbol',
458
+ begin: /(?<!\w):[A-Za-z0-9+-][\w+-]*:/,
459
+ relevance: 0,
460
+ };
461
+
462
+ return {
463
+ name: 'Carve',
464
+ aliases: ['carve'],
465
+ case_insensitive: false,
466
+ contains: [
467
+ // NOTE: front matter is intentionally NOT highlighted. It is valid
468
+ // only at the very top of the document, but highlight.js has no
469
+ // document-start anchor, so a `^---$` begin would also match a bare
470
+ // `---` horizontal rule mid-document and swallow everything up to
471
+ // the next `---`. The horizontal-rule rule below handles `---`
472
+ // lines instead. (Prism anchors front matter via `^` with no `m`
473
+ // flag; see prism/carve.js.)
474
+
475
+ // Block-level elements (order matters - more specific first)
476
+ HEADING,
477
+ CODE_FENCE_START,
478
+ CODE_FENCE_END,
479
+ DIV_BLOCK_START,
480
+ DIV_BLOCK_END,
481
+ HORIZONTAL_RULE,
482
+ TABLE_SEPARATOR,
483
+ LINE_BLOCK, // Must be before TABLE_ROW (both start with |)
484
+ TABLE_ROW,
485
+ BLOCKQUOTE,
486
+ CAPTION,
487
+ TASK_LIST, // Must be before LIST_BULLET
488
+ LIST_BULLET,
489
+ LIST_NUMBER,
490
+ DEFINITION_TERM,
491
+ FOOTNOTE_DEF, // Must be before REFERENCE_DEF
492
+ ABBREVIATION_DEF, // Must be before REFERENCE_DEF (*[ABBR]: vs [ref]:)
493
+ REFERENCE_DEF,
494
+
495
+ // Inline elements (order matters - more specific first)
496
+ FOOTNOTE_REF,
497
+ IMAGE, // Must be before LINK (starts with !)
498
+ SPAN, // Must be before LINK ([text]{attr} vs [text](url))
499
+ REFERENCE_LINK, // Must be before LINK ([text][ref] vs [text](url))
500
+ CITATION, // Must be after SPAN/REF_LINK (no (url)/[ref]/{attr} tail)
501
+ CODE_CALLOUT, // <n> callout markers
502
+ SYMBOL, // :name: shortcodes
503
+ LINK,
504
+ AUTOLINK,
505
+ EMAIL_AUTOLINK,
506
+ RAW_FORMAT, // {=html} - must be before INSERT/DELETE braces
507
+ INSERT, // {+text+}
508
+ DELETE, // {-text-}
509
+ BLOCK_COMMENT, // %%% fence - before LINE_COMMENT
510
+ LINE_COMMENT, // %% to end of line
511
+ CRITIC_SUB, // {~old~>new~} - before FORCED_STRIKE
512
+ CRITIC_COMMENT, // {# ... #} - must be before ATTRIBUTE
513
+ MENTION,
514
+ TAG,
515
+ HIGHLIGHT, // =text=
516
+ SUBSCRIPT, // ,text,
517
+ SUPERSCRIPT, // ^text^
518
+ STRONG,
519
+ EMPHASIS, // /text/
520
+ UNDERLINE, // _text_
521
+ STRIKETHROUGH, // ~text~
522
+ MATH_DISPLAY, // $$`...`$$ - before inline code (leading $)
523
+ MATH_INLINE, // $`...`$
524
+ INLINE_CODE_DOUBLE, // ``code`` - before single
525
+ INLINE_CODE_SINGLE, // `code`
526
+ FORCED_STRONG,
527
+ FORCED_EMPHASIS,
528
+ FORCED_UNDERLINE,
529
+ FORCED_STRIKE,
530
+ ATTRIBUTE_EMPTY,
531
+ ATTRIBUTE,
532
+ ESCAPE,
533
+ HARD_BREAK,
534
+ ],
535
+ };
536
+ };
537
+ }));
@@ -0,0 +1,25 @@
1
+ /**
2
+ * ESM entry for the Carve highlight.js grammar.
3
+ *
4
+ * The grammar itself lives in the UMD file `carve.js` (so it can also load as a
5
+ * classic `<script>` or via CommonJS). This shim runs that module for its side
6
+ * effect - which assigns `globalThis.carveHljs` - and re-exports the language
7
+ * factory as the default export, so ESM consumers get the documented:
8
+ *
9
+ * ```js
10
+ * import hljs from 'highlight.js';
11
+ * import carve from 'carve-grammars/highlightjs/carve.js';
12
+ * hljs.registerLanguage('carve', carve);
13
+ * ```
14
+ *
15
+ * (The package `exports` map routes the ESM `import` of `./highlightjs/carve.js`
16
+ * to this file.)
17
+ *
18
+ * @module carve-grammars/highlightjs/carve
19
+ */
20
+ import './carve.js';
21
+
22
+ /** @type {(hljs?: object) => object} */
23
+ const carve = globalThis.carveHljs;
24
+
25
+ export default carve;
package/package.json ADDED
@@ -0,0 +1,119 @@
1
+ {
2
+ "name": "@markup-carve/carve-grammars",
3
+ "version": "0.1.2",
4
+ "description": "Grammars for the Carve markup language: Tiptap editor kit + serializer, plus Prism, highlight.js and TextMate syntax-highlighting grammars",
5
+ "type": "module",
6
+ "main": "tiptap/index.js",
7
+ "scripts": {
8
+ "test": "node tests/coverage-test.js && node tests/snapshot-test.js && node tests/roundtrip-test.js && node tests/serializer-test.js && node tests/tabs-roundtrip-test.js && node tests/parse-test.js && node tests/grammar-test.js && node tests/shiki-test.js && node tests/engine-sweep-test.js && node tests/textmate-sweep-test.js",
9
+ "test:coverage": "node tests/coverage-test.js",
10
+ "test:snapshot": "node tests/snapshot-test.js",
11
+ "test:roundtrip": "node tests/roundtrip-test.js",
12
+ "snapshots:update": "UPDATE_SNAPSHOTS=1 node tests/snapshot-test.js"
13
+ },
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/markup-carve/carve-grammars.git"
17
+ },
18
+ "keywords": [
19
+ "carve",
20
+ "tiptap",
21
+ "prosemirror",
22
+ "wysiwyg",
23
+ "serializer",
24
+ "markup",
25
+ "syntax-highlighting",
26
+ "prism",
27
+ "prismjs",
28
+ "highlight.js",
29
+ "hljs"
30
+ ],
31
+ "author": "markup-carve",
32
+ "license": "MIT",
33
+ "bugs": {
34
+ "url": "https://github.com/markup-carve/carve-grammars/issues"
35
+ },
36
+ "homepage": "https://github.com/markup-carve/carve-grammars#readme",
37
+ "files": [
38
+ "tiptap/",
39
+ "prism/",
40
+ "highlightjs/",
41
+ "shiki/",
42
+ "textmate/",
43
+ "README.md",
44
+ "LICENSE"
45
+ ],
46
+ "exports": {
47
+ ".": "./tiptap/index.js",
48
+ "./tiptap": "./tiptap/index.js",
49
+ "./tiptap/*": "./tiptap/*",
50
+ "./prism/carve.js": "./prism/carve.js",
51
+ "./prism/*": "./prism/*",
52
+ "./highlightjs/carve.js": {
53
+ "import": "./highlightjs/carve.mjs",
54
+ "default": "./highlightjs/carve.js"
55
+ },
56
+ "./highlightjs/*": "./highlightjs/*",
57
+ "./shiki": "./shiki/index.js",
58
+ "./shiki/carve.css": "./shiki/carve.css",
59
+ "./textmate/carve.tmLanguage.json": "./textmate/carve.tmLanguage.json"
60
+ },
61
+ "peerDependencies": {
62
+ "@shikijs/themes": "^2 || ^3",
63
+ "@tiptap/core": "^2",
64
+ "@tiptap/extension-underline": "^2",
65
+ "@tiptap/starter-kit": "^2",
66
+ "highlight.js": "^11",
67
+ "prismjs": "^1"
68
+ },
69
+ "peerDependenciesMeta": {
70
+ "@tiptap/core": {
71
+ "optional": true
72
+ },
73
+ "@tiptap/starter-kit": {
74
+ "optional": true
75
+ },
76
+ "@tiptap/extension-underline": {
77
+ "optional": true
78
+ },
79
+ "prismjs": {
80
+ "optional": true
81
+ },
82
+ "highlight.js": {
83
+ "optional": true
84
+ },
85
+ "@shikijs/themes": {
86
+ "optional": true
87
+ }
88
+ },
89
+ "devDependencies": {
90
+ "@markup-carve/carve": "github:markup-carve/carve-js",
91
+ "@shikijs/themes": "^3.13.0",
92
+ "@tiptap/core": "^2.27.2",
93
+ "@tiptap/extension-bullet-list": "^2.27.2",
94
+ "@tiptap/extension-code-block": "^2.27.2",
95
+ "@tiptap/extension-hard-break": "^2.27.2",
96
+ "@tiptap/extension-highlight": "^2.27.2",
97
+ "@tiptap/extension-image": "^2.27.2",
98
+ "@tiptap/extension-link": "^2.27.2",
99
+ "@tiptap/extension-list-item": "^2.27.2",
100
+ "@tiptap/extension-subscript": "^2.27.2",
101
+ "@tiptap/extension-superscript": "^2.27.2",
102
+ "@tiptap/extension-table": "^2.27.2",
103
+ "@tiptap/extension-table-cell": "^2.27.2",
104
+ "@tiptap/extension-table-header": "^2.27.2",
105
+ "@tiptap/extension-table-row": "^2.27.2",
106
+ "@tiptap/extension-task-item": "^2.27.2",
107
+ "@tiptap/extension-task-list": "^2.27.2",
108
+ "@tiptap/extension-underline": "^2.27.2",
109
+ "@tiptap/pm": "^2.27.2",
110
+ "@tiptap/starter-kit": "^2.27.2",
111
+ "happy-dom": "^20.10.6",
112
+ "highlight.js": "^11.11.1",
113
+ "prismjs": "^1.30.0",
114
+ "shiki": "^4.3.1"
115
+ },
116
+ "publishConfig": {
117
+ "access": "public"
118
+ }
119
+ }