@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.
- package/LICENSE +21 -0
- package/README.md +240 -0
- package/highlightjs/carve.js +537 -0
- package/highlightjs/carve.mjs +25 -0
- package/package.json +119 -0
- package/prism/carve.js +471 -0
- package/shiki/carve.css +46 -0
- package/shiki/index.js +188 -0
- package/textmate/carve.tmLanguage.json +1023 -0
- package/tiptap/carve-kit.js +507 -0
- package/tiptap/extensions/carve-abbreviation.js +79 -0
- package/tiptap/extensions/carve-definition-list.js +270 -0
- package/tiptap/extensions/carve-delete.js +54 -0
- package/tiptap/extensions/carve-div.js +188 -0
- package/tiptap/extensions/carve-embed.js +248 -0
- package/tiptap/extensions/carve-footnote-definition.js +81 -0
- package/tiptap/extensions/carve-footnote.js +76 -0
- package/tiptap/extensions/carve-insert.js +54 -0
- package/tiptap/extensions/carve-keymap.js +71 -0
- package/tiptap/extensions/carve-math.js +82 -0
- package/tiptap/extensions/carve-mention.js +44 -0
- package/tiptap/extensions/carve-span.js +101 -0
- package/tiptap/extensions/carve-tabs.js +158 -0
- package/tiptap/extensions/index.js +14 -0
- package/tiptap/index.js +53 -0
- package/tiptap/serializer.js +686 -0
package/prism/carve.js
ADDED
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prism.js grammar for the Carve markup language.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the canonical token set in markup-carve/carve
|
|
5
|
+
* (`resources/grammar.ebnf`) and the TextMate grammar in vscode-carve
|
|
6
|
+
* (`syntaxes/carve.tmLanguage.json`). Carve's inline delimiters differ from
|
|
7
|
+
* Markdown/Djot: emphasis is `/italic/`, `*bold*`, `_underline_`,
|
|
8
|
+
* `~strike~`, `=highlight=`, `^sup^`, `,sub,` (the doubled forms `==x==` /
|
|
9
|
+
* `,,x,,` are literal in Carve; the forced brace forms `{=x=}` / `{,x,}` /
|
|
10
|
+
* `{^x^}` render intraword).
|
|
11
|
+
*
|
|
12
|
+
* Usage (ESM):
|
|
13
|
+
*
|
|
14
|
+
* ```js
|
|
15
|
+
* import Prism from 'prismjs';
|
|
16
|
+
* import 'carve-grammars/prism/carve.js'; // registers Prism.languages.carve
|
|
17
|
+
*
|
|
18
|
+
* const html = Prism.highlight(src, Prism.languages.carve, 'carve');
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* Usage (browser / bundler): load `prismjs` first (which sets the global
|
|
22
|
+
* `Prism`), then import this file for its side effect - it reads the global
|
|
23
|
+
* `Prism` (`globalThis` / `window` / `global`) and registers the grammar.
|
|
24
|
+
*
|
|
25
|
+
* @module carve-grammars/prism/carve
|
|
26
|
+
*/
|
|
27
|
+
(function (Prism) {
|
|
28
|
+
if (!Prism) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Inline attribute block: {#id .class key="val"} - reused by spans, divs,
|
|
33
|
+
// headings and extension calls.
|
|
34
|
+
// The payload is STRICT (spec PART 9 S14): a class/id/key identifier may not
|
|
35
|
+
// start with a digit, so `{2=v}` stays literal text rather than scoping as
|
|
36
|
+
// an attribute block. An unquoted value may contain dots and colons.
|
|
37
|
+
var attrItem = /(?:[.#][A-Za-z_][\w-]*|[A-Za-z_][\w:-]*(?:=(?:"(?:[^"\\\n]|\\.)*"|'(?:[^'\\\n]|\\.)*'|[^\s"'{}]+))?)/.source;
|
|
38
|
+
// An EMPTY block is valid only glued to a preceding `]` (`[x]{}` ->
|
|
39
|
+
// <span>x</span>); a bare `{}` in prose is literal text (corpus 123).
|
|
40
|
+
// An EMPTY attribute block is valid only where it is glued to a preceding
|
|
41
|
+
// `]` (`[x]{}` -> <span>x</span>); a bare `{}` in prose is literal text
|
|
42
|
+
// (corpus 123). Prism tokenizes left to right, so the span and its empty
|
|
43
|
+
// block have to be ONE rule -- a lookbehind would lose its `]` to the span.
|
|
44
|
+
var spanEmptyAttrs = {
|
|
45
|
+
pattern: /\[[^\^\]][^\]]*\]\{\s*\}/,
|
|
46
|
+
inside: {
|
|
47
|
+
'attr-value': { pattern: /\{\s*\}/, inside: { 'punctuation': /[{}]/ } },
|
|
48
|
+
'string': /\[[^\]]*\]/,
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
var attributes = {
|
|
52
|
+
pattern: RegExp('\\{\\s*' + attrItem + '(?:\\s+' + attrItem + ')*\\s*\\}'),
|
|
53
|
+
alias: 'attr-value',
|
|
54
|
+
inside: {
|
|
55
|
+
'id': /#[A-Za-z_][\w-]*/,
|
|
56
|
+
'class-name': /\.[A-Za-z_][\w-]*/,
|
|
57
|
+
'attr-name': /[A-Za-z_:][\w:-]*(?==)/,
|
|
58
|
+
'string': /"[^"]*"|'[^']*'/,
|
|
59
|
+
'punctuation': /[{}=]/,
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
// Shared inline emphasis/markup, referenced from block tokens that contain
|
|
64
|
+
// running text (headings, list items, table cells, quotes).
|
|
65
|
+
var inline = {
|
|
66
|
+
'bold-italic': {
|
|
67
|
+
pattern: /\/\*(?=\S)[^*]+\*\//,
|
|
68
|
+
alias: 'important',
|
|
69
|
+
},
|
|
70
|
+
// The "no leading/trailing space" rule is expressed without JS
|
|
71
|
+
// lookbehind (unsupported on Safari < 16.4 and some engines): the first
|
|
72
|
+
// and last content chars are required to be non-space directly.
|
|
73
|
+
// Forced intraword family (PART 9 S22): `{*x*}` `{/x/}` `{_x_}` `{~x~}`.
|
|
74
|
+
// Content may contain the delimiter -- `{/a/b/}` is <em>a/b</em> -- so the
|
|
75
|
+
// run ends at the closing `X}`. These MUST precede 'attributes', or
|
|
76
|
+
// `{_path_}` reads as a boolean attribute instead of <u>path</u>.
|
|
77
|
+
'forced-bold': {
|
|
78
|
+
pattern: /\{\*(?=\S)[^\n]*?\*\}/,
|
|
79
|
+
alias: 'bold',
|
|
80
|
+
},
|
|
81
|
+
'forced-italic': {
|
|
82
|
+
pattern: /\{\/(?=\S)[^\n]*?\/\}/,
|
|
83
|
+
alias: 'italic',
|
|
84
|
+
},
|
|
85
|
+
'forced-underline': {
|
|
86
|
+
pattern: /\{_(?=\S)[^\n]*?_\}/,
|
|
87
|
+
alias: 'underline',
|
|
88
|
+
},
|
|
89
|
+
'forced-strike': {
|
|
90
|
+
pattern: /\{~(?=\S)(?:(?!~>)[^\n])*?~\}/,
|
|
91
|
+
alias: 'deleted',
|
|
92
|
+
},
|
|
93
|
+
'bold': {
|
|
94
|
+
pattern: /\*[^*\s\n](?:[^*\n]*?[^*\s\n])?\*/,
|
|
95
|
+
alias: 'bold',
|
|
96
|
+
},
|
|
97
|
+
'italic': {
|
|
98
|
+
// leading guard via Prism lookbehind (avoids URLs, paths); the
|
|
99
|
+
// trailing `(?![\w/])` lookahead is fine (lookahead is universal).
|
|
100
|
+
pattern: /(^|[^\w/])\/[^/\s\n](?:[^/\n]*?[^/\s\n])?\/(?![\w/])/,
|
|
101
|
+
lookbehind: true,
|
|
102
|
+
alias: 'italic',
|
|
103
|
+
},
|
|
104
|
+
'underline': {
|
|
105
|
+
pattern: /(^|[^\w_])_[^_\s\n](?:[^_\n]*?[^_\s\n])?_(?![\w_])/,
|
|
106
|
+
lookbehind: true,
|
|
107
|
+
alias: 'underline',
|
|
108
|
+
},
|
|
109
|
+
'strike': {
|
|
110
|
+
pattern: /~[^~\s\n](?:[^~\n]*?[^~\s\n])?~/,
|
|
111
|
+
alias: 'deleted',
|
|
112
|
+
},
|
|
113
|
+
'highlight': {
|
|
114
|
+
pattern: /\{=(?=\S)[^\n]*?=\}|(?<![\w=])=(?=\S)[^=\n]+?(?<=\S)=(?![\w=])/,
|
|
115
|
+
alias: 'important',
|
|
116
|
+
},
|
|
117
|
+
// Braced-only: a bare `^` / `,` is literal text (no bare sup/sub).
|
|
118
|
+
'superscript': {
|
|
119
|
+
pattern: /\{\^(?=\S)[^\n]*?\^\}/,
|
|
120
|
+
alias: 'important',
|
|
121
|
+
},
|
|
122
|
+
'subscript': {
|
|
123
|
+
pattern: /\{,(?=\S)[^\n]*?,\}/,
|
|
124
|
+
alias: 'important',
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
Prism.languages.carve = {
|
|
129
|
+
// Block comments %%% ... %%% and line comments %% ...
|
|
130
|
+
// The comment fence is a *bare* %%% line; a `%%% format` opener is a
|
|
131
|
+
// raw passthrough block instead (handled by #raw-block below).
|
|
132
|
+
'comment': [
|
|
133
|
+
{
|
|
134
|
+
pattern: /^[ \t]*%%%[ \t]*\n[\s\S]*?^[ \t]*%%%[ \t]*$/m,
|
|
135
|
+
greedy: true,
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
pattern: /^[ \t]*%%(?!%).*$/m,
|
|
139
|
+
greedy: true,
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
// trailing comment after whitespace (Prism lookbehind, no JS
|
|
143
|
+
// lookbehind: the leading space is captured and excluded).
|
|
144
|
+
pattern: /([ \t])%%.*$/m,
|
|
145
|
+
lookbehind: true,
|
|
146
|
+
greedy: true,
|
|
147
|
+
},
|
|
148
|
+
],
|
|
149
|
+
|
|
150
|
+
// YAML/typed front matter delimited by --- at the very top of the file.
|
|
151
|
+
// `^` (no `m` flag) anchors to the start of the document; the close is
|
|
152
|
+
// matched at end-of-line so a document body may follow.
|
|
153
|
+
'front-matter': {
|
|
154
|
+
pattern: /^---[ \t]*[A-Za-z0-9_-]*[ \t]*\n[\s\S]*?\n---[ \t]*(?:\n|$)/,
|
|
155
|
+
alias: 'comment',
|
|
156
|
+
greedy: true,
|
|
157
|
+
inside: {
|
|
158
|
+
'punctuation': /---/,
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
|
|
162
|
+
// Fenced code blocks: ``` lang ... ``` or ~~~ lang ... ~~~
|
|
163
|
+
'code-block': {
|
|
164
|
+
pattern: /^(`{3,}|~{3,})[ \t]*[^\n]*\n[\s\S]*?^\1[ \t]*$/m,
|
|
165
|
+
greedy: true,
|
|
166
|
+
inside: {
|
|
167
|
+
'punctuation': /^(?:`{3,}|~{3,})|(?:`{3,}|~{3,})$/,
|
|
168
|
+
'language': {
|
|
169
|
+
pattern: /(^(?:`{3,}|~{3,})[ \t]*)[^\s`~]+/,
|
|
170
|
+
lookbehind: true,
|
|
171
|
+
alias: 'class-name',
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
|
|
176
|
+
// Raw passthrough blocks: %%% format ... %%% (rendered verbatim)
|
|
177
|
+
'raw-block': {
|
|
178
|
+
pattern: /^%{3,}[ \t]*\S*[ \t]*\n[\s\S]*?^%{3,}[ \t]*$/m,
|
|
179
|
+
greedy: true,
|
|
180
|
+
alias: 'string',
|
|
181
|
+
inside: {
|
|
182
|
+
'punctuation': /^%{3,}|%{3,}$/,
|
|
183
|
+
'language': {
|
|
184
|
+
pattern: /(^%{3,}[ \t]*)\S+/,
|
|
185
|
+
lookbehind: true,
|
|
186
|
+
alias: 'class-name',
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
|
|
191
|
+
// ATX headings # .. ######
|
|
192
|
+
'title': {
|
|
193
|
+
pattern: /^#{1,6}[ \t]+.+$/m,
|
|
194
|
+
alias: 'important',
|
|
195
|
+
inside: Object.assign({
|
|
196
|
+
'punctuation': /^#{1,6}/,
|
|
197
|
+
}, inline),
|
|
198
|
+
},
|
|
199
|
+
|
|
200
|
+
// Container divs ::: class / :::
|
|
201
|
+
// Strict opener shapes only: type word, optional "title" (straight
|
|
202
|
+
// quotes), optional [label], the | / \ layout tokens, or a typeless
|
|
203
|
+
// [label]. Trailing junk makes the line a paragraph, so it must not
|
|
204
|
+
// highlight as a fence.
|
|
205
|
+
'div': {
|
|
206
|
+
pattern: /^[ \t]*:{3,}(?:[ \t]*(?:\||\\)|[ \t]*[a-zA-Z_][\w-]*(?:[ \t]+"[^"\n]*")?(?:[ \t]+\[[^\]\n]*\])?|[ \t]*\[[^\]\n]*\])?[ \t]*$/m,
|
|
207
|
+
alias: 'tag',
|
|
208
|
+
inside: {
|
|
209
|
+
'punctuation': /:{3,}/,
|
|
210
|
+
'string': /"[^"\n]*"/,
|
|
211
|
+
'symbol': /\[[^\]\n]*\]/,
|
|
212
|
+
'class-name': {
|
|
213
|
+
pattern: /(^[ \t]*:{3,}[ \t]*)(?:[a-zA-Z_][\w-]*|\||\\)/,
|
|
214
|
+
lookbehind: true,
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
|
|
219
|
+
// Table rows: | a | b | (plus header `|=`, caption `^`, span markers)
|
|
220
|
+
'table': {
|
|
221
|
+
pattern: /^[ \t]*\|.*$/m,
|
|
222
|
+
inside: Object.assign({
|
|
223
|
+
// rowspan `^` / colspan `<` markers - must precede `punctuation`
|
|
224
|
+
// so the surrounding `|` is not consumed first.
|
|
225
|
+
'operator': {
|
|
226
|
+
pattern: /(\|)[ \t]*[\^<](?=[ \t]*\|)/,
|
|
227
|
+
lookbehind: true,
|
|
228
|
+
},
|
|
229
|
+
'punctuation': /\|=|\|/,
|
|
230
|
+
'attributes': attributes,
|
|
231
|
+
'url': /\[[^\]]+\]\([^\s)]+\)/,
|
|
232
|
+
}, inline),
|
|
233
|
+
},
|
|
234
|
+
|
|
235
|
+
// Table continuation / list continuation: a lone `+`
|
|
236
|
+
'table-continuation': {
|
|
237
|
+
pattern: /^[ \t]*\+[ \t]*$/m,
|
|
238
|
+
alias: 'punctuation',
|
|
239
|
+
},
|
|
240
|
+
|
|
241
|
+
// Blockquotes: leading > (possibly nested >>)
|
|
242
|
+
'blockquote': {
|
|
243
|
+
pattern: /^[ \t]*>+[ \t]?.*$/m,
|
|
244
|
+
inside: Object.assign({
|
|
245
|
+
'punctuation': /^[ \t]*>+/,
|
|
246
|
+
}, inline),
|
|
247
|
+
},
|
|
248
|
+
|
|
249
|
+
// List markers: -, *, ordered (1. a) i.), task [ ]/[x], definition `: `
|
|
250
|
+
'list': {
|
|
251
|
+
pattern: /^[ \t]*(?:(?:[-*][ \t]+)*[-*][ \t]+(?:\[[ xX]\][ \t]+)?|(?:[0-9]+|[A-Za-z]|[ivxlcdmIVXLCDM]+)[.)][ \t]+|:[ \t]+)/m,
|
|
252
|
+
alias: 'punctuation',
|
|
253
|
+
inside: {
|
|
254
|
+
'constant': /\[[ xX]\]/,
|
|
255
|
+
},
|
|
256
|
+
},
|
|
257
|
+
|
|
258
|
+
// Reference link / abbreviation definitions
|
|
259
|
+
'reference-definition': {
|
|
260
|
+
pattern: /^[ \t]*\[[^\]]+\]:[ \t]+\S+.*$/m,
|
|
261
|
+
alias: 'url',
|
|
262
|
+
inside: {
|
|
263
|
+
'constant': /^[ \t]*\[[^\]]+\]:/,
|
|
264
|
+
},
|
|
265
|
+
},
|
|
266
|
+
'abbreviation-definition': {
|
|
267
|
+
pattern: /^[ \t]*\*\[[A-Z][A-Z0-9]*\]:[ \t]+.*$/m,
|
|
268
|
+
inside: {
|
|
269
|
+
'punctuation': /^[ \t]*\*|\[|\]|:/,
|
|
270
|
+
'symbol': /[A-Z][A-Z0-9]*/,
|
|
271
|
+
},
|
|
272
|
+
},
|
|
273
|
+
|
|
274
|
+
// Display + inline math: $$`...`$$ and $`...`$
|
|
275
|
+
'math': [
|
|
276
|
+
{
|
|
277
|
+
pattern: /\$\$(`+)[\s\S]*?\1\$\$/,
|
|
278
|
+
greedy: true,
|
|
279
|
+
alias: 'string',
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
pattern: /\$(`+)[\s\S]*?\1\$/,
|
|
283
|
+
greedy: true,
|
|
284
|
+
alias: 'string',
|
|
285
|
+
},
|
|
286
|
+
],
|
|
287
|
+
|
|
288
|
+
// Raw inline passthrough: `code`{=format}
|
|
289
|
+
'raw-inline': {
|
|
290
|
+
pattern: /(`+)(?:[^`]|[^`][\s\S]*?[^`])\1\{=[A-Za-z_][\w-]*\}/,
|
|
291
|
+
greedy: true,
|
|
292
|
+
alias: 'string',
|
|
293
|
+
},
|
|
294
|
+
|
|
295
|
+
// Inline code spans
|
|
296
|
+
'code': {
|
|
297
|
+
pattern: /(`+)(?:[^`]|[^`][\s\S]*?[^`])\1/,
|
|
298
|
+
greedy: true,
|
|
299
|
+
},
|
|
300
|
+
|
|
301
|
+
// Images: ; the title may contain
|
|
302
|
+
// backslash-escaped quotes like the link title.
|
|
303
|
+
'image': {
|
|
304
|
+
pattern: /!\[[^\]]*\]\([^\s)]+(?:[ \t]+"(?:[^"\\]|\\[\s\S])*")?\)/,
|
|
305
|
+
greedy: true,
|
|
306
|
+
alias: 'url',
|
|
307
|
+
inside: {
|
|
308
|
+
'string': /"(?:[^"\\]|\\[\s\S])*"/,
|
|
309
|
+
'punctuation': /!\[|\]\(|\)/,
|
|
310
|
+
},
|
|
311
|
+
},
|
|
312
|
+
|
|
313
|
+
// Footnote references: [^label]
|
|
314
|
+
'footnote': {
|
|
315
|
+
pattern: /\[\^[^\]]+\]/,
|
|
316
|
+
alias: 'symbol',
|
|
317
|
+
},
|
|
318
|
+
|
|
319
|
+
// Citations (Tier-2 §22): [@key], [+@key], [@key, p.10], [@a; @b; @c]
|
|
320
|
+
// Distinguished from links/spans/refs by the absence of a trailing
|
|
321
|
+
// `(url)`, `[ref]`, or `{attrs}` suffix. The bracket MUST contain at
|
|
322
|
+
// least one `@key` item.
|
|
323
|
+
'citation': {
|
|
324
|
+
pattern: /\[\+?(?:[^\]@]*@[A-Za-z0-9_][A-Za-z0-9_.:#$%&+?<>~\/-]*(?:[^\]]*)?)\](?!\(|\[|\{)/,
|
|
325
|
+
greedy: true,
|
|
326
|
+
alias: 'string',
|
|
327
|
+
inside: {
|
|
328
|
+
// Integral marker `+` and suppress-author `-`
|
|
329
|
+
'operator': /(?<=^\[)\+|(?<=[@;]\s*)-(?=@)/,
|
|
330
|
+
// The `@key` itself
|
|
331
|
+
'function': /@[A-Za-z0-9_][A-Za-z0-9_.:#$%&+?<>~\/-]*/,
|
|
332
|
+
// Separators and locator punctuation
|
|
333
|
+
'punctuation': /\[|\]|;|,/,
|
|
334
|
+
},
|
|
335
|
+
},
|
|
336
|
+
|
|
337
|
+
// Code callouts (Tier-2 §10): <n> markers trailing a code-fence line
|
|
338
|
+
// or leading a callout-list item. Only pure-digit content.
|
|
339
|
+
'code-callout': {
|
|
340
|
+
pattern: /<\d+>/,
|
|
341
|
+
alias: 'symbol',
|
|
342
|
+
},
|
|
343
|
+
|
|
344
|
+
// Inline links: [text](url "title") and reference [text][id]
|
|
345
|
+
'url': [
|
|
346
|
+
{
|
|
347
|
+
// The link text may be empty ([](url), spec corpus 03-links-8)
|
|
348
|
+
// and the title may contain backslash-escaped quotes:
|
|
349
|
+
// [t](/url "ti\"tle") (spec corpus 03-links-4).
|
|
350
|
+
pattern: /\[[^\]]*\]\([^\s)]+(?:[ \t]+"(?:[^"\\]|\\[\s\S])*")?\)/,
|
|
351
|
+
greedy: true,
|
|
352
|
+
inside: {
|
|
353
|
+
'string': /"(?:[^"\\]|\\[\s\S])*"/,
|
|
354
|
+
'punctuation': /\[|\]\(|\)/,
|
|
355
|
+
},
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
pattern: /\[[^\]]+\]\[[^\]]*\]/,
|
|
359
|
+
greedy: true,
|
|
360
|
+
inside: {
|
|
361
|
+
'punctuation': /\[|\]\[|\]/,
|
|
362
|
+
},
|
|
363
|
+
},
|
|
364
|
+
{
|
|
365
|
+
// autolink <https://...> and <mailto-ish>
|
|
366
|
+
pattern: /<[a-zA-Z][a-zA-Z0-9+.-]*:[^>\s]+>|<[^>\s@]+@[^>\s]+>/,
|
|
367
|
+
greedy: true,
|
|
368
|
+
},
|
|
369
|
+
],
|
|
370
|
+
|
|
371
|
+
// An EMPTY attribute block, only where it is glued to a preceding `]`
|
|
372
|
+
// (`[x]{}` -> <span>x</span>). A bare `{}` in prose is literal text
|
|
373
|
+
// (corpus 123). Must precede 'span', which would otherwise consume the
|
|
374
|
+
// `]` this rule anchors on.
|
|
375
|
+
'span-empty-attrs': spanEmptyAttrs,
|
|
376
|
+
|
|
377
|
+
// Bracketed span with attributes: [text]{.class}
|
|
378
|
+
'span': {
|
|
379
|
+
pattern: /\[[^\^\]][^\]]*\](?=\{)/,
|
|
380
|
+
alias: 'string',
|
|
381
|
+
},
|
|
382
|
+
|
|
383
|
+
// Extension inline call: :name[content]{attrs}
|
|
384
|
+
'extension': {
|
|
385
|
+
pattern: /:[a-zA-Z][\w-]*\[[^\]]*\](?:\{[^}]*\})?/,
|
|
386
|
+
alias: 'function',
|
|
387
|
+
inside: {
|
|
388
|
+
'function': /:[a-zA-Z][\w-]*/,
|
|
389
|
+
'attributes': attributes,
|
|
390
|
+
'punctuation': /\[|\]/,
|
|
391
|
+
},
|
|
392
|
+
},
|
|
393
|
+
|
|
394
|
+
// CriticMarkup: {+ins+} {-del-} {~old~>new~} {#comment#}
|
|
395
|
+
'inserted': {
|
|
396
|
+
pattern: /\{\+[^}]*\+\}/,
|
|
397
|
+
alias: 'inserted',
|
|
398
|
+
},
|
|
399
|
+
'deleted': {
|
|
400
|
+
pattern: /\{-[^}]*-\}/,
|
|
401
|
+
alias: 'deleted',
|
|
402
|
+
},
|
|
403
|
+
'changed': {
|
|
404
|
+
pattern: /\{~[^~]*~>[^~]*~\}/,
|
|
405
|
+
alias: 'important',
|
|
406
|
+
},
|
|
407
|
+
'critic-comment': {
|
|
408
|
+
pattern: /\{#[^}]*#\}/,
|
|
409
|
+
alias: 'comment',
|
|
410
|
+
},
|
|
411
|
+
|
|
412
|
+
// Forced brace emphasis must beat the attribute rule (`{_path_}`).
|
|
413
|
+
'forced-bold': inline['forced-bold'],
|
|
414
|
+
'forced-italic': inline['forced-italic'],
|
|
415
|
+
'forced-underline': inline['forced-underline'],
|
|
416
|
+
'forced-strike': inline['forced-strike'],
|
|
417
|
+
|
|
418
|
+
// Attribute blocks attached to the preceding element
|
|
419
|
+
'attributes': attributes,
|
|
420
|
+
|
|
421
|
+
// Inline emphasis family (must come after code/links/attributes)
|
|
422
|
+
'bold-italic': inline['bold-italic'],
|
|
423
|
+
'bold': inline['bold'],
|
|
424
|
+
'italic': inline['italic'],
|
|
425
|
+
'underline': inline['underline'],
|
|
426
|
+
'strike': inline['strike'],
|
|
427
|
+
'highlight': inline['highlight'],
|
|
428
|
+
'superscript': inline['superscript'],
|
|
429
|
+
'subscript': inline['subscript'],
|
|
430
|
+
|
|
431
|
+
// Mentions @name, tags #tag, symbols :name:
|
|
432
|
+
'mention': {
|
|
433
|
+
pattern: /(^|[^\w.])@[A-Za-z0-9_][\w-]*/,
|
|
434
|
+
lookbehind: true,
|
|
435
|
+
alias: 'variable',
|
|
436
|
+
},
|
|
437
|
+
'tag': {
|
|
438
|
+
pattern: /(^|[^\w])#[A-Za-z0-9_][\w-]*/,
|
|
439
|
+
lookbehind: true,
|
|
440
|
+
alias: 'variable',
|
|
441
|
+
},
|
|
442
|
+
'symbol': {
|
|
443
|
+
// Symbol shortcode (e.g. emoji). Parser shape: name starts
|
|
444
|
+
// alphanumeric, then word chars, `+` or `-` (`:+1:` stays literal).
|
|
445
|
+
pattern: /(^|[^\w]):[A-Za-z0-9+-][\w+-]*:/,
|
|
446
|
+
lookbehind: true,
|
|
447
|
+
alias: 'constant',
|
|
448
|
+
},
|
|
449
|
+
|
|
450
|
+
// Escapes and smart typography
|
|
451
|
+
'escape': {
|
|
452
|
+
pattern: /\\[\\`*_{}[\]()#+\-.!~^/<>@%|=,]/,
|
|
453
|
+
alias: 'constant',
|
|
454
|
+
},
|
|
455
|
+
'typography': {
|
|
456
|
+
pattern: /\.\.\.|---|--|<->|<-|->|=>|!=|<=|>=|\+-|\(c\)|\(r\)|\(tm\)/,
|
|
457
|
+
alias: 'constant',
|
|
458
|
+
},
|
|
459
|
+
};
|
|
460
|
+
|
|
461
|
+
// Allow Carve to be embedded and to embed itself (e.g. inside ```carve).
|
|
462
|
+
Prism.languages.carvemd = Prism.languages.carve;
|
|
463
|
+
})(
|
|
464
|
+
(typeof globalThis !== 'undefined' && globalThis.Prism)
|
|
465
|
+
? globalThis.Prism
|
|
466
|
+
: (typeof window !== 'undefined' && window.Prism)
|
|
467
|
+
? window.Prism
|
|
468
|
+
: (typeof global !== 'undefined' && global.Prism)
|
|
469
|
+
? global.Prism
|
|
470
|
+
: undefined
|
|
471
|
+
);
|
package/shiki/carve.css
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Companion CSS for carve-grammars/shiki.
|
|
3
|
+
*
|
|
4
|
+
* Applies the Shiki dual-theme CSS variables (VitePress emits them but
|
|
5
|
+
* only applies color by default) and styles the data-carve-* attributes
|
|
6
|
+
* emitted by the carveStylingTransformer.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/* Apply Shiki font-style, font-weight and text-decoration CSS variables */
|
|
10
|
+
.vp-code span {
|
|
11
|
+
font-style: var(--shiki-light-font-style, inherit);
|
|
12
|
+
font-weight: var(--shiki-light-font-weight, inherit);
|
|
13
|
+
text-decoration: var(--shiki-light-text-decoration, inherit);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.dark .vp-code span {
|
|
17
|
+
font-style: var(--shiki-dark-font-style, inherit);
|
|
18
|
+
font-weight: var(--shiki-dark-font-weight, inherit);
|
|
19
|
+
text-decoration: var(--shiki-dark-text-decoration, inherit);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/* Carve token styling the Shiki HTML emitter can't express directly.
|
|
23
|
+
Use html prefix to outrank `html.dark .vp-code span` (specificity 0,2,2). */
|
|
24
|
+
html .vp-code span[data-carve-strike] {
|
|
25
|
+
text-decoration: line-through;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
html .vp-code span[data-carve-super] {
|
|
29
|
+
vertical-align: super;
|
|
30
|
+
font-size: 0.75em;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
html .vp-code span[data-carve-sub] {
|
|
34
|
+
vertical-align: sub;
|
|
35
|
+
font-size: 0.75em;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
html .vp-code span[data-carve-highlight] {
|
|
39
|
+
background: rgba(255, 213, 0, 0.35);
|
|
40
|
+
padding: 0 2px;
|
|
41
|
+
border-radius: 2px;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
html.dark .vp-code span[data-carve-highlight] {
|
|
45
|
+
background: rgba(255, 213, 0, 0.18);
|
|
46
|
+
}
|