carve-grammars 0.1.0
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 +206 -0
- package/highlightjs/carve.js +456 -0
- package/highlightjs/carve.mjs +25 -0
- package/package.json +105 -0
- package/prism/carve.js +409 -0
- package/tiptap/carve-kit.js +498 -0
- package/tiptap/extensions/carve-abbreviation.js +79 -0
- package/tiptap/extensions/carve-definition-list.js +270 -0
- package/tiptap/extensions/carve-delete.js +49 -0
- package/tiptap/extensions/carve-div.js +110 -0
- package/tiptap/extensions/carve-embed.js +164 -0
- package/tiptap/extensions/carve-footnote-definition.js +81 -0
- package/tiptap/extensions/carve-footnote.js +76 -0
- package/tiptap/extensions/carve-insert.js +49 -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/index.js +14 -0
- package/tiptap/index.js +53 -0
- package/tiptap/serializer.js +584 -0
|
@@ -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,105 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "carve-grammars",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Grammars for the Carve markup language: Tiptap editor kit + serializer, plus Prism and highlight.js 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/parse-test.js && node tests/grammar-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
|
+
"README.md",
|
|
42
|
+
"LICENSE"
|
|
43
|
+
],
|
|
44
|
+
"exports": {
|
|
45
|
+
".": "./tiptap/index.js",
|
|
46
|
+
"./tiptap": "./tiptap/index.js",
|
|
47
|
+
"./tiptap/*": "./tiptap/*",
|
|
48
|
+
"./prism/carve.js": "./prism/carve.js",
|
|
49
|
+
"./prism/*": "./prism/*",
|
|
50
|
+
"./highlightjs/carve.js": {
|
|
51
|
+
"import": "./highlightjs/carve.mjs",
|
|
52
|
+
"default": "./highlightjs/carve.js"
|
|
53
|
+
},
|
|
54
|
+
"./highlightjs/*": "./highlightjs/*"
|
|
55
|
+
},
|
|
56
|
+
"peerDependencies": {
|
|
57
|
+
"@tiptap/core": "^2",
|
|
58
|
+
"@tiptap/extension-underline": "^2",
|
|
59
|
+
"@tiptap/starter-kit": "^2",
|
|
60
|
+
"highlight.js": "^11",
|
|
61
|
+
"prismjs": "^1"
|
|
62
|
+
},
|
|
63
|
+
"peerDependenciesMeta": {
|
|
64
|
+
"@tiptap/core": {
|
|
65
|
+
"optional": true
|
|
66
|
+
},
|
|
67
|
+
"@tiptap/starter-kit": {
|
|
68
|
+
"optional": true
|
|
69
|
+
},
|
|
70
|
+
"@tiptap/extension-underline": {
|
|
71
|
+
"optional": true
|
|
72
|
+
},
|
|
73
|
+
"prismjs": {
|
|
74
|
+
"optional": true
|
|
75
|
+
},
|
|
76
|
+
"highlight.js": {
|
|
77
|
+
"optional": true
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
"devDependencies": {
|
|
81
|
+
"@markup-carve/carve": "github:markup-carve/carve-js",
|
|
82
|
+
"@tiptap/core": "^2.27.2",
|
|
83
|
+
"@tiptap/extension-bullet-list": "^2.27.2",
|
|
84
|
+
"@tiptap/extension-code-block": "^2.27.2",
|
|
85
|
+
"@tiptap/extension-hard-break": "^2.27.2",
|
|
86
|
+
"@tiptap/extension-highlight": "^2.27.2",
|
|
87
|
+
"@tiptap/extension-image": "^2.27.2",
|
|
88
|
+
"@tiptap/extension-link": "^2.27.2",
|
|
89
|
+
"@tiptap/extension-list-item": "^2.27.2",
|
|
90
|
+
"@tiptap/extension-subscript": "^2.27.2",
|
|
91
|
+
"@tiptap/extension-superscript": "^2.27.2",
|
|
92
|
+
"@tiptap/extension-table": "^2.27.2",
|
|
93
|
+
"@tiptap/extension-table-cell": "^2.27.2",
|
|
94
|
+
"@tiptap/extension-table-header": "^2.27.2",
|
|
95
|
+
"@tiptap/extension-table-row": "^2.27.2",
|
|
96
|
+
"@tiptap/extension-task-item": "^2.27.2",
|
|
97
|
+
"@tiptap/extension-task-list": "^2.27.2",
|
|
98
|
+
"@tiptap/extension-underline": "^2.27.2",
|
|
99
|
+
"@tiptap/pm": "^2.27.2",
|
|
100
|
+
"@tiptap/starter-kit": "^2.27.2",
|
|
101
|
+
"happy-dom": "^20.10.6",
|
|
102
|
+
"highlight.js": "^11.11.1",
|
|
103
|
+
"prismjs": "^1.30.0"
|
|
104
|
+
}
|
|
105
|
+
}
|
package/prism/carve.js
ADDED
|
@@ -0,0 +1,409 @@
|
|
|
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
|
+
var attributes = {
|
|
35
|
+
pattern: /\{[^}\n]+\}/,
|
|
36
|
+
alias: 'attr-value',
|
|
37
|
+
inside: {
|
|
38
|
+
'id': /#[A-Za-z_][\w-]*/,
|
|
39
|
+
'class-name': /\.[A-Za-z_][\w-]*/,
|
|
40
|
+
'attr-name': /[A-Za-z_:][\w:-]*(?==)/,
|
|
41
|
+
'string': /"[^"]*"|'[^']*'/,
|
|
42
|
+
'punctuation': /[{}=]/,
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// Shared inline emphasis/markup, referenced from block tokens that contain
|
|
47
|
+
// running text (headings, list items, table cells, quotes).
|
|
48
|
+
var inline = {
|
|
49
|
+
'bold-italic': {
|
|
50
|
+
pattern: /\/\*(?=\S)[^*]+\*\//,
|
|
51
|
+
alias: 'important',
|
|
52
|
+
},
|
|
53
|
+
// The "no leading/trailing space" rule is expressed without JS
|
|
54
|
+
// lookbehind (unsupported on Safari < 16.4 and some engines): the first
|
|
55
|
+
// and last content chars are required to be non-space directly.
|
|
56
|
+
'bold': {
|
|
57
|
+
pattern: /\*[^*\s\n](?:[^*\n]*?[^*\s\n])?\*/,
|
|
58
|
+
alias: 'bold',
|
|
59
|
+
},
|
|
60
|
+
'italic': {
|
|
61
|
+
// leading guard via Prism lookbehind (avoids URLs, paths); the
|
|
62
|
+
// trailing `(?![\w/])` lookahead is fine (lookahead is universal).
|
|
63
|
+
pattern: /(^|[^\w/])\/[^/\s\n](?:[^/\n]*?[^/\s\n])?\/(?![\w/])/,
|
|
64
|
+
lookbehind: true,
|
|
65
|
+
alias: 'italic',
|
|
66
|
+
},
|
|
67
|
+
'underline': {
|
|
68
|
+
pattern: /(^|[^\w_])_[^_\s\n](?:[^_\n]*?[^_\s\n])?_(?![\w_])/,
|
|
69
|
+
lookbehind: true,
|
|
70
|
+
alias: 'underline',
|
|
71
|
+
},
|
|
72
|
+
'strike': {
|
|
73
|
+
pattern: /~[^~\s\n](?:[^~\n]*?[^~\s\n])?~/,
|
|
74
|
+
alias: 'deleted',
|
|
75
|
+
},
|
|
76
|
+
'highlight': {
|
|
77
|
+
pattern: /\{=(?=\S)[^\n]*?=\}|(?<![\w=])=(?=\S)[^=\n]+?(?<=\S)=(?![\w=])/,
|
|
78
|
+
alias: 'important',
|
|
79
|
+
},
|
|
80
|
+
'superscript': {
|
|
81
|
+
pattern: /\{\^(?=\S)[^\n]*?\^\}|\^(?=\S)[^\s^\n]+?\^/,
|
|
82
|
+
alias: 'important',
|
|
83
|
+
},
|
|
84
|
+
'subscript': {
|
|
85
|
+
pattern: /\{,(?=\S)[^\n]*?,\}|(?<![\w,]),(?=\S)[^,\n]+?(?<=\S),(?![\w,])/,
|
|
86
|
+
alias: 'important',
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
Prism.languages.carve = {
|
|
91
|
+
// Block comments %%% ... %%% and line comments %% ...
|
|
92
|
+
// The comment fence is a *bare* %%% line; a `%%% format` opener is a
|
|
93
|
+
// raw passthrough block instead (handled by #raw-block below).
|
|
94
|
+
'comment': [
|
|
95
|
+
{
|
|
96
|
+
pattern: /^[ \t]*%%%[ \t]*\n[\s\S]*?^[ \t]*%%%[ \t]*$/m,
|
|
97
|
+
greedy: true,
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
pattern: /^[ \t]*%%(?!%).*$/m,
|
|
101
|
+
greedy: true,
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
// trailing comment after whitespace (Prism lookbehind, no JS
|
|
105
|
+
// lookbehind: the leading space is captured and excluded).
|
|
106
|
+
pattern: /([ \t])%%.*$/m,
|
|
107
|
+
lookbehind: true,
|
|
108
|
+
greedy: true,
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
|
|
112
|
+
// YAML/typed front matter delimited by --- at the very top of the file.
|
|
113
|
+
// `^` (no `m` flag) anchors to the start of the document; the close is
|
|
114
|
+
// matched at end-of-line so a document body may follow.
|
|
115
|
+
'front-matter': {
|
|
116
|
+
pattern: /^---[ \t]*[A-Za-z0-9_-]*[ \t]*\n[\s\S]*?\n---[ \t]*(?:\n|$)/,
|
|
117
|
+
alias: 'comment',
|
|
118
|
+
greedy: true,
|
|
119
|
+
inside: {
|
|
120
|
+
'punctuation': /---/,
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
|
|
124
|
+
// Fenced code blocks: ``` lang ... ``` or ~~~ lang ... ~~~
|
|
125
|
+
'code-block': {
|
|
126
|
+
pattern: /^(`{3,}|~{3,})[ \t]*[^\n]*\n[\s\S]*?^\1[ \t]*$/m,
|
|
127
|
+
greedy: true,
|
|
128
|
+
inside: {
|
|
129
|
+
'punctuation': /^(?:`{3,}|~{3,})|(?:`{3,}|~{3,})$/,
|
|
130
|
+
'language': {
|
|
131
|
+
pattern: /(^(?:`{3,}|~{3,})[ \t]*)[^\s`~]+/,
|
|
132
|
+
lookbehind: true,
|
|
133
|
+
alias: 'class-name',
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
|
|
138
|
+
// Raw passthrough blocks: %%% format ... %%% (rendered verbatim)
|
|
139
|
+
'raw-block': {
|
|
140
|
+
pattern: /^%{3,}[ \t]*\S*[ \t]*\n[\s\S]*?^%{3,}[ \t]*$/m,
|
|
141
|
+
greedy: true,
|
|
142
|
+
alias: 'string',
|
|
143
|
+
inside: {
|
|
144
|
+
'punctuation': /^%{3,}|%{3,}$/,
|
|
145
|
+
'language': {
|
|
146
|
+
pattern: /(^%{3,}[ \t]*)\S+/,
|
|
147
|
+
lookbehind: true,
|
|
148
|
+
alias: 'class-name',
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
|
|
153
|
+
// ATX headings # .. ######
|
|
154
|
+
'title': {
|
|
155
|
+
pattern: /^#{1,6}[ \t]+.+$/m,
|
|
156
|
+
alias: 'important',
|
|
157
|
+
inside: Object.assign({
|
|
158
|
+
'punctuation': /^#{1,6}/,
|
|
159
|
+
}, inline),
|
|
160
|
+
},
|
|
161
|
+
|
|
162
|
+
// Container divs ::: class / :::
|
|
163
|
+
'div': {
|
|
164
|
+
pattern: /^[ \t]*:{3,}[ \t]*[^\s{]*.*$/m,
|
|
165
|
+
alias: 'tag',
|
|
166
|
+
inside: {
|
|
167
|
+
'punctuation': /:{3,}/,
|
|
168
|
+
'class-name': {
|
|
169
|
+
pattern: /(^[ \t]*:{3,}[ \t]*)[^\s{]+/,
|
|
170
|
+
lookbehind: true,
|
|
171
|
+
},
|
|
172
|
+
'attributes': attributes,
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
|
|
176
|
+
// Table rows: | a | b | (plus header `|=`, caption `^`, span markers)
|
|
177
|
+
'table': {
|
|
178
|
+
pattern: /^[ \t]*\|.*$/m,
|
|
179
|
+
inside: Object.assign({
|
|
180
|
+
// rowspan `^` / colspan `<` markers - must precede `punctuation`
|
|
181
|
+
// so the surrounding `|` is not consumed first.
|
|
182
|
+
'operator': {
|
|
183
|
+
pattern: /(\|)[ \t]*[\^<](?=[ \t]*\|)/,
|
|
184
|
+
lookbehind: true,
|
|
185
|
+
},
|
|
186
|
+
'punctuation': /\|=|\|/,
|
|
187
|
+
'attributes': attributes,
|
|
188
|
+
'url': /\[[^\]]+\]\([^\s)]+\)/,
|
|
189
|
+
}, inline),
|
|
190
|
+
},
|
|
191
|
+
|
|
192
|
+
// Table continuation / list continuation: a lone `+`
|
|
193
|
+
'table-continuation': {
|
|
194
|
+
pattern: /^[ \t]*\+[ \t]*$/m,
|
|
195
|
+
alias: 'punctuation',
|
|
196
|
+
},
|
|
197
|
+
|
|
198
|
+
// Blockquotes: leading > (possibly nested >>)
|
|
199
|
+
'blockquote': {
|
|
200
|
+
pattern: /^[ \t]*>+[ \t]?.*$/m,
|
|
201
|
+
inside: Object.assign({
|
|
202
|
+
'punctuation': /^[ \t]*>+/,
|
|
203
|
+
}, inline),
|
|
204
|
+
},
|
|
205
|
+
|
|
206
|
+
// List markers: -, *, ordered (1. a) i.), task [ ]/[x], definition `: `
|
|
207
|
+
'list': {
|
|
208
|
+
pattern: /^[ \t]*(?:[-*][ \t]+(?:\[[ xX]\][ \t]+)?|(?:[0-9]+|[A-Za-z]|[ivxlcdmIVXLCDM]+)[.)][ \t]+|:[ \t]+)/m,
|
|
209
|
+
alias: 'punctuation',
|
|
210
|
+
inside: {
|
|
211
|
+
'constant': /\[[ xX]\]/,
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
|
|
215
|
+
// Reference link / abbreviation definitions
|
|
216
|
+
'reference-definition': {
|
|
217
|
+
pattern: /^[ \t]*\[[^\]]+\]:[ \t]+\S+.*$/m,
|
|
218
|
+
alias: 'url',
|
|
219
|
+
inside: {
|
|
220
|
+
'constant': /^[ \t]*\[[^\]]+\]:/,
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
'abbreviation-definition': {
|
|
224
|
+
pattern: /^[ \t]*\*\[[A-Z][A-Z0-9]*\]:[ \t]+.*$/m,
|
|
225
|
+
inside: {
|
|
226
|
+
'punctuation': /^[ \t]*\*|\[|\]|:/,
|
|
227
|
+
'symbol': /[A-Z][A-Z0-9]*/,
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
|
|
231
|
+
// Display + inline math: $$`...`$$ and $`...`$
|
|
232
|
+
'math': [
|
|
233
|
+
{
|
|
234
|
+
pattern: /\$\$(`+)[\s\S]*?\1\$\$/,
|
|
235
|
+
greedy: true,
|
|
236
|
+
alias: 'string',
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
pattern: /\$(`+)[\s\S]*?\1\$/,
|
|
240
|
+
greedy: true,
|
|
241
|
+
alias: 'string',
|
|
242
|
+
},
|
|
243
|
+
],
|
|
244
|
+
|
|
245
|
+
// Raw inline passthrough: `code`{=format}
|
|
246
|
+
'raw-inline': {
|
|
247
|
+
pattern: /(`+)(?:[^`]|[^`][\s\S]*?[^`])\1\{=[A-Za-z_][\w-]*\}/,
|
|
248
|
+
greedy: true,
|
|
249
|
+
alias: 'string',
|
|
250
|
+
},
|
|
251
|
+
|
|
252
|
+
// Inline code spans
|
|
253
|
+
'code': {
|
|
254
|
+
pattern: /(`+)(?:[^`]|[^`][\s\S]*?[^`])\1/,
|
|
255
|
+
greedy: true,
|
|
256
|
+
},
|
|
257
|
+
|
|
258
|
+
// Images: 
|
|
259
|
+
'image': {
|
|
260
|
+
pattern: /!\[[^\]]*\]\([^\s)]+(?:[ \t]+"[^"]*")?\)/,
|
|
261
|
+
greedy: true,
|
|
262
|
+
alias: 'url',
|
|
263
|
+
inside: {
|
|
264
|
+
'string': /"[^"]*"/,
|
|
265
|
+
'punctuation': /!\[|\]\(|\)/,
|
|
266
|
+
},
|
|
267
|
+
},
|
|
268
|
+
|
|
269
|
+
// Footnote references: [^label]
|
|
270
|
+
'footnote': {
|
|
271
|
+
pattern: /\[\^[^\]]+\]/,
|
|
272
|
+
alias: 'symbol',
|
|
273
|
+
},
|
|
274
|
+
|
|
275
|
+
// Citations (Tier-2 §22): [@key], [+@key], [@key, p.10], [@a; @b; @c]
|
|
276
|
+
// Distinguished from links/spans/refs by the absence of a trailing
|
|
277
|
+
// `(url)`, `[ref]`, or `{attrs}` suffix. The bracket MUST contain at
|
|
278
|
+
// least one `@key` item.
|
|
279
|
+
'citation': {
|
|
280
|
+
pattern: /\[\+?(?:[^\]@]*@[A-Za-z0-9_][A-Za-z0-9_.:#$%&+?<>~\/-]*(?:[^\]]*)?)\](?!\(|\[|\{)/,
|
|
281
|
+
greedy: true,
|
|
282
|
+
alias: 'string',
|
|
283
|
+
inside: {
|
|
284
|
+
// Integral marker `+` and suppress-author `-`
|
|
285
|
+
'operator': /(?<=^\[)\+|(?<=[@;]\s*)-(?=@)/,
|
|
286
|
+
// The `@key` itself
|
|
287
|
+
'function': /@[A-Za-z0-9_][A-Za-z0-9_.:#$%&+?<>~\/-]*/,
|
|
288
|
+
// Separators and locator punctuation
|
|
289
|
+
'punctuation': /\[|\]|;|,/,
|
|
290
|
+
},
|
|
291
|
+
},
|
|
292
|
+
|
|
293
|
+
// Code callouts (Tier-2 §10): <n> markers trailing a code-fence line
|
|
294
|
+
// or leading a callout-list item. Only pure-digit content.
|
|
295
|
+
'code-callout': {
|
|
296
|
+
pattern: /<\d+>/,
|
|
297
|
+
alias: 'symbol',
|
|
298
|
+
},
|
|
299
|
+
|
|
300
|
+
// Inline links: [text](url "title") and reference [text][id]
|
|
301
|
+
'url': [
|
|
302
|
+
{
|
|
303
|
+
pattern: /\[[^\]]+\]\([^\s)]+(?:[ \t]+"[^"]*")?\)/,
|
|
304
|
+
greedy: true,
|
|
305
|
+
inside: {
|
|
306
|
+
'string': /"[^"]*"/,
|
|
307
|
+
'punctuation': /\[|\]\(|\)/,
|
|
308
|
+
},
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
pattern: /\[[^\]]+\]\[[^\]]*\]/,
|
|
312
|
+
greedy: true,
|
|
313
|
+
inside: {
|
|
314
|
+
'punctuation': /\[|\]\[|\]/,
|
|
315
|
+
},
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
// autolink <https://...> and <mailto-ish>
|
|
319
|
+
pattern: /<[a-zA-Z][a-zA-Z0-9+.-]*:[^>\s]+>|<[^>\s@]+@[^>\s]+>/,
|
|
320
|
+
greedy: true,
|
|
321
|
+
},
|
|
322
|
+
],
|
|
323
|
+
|
|
324
|
+
// Bracketed span with attributes: [text]{.class}
|
|
325
|
+
'span': {
|
|
326
|
+
pattern: /\[[^\^\]][^\]]*\](?=\{)/,
|
|
327
|
+
alias: 'string',
|
|
328
|
+
},
|
|
329
|
+
|
|
330
|
+
// Extension inline call: :name[content]{attrs}
|
|
331
|
+
'extension': {
|
|
332
|
+
pattern: /:[a-zA-Z][\w-]*\[[^\]]*\](?:\{[^}]*\})?/,
|
|
333
|
+
alias: 'function',
|
|
334
|
+
inside: {
|
|
335
|
+
'function': /:[a-zA-Z][\w-]*/,
|
|
336
|
+
'attributes': attributes,
|
|
337
|
+
'punctuation': /\[|\]/,
|
|
338
|
+
},
|
|
339
|
+
},
|
|
340
|
+
|
|
341
|
+
// CriticMarkup: {+ins+} {-del-} {~old~>new~} {#comment#}
|
|
342
|
+
'inserted': {
|
|
343
|
+
pattern: /\{\+[^}]*\+\}/,
|
|
344
|
+
alias: 'inserted',
|
|
345
|
+
},
|
|
346
|
+
'deleted': {
|
|
347
|
+
pattern: /\{-[^}]*-\}/,
|
|
348
|
+
alias: 'deleted',
|
|
349
|
+
},
|
|
350
|
+
'changed': {
|
|
351
|
+
pattern: /\{~[^~]*~>[^~]*~\}/,
|
|
352
|
+
alias: 'important',
|
|
353
|
+
},
|
|
354
|
+
'critic-comment': {
|
|
355
|
+
pattern: /\{#[^}]*#\}/,
|
|
356
|
+
alias: 'comment',
|
|
357
|
+
},
|
|
358
|
+
|
|
359
|
+
// Attribute blocks attached to the preceding element
|
|
360
|
+
'attributes': attributes,
|
|
361
|
+
|
|
362
|
+
// Inline emphasis family (must come after code/links/attributes)
|
|
363
|
+
'bold-italic': inline['bold-italic'],
|
|
364
|
+
'bold': inline['bold'],
|
|
365
|
+
'italic': inline['italic'],
|
|
366
|
+
'underline': inline['underline'],
|
|
367
|
+
'strike': inline['strike'],
|
|
368
|
+
'highlight': inline['highlight'],
|
|
369
|
+
'superscript': inline['superscript'],
|
|
370
|
+
'subscript': inline['subscript'],
|
|
371
|
+
|
|
372
|
+
// Mentions @name, tags #tag, emoji :name:
|
|
373
|
+
'mention': {
|
|
374
|
+
pattern: /(^|[^\w.])@[A-Za-z0-9_][\w-]*/,
|
|
375
|
+
lookbehind: true,
|
|
376
|
+
alias: 'variable',
|
|
377
|
+
},
|
|
378
|
+
'tag': {
|
|
379
|
+
pattern: /(^|[^\w])#[A-Za-z0-9_][\w-]*/,
|
|
380
|
+
lookbehind: true,
|
|
381
|
+
alias: 'variable',
|
|
382
|
+
},
|
|
383
|
+
'emoji': {
|
|
384
|
+
pattern: /:[A-Za-z0-9_+-]+:/,
|
|
385
|
+
alias: 'constant',
|
|
386
|
+
},
|
|
387
|
+
|
|
388
|
+
// Escapes and smart typography
|
|
389
|
+
'escape': {
|
|
390
|
+
pattern: /\\[\\`*_{}[\]()#+\-.!~^/<>@%|=,]/,
|
|
391
|
+
alias: 'constant',
|
|
392
|
+
},
|
|
393
|
+
'typography': {
|
|
394
|
+
pattern: /\.\.\.|---|--|<->|<-|->|=>|!=|<=|>=|\+-|\(c\)|\(r\)|\(tm\)/,
|
|
395
|
+
alias: 'constant',
|
|
396
|
+
},
|
|
397
|
+
};
|
|
398
|
+
|
|
399
|
+
// Allow Carve to be embedded and to embed itself (e.g. inside ```carve).
|
|
400
|
+
Prism.languages.carvemd = Prism.languages.carve;
|
|
401
|
+
})(
|
|
402
|
+
(typeof globalThis !== 'undefined' && globalThis.Prism)
|
|
403
|
+
? globalThis.Prism
|
|
404
|
+
: (typeof window !== 'undefined' && window.Prism)
|
|
405
|
+
? window.Prism
|
|
406
|
+
: (typeof global !== 'undefined' && global.Prism)
|
|
407
|
+
? global.Prism
|
|
408
|
+
: undefined
|
|
409
|
+
);
|