mdsquare 0.0.0-stage → 0.2.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 +218 -2
- package/dist/callout.d.ts +17 -0
- package/dist/callout.js +541 -0
- package/dist/calloutHeader.d.ts +47 -0
- package/dist/calloutHeader.js +75 -0
- package/dist/codeBlock.d.ts +78 -0
- package/dist/codeBlock.js +686 -0
- package/dist/codeTheme.d.ts +47 -0
- package/dist/codeTheme.js +394 -0
- package/dist/delimiter.d.ts +20 -0
- package/dist/delimiter.js +73 -0
- package/dist/editor.d.ts +132 -0
- package/dist/editor.js +225 -0
- package/dist/emphasis.d.ts +6 -0
- package/dist/emphasis.js +101 -0
- package/dist/escape.d.ts +4 -0
- package/dist/escape.js +39 -0
- package/dist/extensions.d.ts +74 -0
- package/dist/extensions.js +81 -0
- package/dist/footnote.d.ts +24 -0
- package/dist/footnote.js +456 -0
- package/dist/footnoteSyntax.d.ts +23 -0
- package/dist/footnoteSyntax.js +107 -0
- package/dist/hashtag.d.ts +4 -0
- package/dist/hashtag.js +64 -0
- package/dist/hashtagSyntax.d.ts +36 -0
- package/dist/hashtagSyntax.js +99 -0
- package/dist/heading.d.ts +7 -0
- package/dist/heading.js +159 -0
- package/dist/highlight.d.ts +5 -0
- package/dist/highlight.js +6 -0
- package/dist/horizontalRule.d.ts +21 -0
- package/dist/horizontalRule.js +142 -0
- package/dist/image.d.ts +58 -0
- package/dist/image.js +344 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +16 -0
- package/dist/inlineCode.d.ts +4 -0
- package/dist/inlineCode.js +68 -0
- package/dist/link.d.ts +47 -0
- package/dist/link.js +217 -0
- package/dist/list.d.ts +14 -0
- package/dist/list.js +136 -0
- package/dist/listEnter.d.ts +20 -0
- package/dist/listEnter.js +72 -0
- package/dist/listIndent.d.ts +23 -0
- package/dist/listIndent.js +335 -0
- package/dist/markVision.d.ts +17 -0
- package/dist/markVision.js +56 -0
- package/dist/math.d.ts +45 -0
- package/dist/math.js +233 -0
- package/dist/mathSyntax.d.ts +24 -0
- package/dist/mathSyntax.js +179 -0
- package/dist/mention.d.ts +4 -0
- package/dist/mention.js +58 -0
- package/dist/mentionSyntax.d.ts +14 -0
- package/dist/mentionSyntax.js +71 -0
- package/dist/quote.d.ts +9 -0
- package/dist/quote.js +122 -0
- package/dist/setup.d.ts +13 -0
- package/dist/setup.js +40 -0
- package/dist/style.css +6 -0
- package/dist/style.css.d.ts +2 -0
- package/dist/table.d.ts +38 -0
- package/dist/table.js +960 -0
- package/dist/tableEdit.d.ts +30 -0
- package/dist/tableEdit.js +305 -0
- package/dist/tableMenu.d.ts +65 -0
- package/dist/tableMenu.js +1125 -0
- package/dist/tableModel.d.ts +168 -0
- package/dist/tableModel.js +433 -0
- package/dist/tableState.d.ts +36 -0
- package/dist/tableState.js +96 -0
- package/dist/task.d.ts +13 -0
- package/dist/task.js +179 -0
- package/dist/textMate.d.ts +49 -0
- package/dist/textMate.js +284 -0
- package/dist/tikz.d.ts +56 -0
- package/dist/tikz.js +343 -0
- package/dist/underline.d.ts +5 -0
- package/dist/underline.js +6 -0
- package/dist/utils/blockMargin.d.ts +6 -0
- package/dist/utils/blockMargin.js +6 -0
- package/dist/utils/codePoint.d.ts +13 -0
- package/dist/utils/codePoint.js +43 -0
- package/dist/utils/container.d.ts +10 -0
- package/dist/utils/container.js +10 -0
- package/dist/utils/reveal.d.ts +99 -0
- package/dist/utils/reveal.js +161 -0
- package/dist/utils/selection.d.ts +33 -0
- package/dist/utils/selection.js +45 -0
- package/dist/utils/syntaxTree.d.ts +18 -0
- package/dist/utils/syntaxTree.js +23 -0
- package/package.json +79 -4
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { syntaxTree } from "@codemirror/language";
|
|
2
|
+
import { EditorState, StateField, } from "@codemirror/state";
|
|
3
|
+
import { Decoration, EditorView, ViewPlugin, } from "@codemirror/view";
|
|
4
|
+
import { isSelectionOverlapNode } from "./selection.js";
|
|
5
|
+
import { iterateVisibleSyntaxTree } from "./syntaxTree.js";
|
|
6
|
+
/** 선택 범위(멀티 커서 포함) 중 하나라도 노드에 닿아 있으면 true */
|
|
7
|
+
export function isRevealed(selection, node) {
|
|
8
|
+
return selection.ranges.some((range) => isSelectionOverlapNode(range, node));
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* 데코레이션을 처음부터 다시 만들어야 하는지 여부
|
|
12
|
+
* - 백그라운드 파싱이 끝나면 문서/뷰포트/선택 변화 없이 트리만 바뀌므로 트리도 비교합니다.
|
|
13
|
+
* - 설정이 바뀌면(확장 추가/제거, Facet 값 변경) 다른 플러그인과의 역할 분담이 달라질 수 있습니다.
|
|
14
|
+
*/
|
|
15
|
+
export function needsRebuild(update) {
|
|
16
|
+
return (update.docChanged ||
|
|
17
|
+
update.viewportChanged ||
|
|
18
|
+
syntaxTree(update.startState) !== syntaxTree(update.state) ||
|
|
19
|
+
update.transactions.some((tr) => tr.reconfigured));
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* 빌드 시 각 노드의 "기호 표시 여부"를 기록해 두었다가,
|
|
23
|
+
* 선택만 바뀌었을 때 표시 여부가 달라진 노드가 있는지 빠르게 확인합니다.
|
|
24
|
+
*/
|
|
25
|
+
export class RevealTracker {
|
|
26
|
+
ranges = [];
|
|
27
|
+
flags = [];
|
|
28
|
+
/** 새 빌드를 시작할 때 호출합니다. */
|
|
29
|
+
reset() {
|
|
30
|
+
this.ranges = [];
|
|
31
|
+
this.flags = [];
|
|
32
|
+
}
|
|
33
|
+
/** 노드의 표시 여부를 계산하고 기록합니다. */
|
|
34
|
+
track(selection, from, to) {
|
|
35
|
+
const revealed = isRevealed(selection, { from, to });
|
|
36
|
+
this.ranges.push(from, to);
|
|
37
|
+
this.flags.push(revealed);
|
|
38
|
+
return revealed;
|
|
39
|
+
}
|
|
40
|
+
/** 주어진 선택에서 표시 여부가 달라지는 노드가 하나라도 있으면 true */
|
|
41
|
+
changed(selection) {
|
|
42
|
+
const { ranges, flags } = this;
|
|
43
|
+
for (let i = 0; i < flags.length; i++) {
|
|
44
|
+
const node = { from: ranges[i * 2], to: ranges[i * 2 + 1] };
|
|
45
|
+
if (isRevealed(selection, node) !== flags[i])
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/** createRevealPlugin()이 만드는 플러그인 인스턴스 */
|
|
52
|
+
export class RevealPluginValue {
|
|
53
|
+
decorations = Decoration.none;
|
|
54
|
+
tracker = new RevealTracker();
|
|
55
|
+
spec;
|
|
56
|
+
constructor(view, spec) {
|
|
57
|
+
this.spec = spec;
|
|
58
|
+
this.build(view);
|
|
59
|
+
}
|
|
60
|
+
update(update) {
|
|
61
|
+
if (needsRebuild(update) ||
|
|
62
|
+
this.spec.rebuildOn?.(update) ||
|
|
63
|
+
// 선택만 바뀐 경우: 표시 여부가 달라진 노드가 있을 때만 다시 빌드합니다.
|
|
64
|
+
(update.selectionSet && this.tracker.changed(update.state.selection))) {
|
|
65
|
+
this.build(update.view);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
build(view) {
|
|
69
|
+
const { state } = view;
|
|
70
|
+
const { selection } = state;
|
|
71
|
+
const tracker = this.tracker;
|
|
72
|
+
const decorations = [];
|
|
73
|
+
tracker.reset();
|
|
74
|
+
iterateVisibleSyntaxTree(view, this.spec.visit({
|
|
75
|
+
state,
|
|
76
|
+
view,
|
|
77
|
+
decorations,
|
|
78
|
+
isRevealed: (from, to) => tracker.track(selection, from, to),
|
|
79
|
+
}));
|
|
80
|
+
this.decorations = Decoration.set(decorations, this.spec.sort ?? false);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* "커서가 닿은 노드만 기호를 보여주는" 플러그인의 공용 골격을 만듭니다.
|
|
85
|
+
*
|
|
86
|
+
* 공통으로 처리하는 것:
|
|
87
|
+
* - 보이는 범위의 구문 트리만 순회 (접힌 영역 중복 방문 없음)
|
|
88
|
+
* - 문서/뷰포트/구문 트리 변경 시 재빌드
|
|
89
|
+
* - 선택만 바뀐 경우 표시 여부가 달라진 노드가 있을 때만 재빌드
|
|
90
|
+
* - 멀티 커서 지원
|
|
91
|
+
*/
|
|
92
|
+
export function createRevealPlugin(spec) {
|
|
93
|
+
return ViewPlugin.define((view) => new RevealPluginValue(view, spec), {
|
|
94
|
+
decorations: (plugin) => plugin.decorations,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* "커서가 닿은 블록만 원문을 보여주는" StateField를 만듭니다.
|
|
99
|
+
* - 문서/구문 트리/설정이 바뀐 경우에만 scan으로 대상을 다시 찾습니다.
|
|
100
|
+
* - 선택만 바뀐 경우 표시 여부가 달라진 대상이 있을 때만 build를 다시 호출합니다.
|
|
101
|
+
* - 멀티 커서 지원
|
|
102
|
+
*/
|
|
103
|
+
/**
|
|
104
|
+
* 위/아래 화살표가 숨겨진 블록 위젯을 통째로 건너뛰었으면(바로 윗줄 → 바로 아랫줄) 커서를 그 블록으로 옮깁니다.
|
|
105
|
+
* 아래로 가면 블록 시작, 위로 가면 블록 끝. 키보드 이동(select)의 빈 커서 하나일 때만 고칩니다.
|
|
106
|
+
*/
|
|
107
|
+
function enterSkippedBlock(tr, value, isBlock) {
|
|
108
|
+
if (!value || !tr.selection || tr.docChanged || !tr.isUserEvent("select") || tr.isUserEvent("select.pointer")) {
|
|
109
|
+
return tr;
|
|
110
|
+
}
|
|
111
|
+
const before = tr.startState.selection;
|
|
112
|
+
const after = tr.selection;
|
|
113
|
+
if (before.ranges.length !== 1 || after.ranges.length !== 1 || !before.main.empty || !after.main.empty)
|
|
114
|
+
return tr;
|
|
115
|
+
const { doc } = tr.startState;
|
|
116
|
+
const fromLine = doc.lineAt(before.main.head).number;
|
|
117
|
+
const toLine = doc.lineAt(after.main.head).number;
|
|
118
|
+
if (Math.abs(toLine - fromLine) < 2)
|
|
119
|
+
return tr;
|
|
120
|
+
const down = toLine > fromLine;
|
|
121
|
+
for (let i = 0; i < value.items.length; i++) {
|
|
122
|
+
const item = value.items[i];
|
|
123
|
+
if (value.revealed[i] || !isBlock(item))
|
|
124
|
+
continue;
|
|
125
|
+
const first = doc.lineAt(item.from).number;
|
|
126
|
+
const last = doc.lineAt(item.to).number;
|
|
127
|
+
if (down ? fromLine === first - 1 && toLine === last + 1 : fromLine === last + 1 && toLine === first - 1) {
|
|
128
|
+
return [tr, { selection: { anchor: down ? item.from : item.to }, scrollIntoView: true, sequential: true }];
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return tr;
|
|
132
|
+
}
|
|
133
|
+
export function createRevealField(spec) {
|
|
134
|
+
const flags = (items, selection) => items.map((item) => isRevealed(selection, item));
|
|
135
|
+
const create = (state) => {
|
|
136
|
+
const items = spec.scan(state);
|
|
137
|
+
const revealed = flags(items, state.selection);
|
|
138
|
+
return { items, revealed, decorations: spec.build(items, revealed, state) };
|
|
139
|
+
};
|
|
140
|
+
return StateField.define({
|
|
141
|
+
create,
|
|
142
|
+
update(value, tr) {
|
|
143
|
+
if (tr.docChanged || tr.reconfigured || syntaxTree(tr.startState) !== syntaxTree(tr.state)) {
|
|
144
|
+
return create(tr.state);
|
|
145
|
+
}
|
|
146
|
+
if (tr.selection) {
|
|
147
|
+
const revealed = flags(value.items, tr.state.selection);
|
|
148
|
+
if (revealed.every((flag, i) => flag === value.revealed[i]))
|
|
149
|
+
return value;
|
|
150
|
+
return { ...value, revealed, decorations: spec.build(value.items, revealed, tr.state) };
|
|
151
|
+
}
|
|
152
|
+
return value;
|
|
153
|
+
},
|
|
154
|
+
provide: (field) => [
|
|
155
|
+
EditorView.decorations.from(field, (value) => value.decorations),
|
|
156
|
+
spec.block
|
|
157
|
+
? EditorState.transactionFilter.of((tr) => enterSkippedBlock(tr, tr.startState.field(field, false), spec.block))
|
|
158
|
+
: [],
|
|
159
|
+
],
|
|
160
|
+
});
|
|
161
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { SelectionRange } from "@codemirror/state";
|
|
2
|
+
import type { SyntaxNodeRef } from "@lezer/common";
|
|
3
|
+
/** from/to만 필요하므로 SyntaxNodeRef, SyntaxNode 등 어떤 노드든 받을 수 있게 합니다. */
|
|
4
|
+
type NodeRange = Pick<SyntaxNodeRef, "from" | "to">;
|
|
5
|
+
/**
|
|
6
|
+
* Selection이 특정 범위 [from, to] 안에 완전히 포함되는지 여부
|
|
7
|
+
* @param selection SelectionRange
|
|
8
|
+
* @param from 시작 위치
|
|
9
|
+
* @param to 끝 위치
|
|
10
|
+
*/
|
|
11
|
+
export declare function isSelectionBetween(selection: SelectionRange, from: number, to: number): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Node가 Selection 안에 완전히 포함되는지 여부
|
|
14
|
+
* @param selection SelectionRange
|
|
15
|
+
* @param node SyntaxNodeRef
|
|
16
|
+
*/
|
|
17
|
+
export declare function isNodeWithinSelection(selection: SelectionRange, node: NodeRange): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Selection이 Node의 경계 중 정확히 하나를 가로지르는지(일부만 걸치는지) 여부
|
|
20
|
+
* - Selection이 Node를 완전히 포함하거나, Node 안에 완전히 포함되면 false입니다.
|
|
21
|
+
* - 빈 Selection(커서)은 경계를 가로지를 수 없으므로 항상 false입니다.
|
|
22
|
+
* @param selection SelectionRange
|
|
23
|
+
* @param node SyntaxNodeRef
|
|
24
|
+
*/
|
|
25
|
+
export declare function isSelectionPartiallyOverlapNode(selection: SelectionRange, node: NodeRange): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Selection과 Node가 겹치거나 맞닿아 있는지 여부
|
|
28
|
+
* (포함, 피포함, 일부 걸침, 경계에서 맞닿음을 모두 포함)
|
|
29
|
+
* @param selection SelectionRange
|
|
30
|
+
* @param node SyntaxNodeRef
|
|
31
|
+
*/
|
|
32
|
+
export declare function isSelectionOverlapNode(selection: SelectionRange, node: NodeRange): boolean;
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* 모든 판정은 닫힌 구간 [from, to] 기준입니다.
|
|
3
|
+
* 즉 커서가 노드 바로 앞/뒤(node.from, node.to)에 있어도 "닿아 있음"으로 봅니다.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Selection이 특정 범위 [from, to] 안에 완전히 포함되는지 여부
|
|
7
|
+
* @param selection SelectionRange
|
|
8
|
+
* @param from 시작 위치
|
|
9
|
+
* @param to 끝 위치
|
|
10
|
+
*/
|
|
11
|
+
export function isSelectionBetween(selection, from, to) {
|
|
12
|
+
return selection.from >= from && selection.to <= to;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Node가 Selection 안에 완전히 포함되는지 여부
|
|
16
|
+
* @param selection SelectionRange
|
|
17
|
+
* @param node SyntaxNodeRef
|
|
18
|
+
*/
|
|
19
|
+
export function isNodeWithinSelection(selection, node) {
|
|
20
|
+
return selection.from <= node.from && selection.to >= node.to;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Selection이 Node의 경계 중 정확히 하나를 가로지르는지(일부만 걸치는지) 여부
|
|
24
|
+
* - Selection이 Node를 완전히 포함하거나, Node 안에 완전히 포함되면 false입니다.
|
|
25
|
+
* - 빈 Selection(커서)은 경계를 가로지를 수 없으므로 항상 false입니다.
|
|
26
|
+
* @param selection SelectionRange
|
|
27
|
+
* @param node SyntaxNodeRef
|
|
28
|
+
*/
|
|
29
|
+
export function isSelectionPartiallyOverlapNode(selection, node) {
|
|
30
|
+
const { from, to } = selection;
|
|
31
|
+
return (
|
|
32
|
+
// 앞쪽 경계를 가로지름: [sel ... (node.from) ... sel] ... node.to
|
|
33
|
+
(from < node.from && to > node.from && to < node.to) ||
|
|
34
|
+
// 뒤쪽 경계를 가로지름: node.from ... [sel ... (node.to) ... sel]
|
|
35
|
+
(from > node.from && from < node.to && to > node.to));
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Selection과 Node가 겹치거나 맞닿아 있는지 여부
|
|
39
|
+
* (포함, 피포함, 일부 걸침, 경계에서 맞닿음을 모두 포함)
|
|
40
|
+
* @param selection SelectionRange
|
|
41
|
+
* @param node SyntaxNodeRef
|
|
42
|
+
*/
|
|
43
|
+
export function isSelectionOverlapNode(selection, node) {
|
|
44
|
+
return selection.from <= node.to && selection.to >= node.from;
|
|
45
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { EditorView } from "@codemirror/view";
|
|
2
|
+
import type { SyntaxNodeRef } from "@lezer/common";
|
|
3
|
+
export interface SyntaxTreeIterator {
|
|
4
|
+
/** false를 반환하면 해당 노드의 자식은 순회하지 않습니다(leave도 호출되지 않음). */
|
|
5
|
+
enter(node: SyntaxNodeRef): boolean | void;
|
|
6
|
+
leave?(node: SyntaxNodeRef): void;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* 화면에 보이는 범위(view.visibleRanges)에 걸친 노드만 순회합니다.
|
|
10
|
+
*
|
|
11
|
+
* visibleRanges는 접힌 영역(20자 이상) 등을 기준으로 여러 구간으로 나뉠 수 있습니다.
|
|
12
|
+
* 구간마다 따로 iterate하면 여러 구간에 걸친 노드(Document, ListItem 등)가
|
|
13
|
+
* 중복 방문되고 leave가 중간에 호출되므로, 전체 구간을 한 번만 순회하면서
|
|
14
|
+
* 보이는 구간과 겹치지 않는 노드(와 그 자식)를 건너뜁니다.
|
|
15
|
+
*
|
|
16
|
+
* 범위 판정은 Lezer의 iterate와 동일하게 경계에 닿는 노드도 포함합니다.
|
|
17
|
+
*/
|
|
18
|
+
export declare function iterateVisibleSyntaxTree(view: EditorView, { enter, leave }: SyntaxTreeIterator): void;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { syntaxTree } from "@codemirror/language";
|
|
2
|
+
/**
|
|
3
|
+
* 화면에 보이는 범위(view.visibleRanges)에 걸친 노드만 순회합니다.
|
|
4
|
+
*
|
|
5
|
+
* visibleRanges는 접힌 영역(20자 이상) 등을 기준으로 여러 구간으로 나뉠 수 있습니다.
|
|
6
|
+
* 구간마다 따로 iterate하면 여러 구간에 걸친 노드(Document, ListItem 등)가
|
|
7
|
+
* 중복 방문되고 leave가 중간에 호출되므로, 전체 구간을 한 번만 순회하면서
|
|
8
|
+
* 보이는 구간과 겹치지 않는 노드(와 그 자식)를 건너뜁니다.
|
|
9
|
+
*
|
|
10
|
+
* 범위 판정은 Lezer의 iterate와 동일하게 경계에 닿는 노드도 포함합니다.
|
|
11
|
+
*/
|
|
12
|
+
export function iterateVisibleSyntaxTree(view, { enter, leave }) {
|
|
13
|
+
const ranges = view.visibleRanges;
|
|
14
|
+
if (ranges.length === 0)
|
|
15
|
+
return;
|
|
16
|
+
const isVisible = (node) => ranges.some((range) => node.from <= range.to && node.to >= range.from);
|
|
17
|
+
syntaxTree(view.state).iterate({
|
|
18
|
+
from: ranges[0].from,
|
|
19
|
+
to: ranges[ranges.length - 1].to,
|
|
20
|
+
enter: (node) => (isVisible(node) ? enter(node) : false),
|
|
21
|
+
leave,
|
|
22
|
+
});
|
|
23
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,81 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mdsquare",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Hybrid (live preview) Markdown editor built on CodeMirror 6: tables, callouts, math, code blocks, footnotes and more",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"markdown",
|
|
7
|
+
"editor",
|
|
8
|
+
"markdown-editor",
|
|
9
|
+
"live-preview",
|
|
10
|
+
"wysiwyg",
|
|
11
|
+
"codemirror",
|
|
12
|
+
"codemirror6",
|
|
13
|
+
"lezer",
|
|
14
|
+
"gfm",
|
|
15
|
+
"table",
|
|
16
|
+
"katex"
|
|
17
|
+
],
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"author": "ordidxzero <ordidxzero@gmail.com>",
|
|
20
|
+
"type": "module",
|
|
21
|
+
"sideEffects": [
|
|
22
|
+
"*.css"
|
|
23
|
+
],
|
|
24
|
+
"main": "./dist/index.js",
|
|
25
|
+
"module": "./dist/index.js",
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"import": "./dist/index.js"
|
|
31
|
+
},
|
|
32
|
+
"./extensions": {
|
|
33
|
+
"types": "./dist/extensions.d.ts",
|
|
34
|
+
"import": "./dist/extensions.js"
|
|
35
|
+
},
|
|
36
|
+
"./style.css": {
|
|
37
|
+
"types": "./dist/style.css.d.ts",
|
|
38
|
+
"default": "./dist/style.css"
|
|
39
|
+
},
|
|
40
|
+
"./package.json": "./package.json"
|
|
41
|
+
},
|
|
42
|
+
"files": [
|
|
43
|
+
"dist",
|
|
44
|
+
"README.md"
|
|
45
|
+
],
|
|
46
|
+
"scripts": {
|
|
47
|
+
"dev": "vite",
|
|
48
|
+
"build": "rm -rf dist && tsc -p tsconfig.build.json && node scripts/finish-build.mjs",
|
|
49
|
+
"typecheck": "tsc --noEmit",
|
|
50
|
+
"test": "vitest run",
|
|
51
|
+
"test:watch": "vitest",
|
|
52
|
+
"preview": "vite build && vite preview",
|
|
53
|
+
"bench": "node bench/highlight.ts",
|
|
54
|
+
"prepublishOnly": "npm run typecheck && npm test && npm run build"
|
|
55
|
+
},
|
|
56
|
+
"dependencies": {
|
|
57
|
+
"@codemirror/autocomplete": "^6.20.4",
|
|
58
|
+
"@codemirror/commands": "^6.11.1",
|
|
59
|
+
"@codemirror/lang-markdown": "^6.5.2",
|
|
60
|
+
"@codemirror/language": "^6.13.1",
|
|
61
|
+
"@codemirror/language-data": "^6.5.2",
|
|
62
|
+
"@codemirror/search": "^6.7.2",
|
|
63
|
+
"@codemirror/state": "^6.7.6",
|
|
64
|
+
"@codemirror/view": "^6.43.15",
|
|
65
|
+
"@lezer/common": "^1.5.5",
|
|
66
|
+
"@lezer/highlight": "^1.2.5",
|
|
67
|
+
"@lezer/markdown": "^1.8.1",
|
|
68
|
+
"katex": "^0.19.1"
|
|
69
|
+
},
|
|
70
|
+
"devDependencies": {
|
|
71
|
+
"@codemirror/lang-javascript": "^6.2.5",
|
|
72
|
+
"@codemirror/lang-json": "^6.0.2",
|
|
73
|
+
"@codemirror/lang-python": "^6.2.1",
|
|
74
|
+
"@drgrice1/tikzjax": "1.0.0-beta24",
|
|
75
|
+
"@types/node": "^26.6.6",
|
|
76
|
+
"jsdom": "^31.0.0",
|
|
77
|
+
"typescript": "^7.0.2",
|
|
78
|
+
"vite": "^8.3.6",
|
|
79
|
+
"vitest": "^5.1.0"
|
|
80
|
+
}
|
|
81
|
+
}
|