@opencode-ai/ui 0.0.0-next-17078 → 0.0.0-next-17079

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 (166) hide show
  1. package/dist/context/i18n.d.ts +10 -1
  2. package/dist/context/marked-parser.d.ts +2 -0
  3. package/dist/context/marked-theme-register.d.ts +1 -0
  4. package/dist/context/marked-theme.d.ts +2 -0
  5. package/dist/context/marked.d.ts +2 -9
  6. package/dist/i18n/am.d.ts +1 -0
  7. package/dist/i18n/ar.d.ts +38 -0
  8. package/dist/i18n/az.d.ts +1 -0
  9. package/dist/i18n/bg.d.ts +193 -0
  10. package/dist/i18n/bn.d.ts +1 -0
  11. package/dist/i18n/br.d.ts +26 -0
  12. package/dist/i18n/bs.d.ts +26 -0
  13. package/dist/i18n/ca.d.ts +1 -0
  14. package/dist/i18n/cs.d.ts +1 -0
  15. package/dist/i18n/da.d.ts +22 -0
  16. package/dist/i18n/de.d.ts +22 -0
  17. package/dist/i18n/dv.d.ts +1 -0
  18. package/dist/i18n/dz.d.ts +1 -0
  19. package/dist/i18n/el.d.ts +1 -0
  20. package/dist/i18n/es.d.ts +26 -0
  21. package/dist/i18n/et.d.ts +1 -0
  22. package/dist/i18n/fa.d.ts +1 -0
  23. package/dist/i18n/fi.d.ts +1 -0
  24. package/dist/i18n/fo.d.ts +1 -0
  25. package/dist/i18n/fr.d.ts +26 -0
  26. package/dist/i18n/hi.d.ts +1 -0
  27. package/dist/i18n/hr.d.ts +1 -0
  28. package/dist/i18n/hu.d.ts +1 -0
  29. package/dist/i18n/hy.d.ts +1 -0
  30. package/dist/i18n/id.d.ts +1 -0
  31. package/dist/i18n/is.d.ts +1 -0
  32. package/dist/i18n/it.d.ts +1 -0
  33. package/dist/i18n/ja.d.ts +22 -0
  34. package/dist/i18n/ka.d.ts +1 -0
  35. package/dist/i18n/km.d.ts +193 -0
  36. package/dist/i18n/ko.d.ts +22 -0
  37. package/dist/i18n/lo.d.ts +193 -0
  38. package/dist/i18n/lt.d.ts +1 -0
  39. package/dist/i18n/lv.d.ts +1 -0
  40. package/dist/i18n/mk.d.ts +193 -0
  41. package/dist/i18n/mn.d.ts +193 -0
  42. package/dist/i18n/ms.d.ts +1 -0
  43. package/dist/i18n/my.d.ts +193 -0
  44. package/dist/i18n/ne.d.ts +1 -0
  45. package/dist/i18n/nl.d.ts +1 -0
  46. package/dist/i18n/pa.d.ts +1 -0
  47. package/dist/i18n/pl.d.ts +30 -0
  48. package/dist/i18n/ro.d.ts +1 -0
  49. package/dist/i18n/ru.d.ts +30 -0
  50. package/dist/i18n/si.d.ts +1 -0
  51. package/dist/i18n/sk.d.ts +1 -0
  52. package/dist/i18n/sl.d.ts +1 -0
  53. package/dist/i18n/sq.d.ts +1 -0
  54. package/dist/i18n/sr.d.ts +197 -0
  55. package/dist/i18n/sv.d.ts +1 -0
  56. package/dist/i18n/tg.d.ts +193 -0
  57. package/dist/i18n/th.d.ts +22 -0
  58. package/dist/i18n/tk.d.ts +1 -0
  59. package/dist/i18n/tr.d.ts +22 -0
  60. package/dist/i18n/ur.d.ts +1 -0
  61. package/dist/i18n/uz.d.ts +1 -0
  62. package/dist/i18n/vi.d.ts +1 -0
  63. package/dist/i18n/zh.d.ts +22 -0
  64. package/dist/i18n/zht.d.ts +22 -0
  65. package/dist/v2/components/toast-v2.d.ts +19 -10
  66. package/package.json +3 -3
  67. package/src/components/diff-changes.css +2 -0
  68. package/src/components/dropdown-menu.css +2 -2
  69. package/src/components/icon.css +5 -0
  70. package/src/components/icon.tsx +12 -1
  71. package/src/components/provider-icons/sprite.svg +2 -27
  72. package/src/components/resize-handle.css +14 -2
  73. package/src/components/resize-handle.tsx +5 -1
  74. package/src/components/scroll-view.css +1 -1
  75. package/src/components/select.css +5 -3
  76. package/src/components/switch.css +4 -0
  77. package/src/components/tabs.css +54 -26
  78. package/src/components/tabs.tsx +1 -0
  79. package/src/components/text-field.css +2 -2
  80. package/src/components/toast.css +1 -1
  81. package/src/context/i18n.tsx +38 -2
  82. package/src/context/marked-parser.tsx +68 -0
  83. package/src/context/marked-theme-register.tsx +10 -0
  84. package/src/context/marked-theme.tsx +372 -0
  85. package/src/context/marked.tsx +20 -562
  86. package/src/i18n/am.ts +194 -0
  87. package/src/i18n/ar.ts +62 -22
  88. package/src/i18n/az.ts +195 -0
  89. package/src/i18n/bg.ts +195 -0
  90. package/src/i18n/bn.ts +197 -0
  91. package/src/i18n/br.ts +34 -6
  92. package/src/i18n/bs.ts +51 -23
  93. package/src/i18n/ca.ts +199 -0
  94. package/src/i18n/cs.ts +203 -0
  95. package/src/i18n/da.ts +36 -12
  96. package/src/i18n/de.ts +58 -36
  97. package/src/i18n/dv.ts +196 -0
  98. package/src/i18n/dz.ts +197 -0
  99. package/src/i18n/el.ts +195 -0
  100. package/src/i18n/en.ts +24 -0
  101. package/src/i18n/es.ts +45 -17
  102. package/src/i18n/et.ts +195 -0
  103. package/src/i18n/fa.ts +195 -0
  104. package/src/i18n/fi.ts +195 -0
  105. package/src/i18n/fo.ts +195 -0
  106. package/src/i18n/fr.ts +51 -21
  107. package/src/i18n/hi.ts +197 -0
  108. package/src/i18n/hr.ts +200 -0
  109. package/src/i18n/hu.ts +197 -0
  110. package/src/i18n/hy.ts +195 -0
  111. package/src/i18n/id.ts +217 -0
  112. package/src/i18n/is.ts +195 -0
  113. package/src/i18n/it.ts +200 -0
  114. package/src/i18n/ja.ts +29 -5
  115. package/src/i18n/ka.ts +195 -0
  116. package/src/i18n/km.ts +196 -0
  117. package/src/i18n/ko.ts +36 -12
  118. package/src/i18n/lo.ts +195 -0
  119. package/src/i18n/lt.ts +203 -0
  120. package/src/i18n/lv.ts +199 -0
  121. package/src/i18n/mk.ts +195 -0
  122. package/src/i18n/mn.ts +195 -0
  123. package/src/i18n/ms.ts +195 -0
  124. package/src/i18n/my.ts +196 -0
  125. package/src/i18n/ne.ts +197 -0
  126. package/src/i18n/nl.ts +195 -0
  127. package/src/i18n/no.ts +47 -23
  128. package/src/i18n/pa.ts +196 -0
  129. package/src/i18n/pl.ts +57 -24
  130. package/src/i18n/ro.ts +199 -0
  131. package/src/i18n/ru.ts +55 -23
  132. package/src/i18n/si.ts +195 -0
  133. package/src/i18n/sk.ts +203 -0
  134. package/src/i18n/sl.ts +204 -0
  135. package/src/i18n/sq.ts +195 -0
  136. package/src/i18n/sr.ts +200 -0
  137. package/src/i18n/sv.ts +195 -0
  138. package/src/i18n/tg.ts +195 -0
  139. package/src/i18n/th.ts +44 -21
  140. package/src/i18n/tk.ts +195 -0
  141. package/src/i18n/tr.ts +49 -25
  142. package/src/i18n/uk.ts +47 -15
  143. package/src/i18n/ur.ts +196 -0
  144. package/src/i18n/uz.ts +198 -0
  145. package/src/i18n/vi.ts +195 -0
  146. package/src/i18n/zh.ts +52 -29
  147. package/src/i18n/zht.ts +45 -22
  148. package/src/theme/themes/oc-2.json +4 -2
  149. package/src/v2/components/button-v2.css +2 -2
  150. package/src/v2/components/dialog-v2.css +2 -2
  151. package/src/v2/components/dialog-v2.tsx +3 -1
  152. package/src/v2/components/diff-changes-v2.css +2 -0
  153. package/src/v2/components/file-tree-v2.css +6 -2
  154. package/src/v2/components/inline-input-v2.tsx +3 -1
  155. package/src/v2/components/line-comment-v2.css +1 -1
  156. package/src/v2/components/line-comment-v2.tsx +6 -4
  157. package/src/v2/components/select-v2.css +16 -5
  158. package/src/v2/components/switch-v2.css +8 -0
  159. package/src/v2/components/tabs-v2.css +4 -6
  160. package/src/v2/components/tabs-v2.tsx +4 -2
  161. package/src/v2/components/text-input-v2.css +7 -5
  162. package/src/v2/components/text-input-v2.tsx +7 -1
  163. package/src/v2/components/toast-v2.css +132 -122
  164. package/src/v2/components/toast-v2.tsx +208 -73
  165. package/dist/context/marked-code-span.d.ts +0 -10
  166. package/src/context/marked-code-span.ts +0 -17
@@ -1,570 +1,28 @@
1
- import { marked, type MarkedExtension, type Tokens } from "marked"
2
- import markedShiki from "marked-shiki"
3
- import katex from "katex"
1
+ import { getSharedHighlighter } from "@pierre/diffs"
4
2
  import { bundledLanguages, type BundledLanguage } from "shiki"
5
3
  import { createSimpleContext } from "./helper"
6
- import { markedCodeSpanBoundary } from "./marked-code-span"
7
- import { getSharedHighlighter, registerCustomTheme, ThemeRegistrationResolved } from "@pierre/diffs"
4
+ import { createMarkdownParser } from "./marked-parser"
5
+ import { registerOpenCodeTheme } from "./marked-theme-register"
8
6
 
9
- export const OpenCodeTheme = {
10
- name: "OpenCode",
11
- bg: "var(--color-background-stronger)",
12
- fg: "var(--text-base)",
13
- colors: {
14
- "editor.background": "var(--color-background-stronger)",
15
- "editor.foreground": "var(--text-base)",
16
- "gitDecoration.addedResourceForeground": "var(--syntax-diff-add)",
17
- "gitDecoration.deletedResourceForeground": "var(--syntax-diff-delete)",
18
- "gitDecoration.modifiedResourceForeground": "var(--syntax-diff-unknown)",
19
- // "gitDecoration.conflictingResourceForeground": "#ffca00",
20
- // "gitDecoration.modifiedResourceForeground": "#1a76d4",
21
- // "gitDecoration.untrackedResourceForeground": "#00cab1",
22
- // "gitDecoration.ignoredResourceForeground": "#84848A",
23
- // "terminal.titleForeground": "#adadb1",
24
- // "terminal.titleInactiveForeground": "#84848A",
25
- // "terminal.background": "#141415",
26
- // "terminal.foreground": "#adadb1",
27
- // "terminal.ansiBlack": "#141415",
28
- // "terminal.ansiRed": "#ff2e3f",
29
- // "terminal.ansiGreen": "#0dbe4e",
30
- // "terminal.ansiYellow": "#ffca00",
31
- // "terminal.ansiBlue": "#008cff",
32
- // "terminal.ansiMagenta": "#c635e4",
33
- // "terminal.ansiCyan": "#08c0ef",
34
- // "terminal.ansiWhite": "#c6c6c8",
35
- // "terminal.ansiBrightBlack": "#141415",
36
- // "terminal.ansiBrightRed": "#ff2e3f",
37
- // "terminal.ansiBrightGreen": "#0dbe4e",
38
- // "terminal.ansiBrightYellow": "#ffca00",
39
- // "terminal.ansiBrightBlue": "#008cff",
40
- // "terminal.ansiBrightMagenta": "#c635e4",
41
- // "terminal.ansiBrightCyan": "#08c0ef",
42
- // "terminal.ansiBrightWhite": "#c6c6c8",
43
- },
44
- tokenColors: [
45
- {
46
- scope: ["comment", "punctuation.definition.comment", "string.comment"],
47
- settings: {
48
- foreground: "var(--syntax-comment)",
49
- },
50
- },
51
- {
52
- scope: ["entity.other.attribute-name"],
53
- settings: {
54
- foreground: "var(--syntax-property)", // maybe attribute
55
- },
56
- },
57
- {
58
- scope: ["constant", "entity.name.constant", "variable.other.constant", "variable.language", "entity"],
59
- settings: {
60
- foreground: "var(--syntax-constant)",
61
- },
62
- },
63
- {
64
- scope: ["entity.name", "meta.export.default", "meta.definition.variable"],
65
- settings: {
66
- foreground: "var(--syntax-type)",
67
- },
68
- },
69
- {
70
- scope: ["meta.object.member"],
71
- settings: {
72
- foreground: "var(--syntax-primitive)",
73
- },
74
- },
75
- {
76
- scope: [
77
- "variable.parameter.function",
78
- "meta.jsx.children",
79
- "meta.block",
80
- "meta.tag.attributes",
81
- "entity.name.constant",
82
- "meta.embedded.expression",
83
- "meta.template.expression",
84
- "string.other.begin.yaml",
85
- "string.other.end.yaml",
86
- ],
87
- settings: {
88
- foreground: "var(--syntax-punctuation)",
89
- },
90
- },
91
- {
92
- scope: ["entity.name.function", "support.type.primitive"],
93
- settings: {
94
- foreground: "var(--syntax-primitive)",
95
- },
96
- },
97
- {
98
- scope: ["support.class.component"],
99
- settings: {
100
- foreground: "var(--syntax-type)",
101
- },
102
- },
103
- {
104
- scope: "keyword",
105
- settings: {
106
- foreground: "var(--syntax-keyword)",
107
- },
108
- },
109
- {
110
- scope: [
111
- "keyword.operator",
112
- "storage.type.function.arrow",
113
- "punctuation.separator.key-value.css",
114
- "entity.name.tag.yaml",
115
- "punctuation.separator.key-value.mapping.yaml",
116
- ],
117
- settings: {
118
- foreground: "var(--syntax-operator)",
119
- },
120
- },
121
- {
122
- scope: ["storage", "storage.type"],
123
- settings: {
124
- foreground: "var(--syntax-keyword)",
125
- },
126
- },
127
- {
128
- scope: ["storage.modifier.package", "storage.modifier.import", "storage.type.java"],
129
- settings: {
130
- foreground: "var(--syntax-primitive)",
131
- },
132
- },
133
- {
134
- scope: [
135
- "string",
136
- "punctuation.definition.string",
137
- "string punctuation.section.embedded source",
138
- "entity.name.tag",
139
- ],
140
- settings: {
141
- foreground: "var(--syntax-string)",
142
- },
143
- },
144
- {
145
- scope: "support",
146
- settings: {
147
- foreground: "var(--syntax-primitive)",
148
- },
149
- },
150
- {
151
- scope: ["support.type.object.module", "variable.other.object", "support.type.property-name.css"],
152
- settings: {
153
- foreground: "var(--syntax-object)",
154
- },
155
- },
156
- {
157
- scope: "meta.property-name",
158
- settings: {
159
- foreground: "var(--syntax-property)",
160
- },
161
- },
162
- {
163
- scope: "variable",
164
- settings: {
165
- foreground: "var(--syntax-variable)",
166
- },
167
- },
168
- {
169
- scope: "variable.other",
170
- settings: {
171
- foreground: "var(--syntax-variable)",
172
- },
173
- },
174
- {
175
- scope: [
176
- "invalid.broken",
177
- "invalid.illegal",
178
- "invalid.unimplemented",
179
- "invalid.deprecated",
180
- "message.error",
181
- "markup.deleted",
182
- "meta.diff.header.from-file",
183
- "punctuation.definition.deleted",
184
- "brackethighlighter.unmatched",
185
- "token.error-token",
186
- ],
187
- settings: {
188
- foreground: "var(--syntax-critical)",
189
- },
190
- },
191
- {
192
- scope: "carriage-return",
193
- settings: {
194
- foreground: "var(--syntax-keyword)",
195
- },
196
- },
197
- {
198
- scope: "string source",
199
- settings: {
200
- foreground: "var(--syntax-variable)",
201
- },
202
- },
203
- {
204
- scope: "string variable",
205
- settings: {
206
- foreground: "var(--syntax-constant)",
207
- },
208
- },
209
- {
210
- scope: [
211
- "source.regexp",
212
- "string.regexp",
213
- "string.regexp.character-class",
214
- "string.regexp constant.character.escape",
215
- "string.regexp source.ruby.embedded",
216
- "string.regexp string.regexp.arbitrary-repitition",
217
- "string.regexp constant.character.escape",
218
- ],
219
- settings: {
220
- foreground: "var(--syntax-regexp)",
221
- },
222
- },
223
- {
224
- scope: "support.constant",
225
- settings: {
226
- foreground: "var(--syntax-primitive)",
227
- },
228
- },
229
- {
230
- scope: "support.variable",
231
- settings: {
232
- foreground: "var(--syntax-variable)",
233
- },
234
- },
235
- {
236
- scope: "meta.module-reference",
237
- settings: {
238
- foreground: "var(--syntax-info)",
239
- },
240
- },
241
- {
242
- scope: "punctuation.definition.list.begin.markdown",
243
- settings: {
244
- foreground: "var(--syntax-punctuation)",
245
- },
246
- },
247
- {
248
- scope: ["markup.heading", "markup.heading entity.name"],
249
- settings: {
250
- fontStyle: "bold",
251
- foreground: "var(--syntax-info)",
252
- },
253
- },
254
- {
255
- scope: "markup.quote",
256
- settings: {
257
- foreground: "var(--syntax-info)",
258
- },
259
- },
260
- {
261
- scope: "markup.italic",
262
- settings: {
263
- fontStyle: "italic",
264
- // foreground: "",
265
- },
266
- },
267
- {
268
- scope: "markup.bold",
269
- settings: {
270
- fontStyle: "bold",
271
- foreground: "var(--text-strong)",
272
- },
273
- },
274
- {
275
- scope: [
276
- "markup.raw",
277
- "markup.inserted",
278
- "meta.diff.header.to-file",
279
- "punctuation.definition.inserted",
280
- "markup.changed",
281
- "punctuation.definition.changed",
282
- "markup.ignored",
283
- "markup.untracked",
284
- ],
285
- settings: {
286
- foreground: "var(--text-base)",
287
- },
288
- },
289
- {
290
- scope: "meta.diff.range",
291
- settings: {
292
- fontStyle: "bold",
293
- foreground: "var(--syntax-unknown)",
294
- },
295
- },
296
- {
297
- scope: "meta.diff.header",
298
- settings: {
299
- foreground: "var(--syntax-unknown)",
300
- },
301
- },
302
- {
303
- scope: "meta.separator",
304
- settings: {
305
- fontStyle: "bold",
306
- foreground: "var(--syntax-unknown)",
307
- },
308
- },
309
- {
310
- scope: "meta.output",
311
- settings: {
312
- foreground: "var(--syntax-unknown)",
313
- },
314
- },
315
- {
316
- scope: "meta.export.default",
317
- settings: {
318
- foreground: "var(--syntax-unknown)",
319
- },
320
- },
321
- {
322
- scope: [
323
- "brackethighlighter.tag",
324
- "brackethighlighter.curly",
325
- "brackethighlighter.round",
326
- "brackethighlighter.square",
327
- "brackethighlighter.angle",
328
- "brackethighlighter.quote",
329
- ],
330
- settings: {
331
- foreground: "var(--syntax-unknown)",
332
- },
333
- },
334
- {
335
- scope: ["constant.other.reference.link", "string.other.link"],
336
- settings: {
337
- fontStyle: "underline",
338
- foreground: "var(--syntax-unknown)",
339
- },
340
- },
341
- {
342
- scope: "token.info-token",
343
- settings: {
344
- foreground: "var(--syntax-info)",
345
- },
346
- },
347
- {
348
- scope: "token.warn-token",
349
- settings: {
350
- foreground: "var(--syntax-warning)",
351
- },
352
- },
353
- {
354
- scope: "token.debug-token",
355
- settings: {
356
- foreground: "var(--syntax-info)",
357
- },
358
- },
359
- ],
360
- semanticTokenColors: {
361
- comment: "var(--syntax-comment)",
362
- string: "var(--syntax-string)",
363
- number: "var(--syntax-constant)",
364
- regexp: "var(--syntax-regexp)",
365
- keyword: "var(--syntax-keyword)",
366
- variable: "var(--syntax-variable)",
367
- parameter: "var(--syntax-variable)",
368
- property: "var(--syntax-property)",
369
- function: "var(--syntax-primitive)",
370
- method: "var(--syntax-primitive)",
371
- type: "var(--syntax-type)",
372
- class: "var(--syntax-type)",
373
- namespace: "var(--syntax-type)",
374
- enumMember: "var(--syntax-primitive)",
375
- "variable.constant": "var(--syntax-constant)",
376
- "variable.defaultLibrary": "var(--syntax-unknown)",
377
- },
378
- } as unknown as ThemeRegistrationResolved
7
+ export { OpenCodeTheme } from "./marked-theme"
379
8
 
380
- registerCustomTheme("OpenCode", () => Promise.resolve(OpenCodeTheme))
381
-
382
- function renderMathInText(text: string): string {
383
- let result = text
384
-
385
- // Display math: $$...$$
386
- const displayMathRegex = /\$\$([\s\S]*?)\$\$/g
387
- result = result.replace(displayMathRegex, (_, math) => {
388
- try {
389
- return katex.renderToString(math, {
390
- displayMode: true,
391
- throwOnError: false,
392
- })
393
- } catch {
394
- return `$$${math}$$`
395
- }
396
- })
397
-
398
- // Inline math: \(...\)
399
- const inlineMathRegex = /\\\(((?:\\.|[^\\\n])*?)\\\)/g
400
- result = result.replace(inlineMathRegex, (_, math) => {
401
- try {
402
- return katex.renderToString(math, {
403
- displayMode: false,
404
- throwOnError: false,
405
- })
406
- } catch {
407
- return `\\(${math}\\)`
408
- }
409
- })
410
-
411
- return result
412
- }
413
-
414
- const inlineMathRegex = /^\\\(((?:\\.|[^\\\n])*?)\\\)/
415
- const blockMathRegex = /^\$\$\n([\s\S]+?)\n\$\$(?:\n|$)/
416
-
417
- const katexExtension: MarkedExtension = {
418
- extensions: [
419
- {
420
- name: "inlineKatex",
421
- level: "inline",
422
- start(src) {
423
- const index = src.indexOf("\\(")
424
- if (index === -1) return
425
- return index
426
- },
427
- tokenizer(src) {
428
- const match = src.match(inlineMathRegex)
429
- if (!match) return
430
- return {
431
- type: "inlineKatex",
432
- raw: match[0],
433
- text: match[1].trim(),
434
- displayMode: false,
435
- }
436
- },
437
- renderer: renderKatexToken,
438
- },
439
- {
440
- name: "blockKatex",
441
- level: "block",
442
- tokenizer(src) {
443
- const match = src.match(blockMathRegex)
444
- if (!match) return
445
- return {
446
- type: "blockKatex",
447
- raw: match[0],
448
- text: match[1].trim(),
449
- displayMode: true,
450
- }
451
- },
452
- renderer: renderKatexToken,
453
- },
454
- ],
455
- }
456
-
457
- function renderKatexToken(token: Tokens.Generic) {
458
- return katex.renderToString(typeof token.text === "string" ? token.text : "", {
459
- displayMode: token.displayMode === true,
460
- throwOnError: false,
461
- })
462
- }
463
-
464
- function renderMathExpressions(html: string): string {
465
- // Split on code/pre/kbd tags to avoid processing their contents
466
- const codeBlockPattern = /(<(?:pre|code|kbd)[^>]*>[\s\S]*?<\/(?:pre|code|kbd)>)/gi
467
- const parts = html.split(codeBlockPattern)
468
-
469
- return parts
470
- .map((part, i) => {
471
- // Odd indices are the captured code blocks - leave them alone
472
- if (i % 2 === 1) return part
473
- // Process math only in non-code parts
474
- return renderMathInText(part)
475
- })
476
- .join("")
477
- }
478
-
479
- async function highlightCodeBlocks(html: string): Promise<string> {
480
- const codeBlockRegex = /<pre><code(?:\s+class="language-([^"]*)")?>([\s\S]*?)<\/code><\/pre>/g
481
- const matches = [...html.matchAll(codeBlockRegex)]
482
- if (matches.length === 0) return html
483
-
484
- const highlighter = await getSharedHighlighter({
485
- themes: ["OpenCode"],
486
- langs: [],
487
- preferredHighlighter: "shiki-wasm",
488
- })
489
-
490
- let result = html
491
- for (const match of matches) {
492
- const [fullMatch, lang, escapedCode] = match
493
- const code = escapedCode
494
- .replace(/&lt;/g, "<")
495
- .replace(/&gt;/g, ">")
496
- .replace(/&amp;/g, "&")
497
- .replace(/&quot;/g, '"')
498
- .replace(/&#39;/g, "'")
499
-
500
- let language = lang || "text"
501
- if (!(language in bundledLanguages)) {
502
- language = "text"
503
- }
504
- if (!highlighter.getLoadedLanguages().includes(language)) {
505
- await highlighter.loadLanguage(language as BundledLanguage)
506
- }
507
-
508
- const highlighted = highlighter.codeToHtml(code, {
509
- lang: language,
510
- theme: "OpenCode",
511
- tabindex: false,
512
- })
513
- result = result.replace(fullMatch, () => highlighted)
514
- }
515
-
516
- return result
517
- }
518
-
519
- export type NativeMarkdownParser = (markdown: string) => Promise<string>
9
+ registerOpenCodeTheme()
520
10
 
521
11
  export const { use: useMarked, provider: MarkedProvider } = createSimpleContext({
522
12
  name: "Marked",
523
- init: (props: { nativeParser?: NativeMarkdownParser }) => {
524
- const jsParser = marked.use(
525
- markedCodeSpanBoundary,
526
- {
527
- renderer: {
528
- link({ href, title, text }) {
529
- const titleAttr = title ? ` title="${title}"` : ""
530
- return `<a href="${href}"${titleAttr} class="external-link" target="_blank" rel="noopener noreferrer">${text}</a>`
531
- },
532
- },
533
- },
534
- katexExtension,
535
- markedShiki({
536
- async highlight(code, lang) {
537
- const highlighter = await getSharedHighlighter({
538
- themes: ["OpenCode"],
539
- langs: [],
540
- preferredHighlighter: "shiki-wasm",
541
- })
542
- if (!(lang in bundledLanguages)) {
543
- lang = "text"
544
- }
545
- if (!highlighter.getLoadedLanguages().includes(lang)) {
546
- await highlighter.loadLanguage(lang as BundledLanguage)
547
- }
548
- return highlighter.codeToHtml(code, {
549
- lang: lang || "text",
550
- theme: "OpenCode",
551
- tabindex: false,
552
- })
553
- },
554
- }),
555
- )
556
-
557
- if (props.nativeParser) {
558
- const nativeParser = props.nativeParser
559
- return {
560
- async parse(markdown: string): Promise<string> {
561
- const html = await nativeParser(markdown)
562
- const withMath = renderMathExpressions(html)
563
- return highlightCodeBlocks(withMath)
564
- },
565
- }
566
- }
567
-
568
- return jsParser
569
- },
13
+ init: () =>
14
+ createMarkdownParser(async (code, language) => {
15
+ const highlighter = await getSharedHighlighter({
16
+ themes: ["OpenCode"],
17
+ langs: [],
18
+ preferredHighlighter: "shiki-wasm",
19
+ })
20
+ const name = language in bundledLanguages ? language : "text"
21
+ if (!highlighter.getLoadedLanguages().includes(name)) await highlighter.loadLanguage(name as BundledLanguage)
22
+ return highlighter.codeToHtml(code, {
23
+ lang: name,
24
+ theme: "OpenCode",
25
+ tabindex: false,
26
+ })
27
+ }),
570
28
  })