@particle-academy/fancy-code 0.8.0 → 0.9.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/dist/index.cjs +15 -198
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -36
- package/dist/index.d.ts +3 -36
- package/dist/index.js +6 -189
- package/dist/index.js.map +1 -1
- package/package.json +5 -2
package/dist/index.d.cts
CHANGED
|
@@ -1,34 +1,9 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { RefObject, ReactNode, CSSProperties } from 'react';
|
|
3
|
-
import { DiffAnnotations, LineChangeType } from '@particle-academy/fancy-file-commons';
|
|
4
|
-
export { languageFromFilename } from '@particle-academy/fancy-file-commons';
|
|
3
|
+
import { ThemeColors, DiffAnnotations, LineChangeType, Token, Tokenizer } from '@particle-academy/fancy-file-commons';
|
|
4
|
+
export { ThemeColors, Token, TokenType, Tokenizer, languageFromFilename } from '@particle-academy/fancy-file-commons';
|
|
5
5
|
import { MediaKind, MediaViewerProps, InputTagProps, InputTagTriggers, InputTagAdapter } from '@particle-academy/react-fancy';
|
|
6
6
|
|
|
7
|
-
interface ThemeColors {
|
|
8
|
-
background: string;
|
|
9
|
-
foreground: string;
|
|
10
|
-
gutterBackground: string;
|
|
11
|
-
gutterForeground: string;
|
|
12
|
-
gutterBorder: string;
|
|
13
|
-
activeLineBackground: string;
|
|
14
|
-
selectionBackground: string;
|
|
15
|
-
cursorColor: string;
|
|
16
|
-
diffAdded?: string;
|
|
17
|
-
diffModified?: string;
|
|
18
|
-
diffRemoved?: string;
|
|
19
|
-
keyword: string;
|
|
20
|
-
string: string;
|
|
21
|
-
comment: string;
|
|
22
|
-
number: string;
|
|
23
|
-
operator: string;
|
|
24
|
-
function: string;
|
|
25
|
-
type: string;
|
|
26
|
-
tag: string;
|
|
27
|
-
attribute: string;
|
|
28
|
-
attributeValue: string;
|
|
29
|
-
punctuation: string;
|
|
30
|
-
variable: string;
|
|
31
|
-
}
|
|
32
7
|
interface ThemeDefinition {
|
|
33
8
|
/** Unique theme name */
|
|
34
9
|
name: string;
|
|
@@ -407,14 +382,6 @@ declare function diffRemovedColor(colors: ThemeColors): string;
|
|
|
407
382
|
*/
|
|
408
383
|
declare function renderMarkdown(markdown: string): string;
|
|
409
384
|
|
|
410
|
-
type TokenType = "keyword" | "string" | "comment" | "number" | "operator" | "tag" | "attribute" | "attributeValue" | "punctuation" | "function" | "type" | "variable" | "plain";
|
|
411
|
-
interface Token {
|
|
412
|
-
type: TokenType;
|
|
413
|
-
start: number;
|
|
414
|
-
end: number;
|
|
415
|
-
}
|
|
416
|
-
type Tokenizer = (source: string) => Token[];
|
|
417
|
-
|
|
418
385
|
/**
|
|
419
386
|
* Minimal, dependency-free Markdown tokenizer for editor highlighting. Line-based
|
|
420
387
|
* for block constructs (fences, headings, blockquotes, list markers) plus a few
|
|
@@ -481,4 +448,4 @@ interface CodeEditorInputTagProps extends Omit<InputTagProps, "adapter"> {
|
|
|
481
448
|
*/
|
|
482
449
|
declare function CodeEditorInputTag(props: CodeEditorInputTagProps): react.JSX.Element;
|
|
483
450
|
|
|
484
|
-
export { CodeEditor, type CodeEditorContextValue, CodeEditorInputTag, type CodeEditorInputTagProps, type CodeEditorPanelProps, type CodeEditorProps, type CodeEditorStatusBarProps, type CodeEditorToolbarProps, type FileKind, FileViewer, type FileViewerProps, type GutterDiffMark, type LanguageDefinition, MarkdownEditor, type MarkdownEditorMode, type MarkdownEditorProps, type ResolveFileKindInput, type
|
|
451
|
+
export { CodeEditor, type CodeEditorContextValue, CodeEditorInputTag, type CodeEditorInputTagProps, type CodeEditorPanelProps, type CodeEditorProps, type CodeEditorStatusBarProps, type CodeEditorToolbarProps, type FileKind, FileViewer, type FileViewerProps, type GutterDiffMark, type LanguageDefinition, MarkdownEditor, type MarkdownEditorMode, type MarkdownEditorProps, type ResolveFileKindInput, type ThemeDefinition, diffMarkColor, diffRemovedColor, getLanguage, getRegisteredLanguages, getRegisteredThemes, getTheme, gutterDiffMark, hasDeletedAtEnd, registerLanguage, registerTheme, renderMarkdown, resolveFileKind, tokenizeMarkdown, useCodeEditor, useCodeEditorInputTagAdapter };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,34 +1,9 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { RefObject, ReactNode, CSSProperties } from 'react';
|
|
3
|
-
import { DiffAnnotations, LineChangeType } from '@particle-academy/fancy-file-commons';
|
|
4
|
-
export { languageFromFilename } from '@particle-academy/fancy-file-commons';
|
|
3
|
+
import { ThemeColors, DiffAnnotations, LineChangeType, Token, Tokenizer } from '@particle-academy/fancy-file-commons';
|
|
4
|
+
export { ThemeColors, Token, TokenType, Tokenizer, languageFromFilename } from '@particle-academy/fancy-file-commons';
|
|
5
5
|
import { MediaKind, MediaViewerProps, InputTagProps, InputTagTriggers, InputTagAdapter } from '@particle-academy/react-fancy';
|
|
6
6
|
|
|
7
|
-
interface ThemeColors {
|
|
8
|
-
background: string;
|
|
9
|
-
foreground: string;
|
|
10
|
-
gutterBackground: string;
|
|
11
|
-
gutterForeground: string;
|
|
12
|
-
gutterBorder: string;
|
|
13
|
-
activeLineBackground: string;
|
|
14
|
-
selectionBackground: string;
|
|
15
|
-
cursorColor: string;
|
|
16
|
-
diffAdded?: string;
|
|
17
|
-
diffModified?: string;
|
|
18
|
-
diffRemoved?: string;
|
|
19
|
-
keyword: string;
|
|
20
|
-
string: string;
|
|
21
|
-
comment: string;
|
|
22
|
-
number: string;
|
|
23
|
-
operator: string;
|
|
24
|
-
function: string;
|
|
25
|
-
type: string;
|
|
26
|
-
tag: string;
|
|
27
|
-
attribute: string;
|
|
28
|
-
attributeValue: string;
|
|
29
|
-
punctuation: string;
|
|
30
|
-
variable: string;
|
|
31
|
-
}
|
|
32
7
|
interface ThemeDefinition {
|
|
33
8
|
/** Unique theme name */
|
|
34
9
|
name: string;
|
|
@@ -407,14 +382,6 @@ declare function diffRemovedColor(colors: ThemeColors): string;
|
|
|
407
382
|
*/
|
|
408
383
|
declare function renderMarkdown(markdown: string): string;
|
|
409
384
|
|
|
410
|
-
type TokenType = "keyword" | "string" | "comment" | "number" | "operator" | "tag" | "attribute" | "attributeValue" | "punctuation" | "function" | "type" | "variable" | "plain";
|
|
411
|
-
interface Token {
|
|
412
|
-
type: TokenType;
|
|
413
|
-
start: number;
|
|
414
|
-
end: number;
|
|
415
|
-
}
|
|
416
|
-
type Tokenizer = (source: string) => Token[];
|
|
417
|
-
|
|
418
385
|
/**
|
|
419
386
|
* Minimal, dependency-free Markdown tokenizer for editor highlighting. Line-based
|
|
420
387
|
* for block constructs (fences, headings, blockquotes, list markers) plus a few
|
|
@@ -481,4 +448,4 @@ interface CodeEditorInputTagProps extends Omit<InputTagProps, "adapter"> {
|
|
|
481
448
|
*/
|
|
482
449
|
declare function CodeEditorInputTag(props: CodeEditorInputTagProps): react.JSX.Element;
|
|
483
450
|
|
|
484
|
-
export { CodeEditor, type CodeEditorContextValue, CodeEditorInputTag, type CodeEditorInputTagProps, type CodeEditorPanelProps, type CodeEditorProps, type CodeEditorStatusBarProps, type CodeEditorToolbarProps, type FileKind, FileViewer, type FileViewerProps, type GutterDiffMark, type LanguageDefinition, MarkdownEditor, type MarkdownEditorMode, type MarkdownEditorProps, type ResolveFileKindInput, type
|
|
451
|
+
export { CodeEditor, type CodeEditorContextValue, CodeEditorInputTag, type CodeEditorInputTagProps, type CodeEditorPanelProps, type CodeEditorProps, type CodeEditorStatusBarProps, type CodeEditorToolbarProps, type FileKind, FileViewer, type FileViewerProps, type GutterDiffMark, type LanguageDefinition, MarkdownEditor, type MarkdownEditorMode, type MarkdownEditorProps, type ResolveFileKindInput, type ThemeDefinition, diffMarkColor, diffRemovedColor, getLanguage, getRegisteredLanguages, getRegisteredThemes, getTheme, gutterDiffMark, hasDeletedAtEnd, registerLanguage, registerTheme, renderMarkdown, resolveFileKind, tokenizeMarkdown, useCodeEditor, useCodeEditorInputTagAdapter };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createContext, useMemo, useState, useCallback, useRef, useEffect, useSyncExternalStore, useContext } from 'react';
|
|
2
2
|
import { cn, useControllableState, resolveMediaType, MediaViewer, textareaAdapter, InputTag } from '@particle-academy/react-fancy';
|
|
3
|
-
import { annotateLines, languageFromFilename } from '@particle-academy/fancy-file-commons';
|
|
3
|
+
import { annotateLines, highlightCode, tok, tokenizeHtml, LIGHT_COLORS, DARK_COLORS, languageFromFilename } from '@particle-academy/fancy-file-commons';
|
|
4
4
|
export { languageFromFilename } from '@particle-academy/fancy-file-commons';
|
|
5
5
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
6
6
|
|
|
@@ -445,89 +445,6 @@ var tokenizeJavaScript = (source) => {
|
|
|
445
445
|
return tokens;
|
|
446
446
|
};
|
|
447
447
|
|
|
448
|
-
// src/engine/tokenizers/html.ts
|
|
449
|
-
var tokenizeHtml = (source) => {
|
|
450
|
-
const tokens = [];
|
|
451
|
-
const len = source.length;
|
|
452
|
-
let i = 0;
|
|
453
|
-
while (i < len) {
|
|
454
|
-
if (source[i] === "<" && source.slice(i, i + 4) === "<!--") {
|
|
455
|
-
const pos2 = i;
|
|
456
|
-
i += 4;
|
|
457
|
-
while (i < len && source.slice(i, i + 3) !== "-->") i++;
|
|
458
|
-
i += 3;
|
|
459
|
-
tokens.push({ type: "comment", start: pos2, end: i });
|
|
460
|
-
continue;
|
|
461
|
-
}
|
|
462
|
-
if (source[i] === "<" && source.slice(i, i + 9).toUpperCase() === "<!DOCTYPE") {
|
|
463
|
-
const pos2 = i;
|
|
464
|
-
while (i < len && source[i] !== ">") i++;
|
|
465
|
-
i++;
|
|
466
|
-
tokens.push({ type: "keyword", start: pos2, end: i });
|
|
467
|
-
continue;
|
|
468
|
-
}
|
|
469
|
-
if (source[i] === "<") {
|
|
470
|
-
tokens.push({ type: "punctuation", start: i, end: i + 1 });
|
|
471
|
-
i++;
|
|
472
|
-
if (i < len && source[i] === "/") {
|
|
473
|
-
tokens.push({ type: "punctuation", start: i, end: i + 1 });
|
|
474
|
-
i++;
|
|
475
|
-
}
|
|
476
|
-
if (i < len && /[a-zA-Z]/.test(source[i])) {
|
|
477
|
-
const pos2 = i;
|
|
478
|
-
while (i < len && /[a-zA-Z0-9-]/.test(source[i])) i++;
|
|
479
|
-
tokens.push({ type: "tag", start: pos2, end: i });
|
|
480
|
-
}
|
|
481
|
-
while (i < len && source[i] !== ">" && !(source[i] === "/" && source[i + 1] === ">")) {
|
|
482
|
-
if (source[i] === " " || source[i] === " " || source[i] === "\n" || source[i] === "\r") {
|
|
483
|
-
i++;
|
|
484
|
-
continue;
|
|
485
|
-
}
|
|
486
|
-
if (/[a-zA-Z_@:]/.test(source[i])) {
|
|
487
|
-
const pos2 = i;
|
|
488
|
-
while (i < len && /[a-zA-Z0-9_\-:.]/.test(source[i])) i++;
|
|
489
|
-
tokens.push({ type: "attribute", start: pos2, end: i });
|
|
490
|
-
while (i < len && (source[i] === " " || source[i] === " ")) i++;
|
|
491
|
-
if (i < len && source[i] === "=") {
|
|
492
|
-
tokens.push({ type: "operator", start: i, end: i + 1 });
|
|
493
|
-
i++;
|
|
494
|
-
while (i < len && (source[i] === " " || source[i] === " ")) i++;
|
|
495
|
-
if (i < len && (source[i] === '"' || source[i] === "'")) {
|
|
496
|
-
const quote = source[i];
|
|
497
|
-
const pos3 = i;
|
|
498
|
-
i++;
|
|
499
|
-
while (i < len && source[i] !== quote) i++;
|
|
500
|
-
i++;
|
|
501
|
-
tokens.push({ type: "attributeValue", start: pos3, end: i });
|
|
502
|
-
} else if (i < len && /[^\s>]/.test(source[i])) {
|
|
503
|
-
const pos3 = i;
|
|
504
|
-
while (i < len && /[^\s>]/.test(source[i])) i++;
|
|
505
|
-
tokens.push({ type: "attributeValue", start: pos3, end: i });
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
continue;
|
|
509
|
-
}
|
|
510
|
-
i++;
|
|
511
|
-
}
|
|
512
|
-
if (i < len && source[i] === "/") {
|
|
513
|
-
tokens.push({ type: "punctuation", start: i, end: i + 1 });
|
|
514
|
-
i++;
|
|
515
|
-
}
|
|
516
|
-
if (i < len && source[i] === ">") {
|
|
517
|
-
tokens.push({ type: "punctuation", start: i, end: i + 1 });
|
|
518
|
-
i++;
|
|
519
|
-
}
|
|
520
|
-
continue;
|
|
521
|
-
}
|
|
522
|
-
const pos = i;
|
|
523
|
-
while (i < len && source[i] !== "<") i++;
|
|
524
|
-
if (i > pos) {
|
|
525
|
-
tokens.push({ type: "plain", start: pos, end: i });
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
return tokens;
|
|
529
|
-
};
|
|
530
|
-
|
|
531
448
|
// src/engine/tokenizers/php.ts
|
|
532
449
|
var PHP_KEYWORDS = /* @__PURE__ */ new Set([
|
|
533
450
|
"abstract",
|
|
@@ -1111,11 +1028,6 @@ var tokenizeGo = (source) => {
|
|
|
1111
1028
|
return tokens;
|
|
1112
1029
|
};
|
|
1113
1030
|
|
|
1114
|
-
// src/engine/tokenizer.ts
|
|
1115
|
-
function tok(type, s, e) {
|
|
1116
|
-
return { type, start: s, end: e };
|
|
1117
|
-
}
|
|
1118
|
-
|
|
1119
1031
|
// src/engine/tokenizers/markdown.ts
|
|
1120
1032
|
function tokenizeMarkdown(source) {
|
|
1121
1033
|
const tokens = [];
|
|
@@ -1320,112 +1232,17 @@ function getTheme(name) {
|
|
|
1320
1232
|
function getRegisteredThemes() {
|
|
1321
1233
|
return Array.from(themeRegistry.keys());
|
|
1322
1234
|
}
|
|
1323
|
-
|
|
1324
|
-
// src/themes/light.ts
|
|
1325
1235
|
registerTheme({
|
|
1326
1236
|
name: "light",
|
|
1327
1237
|
variant: "light",
|
|
1328
|
-
colors:
|
|
1329
|
-
background: "#ffffff",
|
|
1330
|
-
foreground: "#1e1e2e",
|
|
1331
|
-
gutterBackground: "#f8fafc",
|
|
1332
|
-
gutterForeground: "#94a3b8",
|
|
1333
|
-
gutterBorder: "#e2e8f0",
|
|
1334
|
-
activeLineBackground: "#f8fafc",
|
|
1335
|
-
selectionBackground: "#dbeafe",
|
|
1336
|
-
cursorColor: "#3b82f6",
|
|
1337
|
-
diffAdded: "#1a7f37",
|
|
1338
|
-
diffModified: "#0969da",
|
|
1339
|
-
diffRemoved: "#cf222e",
|
|
1340
|
-
keyword: "#8b5cf6",
|
|
1341
|
-
string: "#059669",
|
|
1342
|
-
comment: "#94a3b8",
|
|
1343
|
-
number: "#d97706",
|
|
1344
|
-
operator: "#0891b2",
|
|
1345
|
-
function: "#2563eb",
|
|
1346
|
-
type: "#d97706",
|
|
1347
|
-
tag: "#dc2626",
|
|
1348
|
-
attribute: "#d97706",
|
|
1349
|
-
attributeValue: "#059669",
|
|
1350
|
-
punctuation: "#64748b",
|
|
1351
|
-
variable: "#1e1e2e"
|
|
1352
|
-
}
|
|
1238
|
+
colors: LIGHT_COLORS
|
|
1353
1239
|
});
|
|
1354
|
-
|
|
1355
|
-
// src/themes/dark.ts
|
|
1356
1240
|
registerTheme({
|
|
1357
1241
|
name: "dark",
|
|
1358
1242
|
variant: "dark",
|
|
1359
|
-
colors:
|
|
1360
|
-
background: "#18181b",
|
|
1361
|
-
foreground: "#e4e4e7",
|
|
1362
|
-
gutterBackground: "#18181b",
|
|
1363
|
-
gutterForeground: "#52525b",
|
|
1364
|
-
gutterBorder: "#27272a",
|
|
1365
|
-
activeLineBackground: "#27272a",
|
|
1366
|
-
selectionBackground: "#1e3a5f",
|
|
1367
|
-
cursorColor: "#60a5fa",
|
|
1368
|
-
diffAdded: "#3fb950",
|
|
1369
|
-
diffModified: "#4184e4",
|
|
1370
|
-
diffRemoved: "#f85149",
|
|
1371
|
-
keyword: "#c084fc",
|
|
1372
|
-
string: "#34d399",
|
|
1373
|
-
comment: "#71717a",
|
|
1374
|
-
number: "#fbbf24",
|
|
1375
|
-
operator: "#22d3ee",
|
|
1376
|
-
function: "#60a5fa",
|
|
1377
|
-
type: "#fbbf24",
|
|
1378
|
-
tag: "#f87171",
|
|
1379
|
-
attribute: "#fbbf24",
|
|
1380
|
-
attributeValue: "#34d399",
|
|
1381
|
-
punctuation: "#a1a1aa",
|
|
1382
|
-
variable: "#e4e4e7"
|
|
1383
|
-
}
|
|
1243
|
+
colors: DARK_COLORS
|
|
1384
1244
|
});
|
|
1385
1245
|
|
|
1386
|
-
// src/engine/highlight.ts
|
|
1387
|
-
function escapeHtml(text) {
|
|
1388
|
-
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
1389
|
-
}
|
|
1390
|
-
var COLOR_RE = /^(#[0-9a-fA-F]{3,8}|(?:rgb|rgba|hsl|hsla)\([\d\s,.%/-]+\)|[a-zA-Z]+)$/;
|
|
1391
|
-
function safeColor(value) {
|
|
1392
|
-
return typeof value === "string" && COLOR_RE.test(value.trim()) ? value.trim() : "inherit";
|
|
1393
|
-
}
|
|
1394
|
-
function highlightCode(source, tokens, colors) {
|
|
1395
|
-
if (tokens.length === 0) return escapeHtml(source);
|
|
1396
|
-
const colorMap = {
|
|
1397
|
-
keyword: colors.keyword,
|
|
1398
|
-
string: colors.string,
|
|
1399
|
-
comment: colors.comment,
|
|
1400
|
-
number: colors.number,
|
|
1401
|
-
operator: colors.operator,
|
|
1402
|
-
function: colors.function,
|
|
1403
|
-
type: colors.type,
|
|
1404
|
-
tag: colors.tag,
|
|
1405
|
-
attribute: colors.attribute,
|
|
1406
|
-
attributeValue: colors.attributeValue,
|
|
1407
|
-
punctuation: colors.punctuation,
|
|
1408
|
-
variable: colors.variable,
|
|
1409
|
-
plain: colors.foreground
|
|
1410
|
-
};
|
|
1411
|
-
const parts = [];
|
|
1412
|
-
let pos = 0;
|
|
1413
|
-
for (const token of tokens) {
|
|
1414
|
-
if (token.start > pos) {
|
|
1415
|
-
parts.push(escapeHtml(source.slice(pos, token.start)));
|
|
1416
|
-
}
|
|
1417
|
-
const text = escapeHtml(source.slice(token.start, token.end));
|
|
1418
|
-
const color = safeColor(colorMap[token.type]);
|
|
1419
|
-
const style = token.type === "comment" ? `color:${color};font-style:italic` : `color:${color}`;
|
|
1420
|
-
parts.push(`<span style="${style}">${text}</span>`);
|
|
1421
|
-
pos = token.end;
|
|
1422
|
-
}
|
|
1423
|
-
if (pos < source.length) {
|
|
1424
|
-
parts.push(escapeHtml(source.slice(pos)));
|
|
1425
|
-
}
|
|
1426
|
-
return parts.join("");
|
|
1427
|
-
}
|
|
1428
|
-
|
|
1429
1246
|
// src/engine/position.ts
|
|
1430
1247
|
function lineColumnToOffset(text, line, column = 1) {
|
|
1431
1248
|
const lines = text.split("\n");
|
|
@@ -1818,7 +1635,7 @@ var CodeEditor = Object.assign(CodeEditorRoot, {
|
|
|
1818
1635
|
});
|
|
1819
1636
|
|
|
1820
1637
|
// src/engine/markdown-render.ts
|
|
1821
|
-
function
|
|
1638
|
+
function escapeHtml(s) {
|
|
1822
1639
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
1823
1640
|
}
|
|
1824
1641
|
function escapeAttr(s) {
|
|
@@ -1859,10 +1676,10 @@ function renderMarkdown(markdown) {
|
|
|
1859
1676
|
i++;
|
|
1860
1677
|
}
|
|
1861
1678
|
i++;
|
|
1862
|
-
out.push(`<pre><code${lang ? ` class="language-${escapeAttr(
|
|
1679
|
+
out.push(`<pre><code${lang ? ` class="language-${escapeAttr(escapeHtml(lang))}"` : ""}>${escapeHtml(body.join("\n"))}</code></pre>`);
|
|
1863
1680
|
continue;
|
|
1864
1681
|
}
|
|
1865
|
-
const esc =
|
|
1682
|
+
const esc = escapeHtml(line);
|
|
1866
1683
|
if (/^\s*$/.test(line)) {
|
|
1867
1684
|
flushPara();
|
|
1868
1685
|
closeList();
|