@shadow-garden/bapbong-model 0.12.0 → 0.14.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 +322 -0
- package/dist/index.js +322 -0
- package/dist/lib/model.d.ts +2 -2
- package/dist/lib/model.d.ts.map +1 -1
- package/package.json +3 -2
package/dist/index.cjs
CHANGED
|
@@ -71,6 +71,262 @@ function fieldAt(doc, pos) {
|
|
|
71
71
|
|
|
72
72
|
// packages/model/src/lib/model.ts
|
|
73
73
|
var import_prosemirror_model = require("prosemirror-model");
|
|
74
|
+
|
|
75
|
+
// packages/contracts/dist/index.js
|
|
76
|
+
var FIELD_SET = {
|
|
77
|
+
family: true,
|
|
78
|
+
sizePt: true,
|
|
79
|
+
bold: true,
|
|
80
|
+
italic: true,
|
|
81
|
+
letterSpacing: true,
|
|
82
|
+
scaleX: true,
|
|
83
|
+
kerning: true
|
|
84
|
+
};
|
|
85
|
+
var FIELDS = Object.keys(FIELD_SET);
|
|
86
|
+
var SUB_DIGIT = "\u2080\u2081\u2082\u2083\u2084\u2085\u2086\u2087\u2088\u2089";
|
|
87
|
+
var SUP_DIGIT = "\u2070\xB9\xB2\xB3\u2074\u2075\u2076\u2077\u2078\u2079";
|
|
88
|
+
var digitsVia = (s, alphabet) => /^[0-9]+$/.test(s) ? [...s].map((d) => alphabet[Number(d)]).join("") : null;
|
|
89
|
+
function astToLinear(row) {
|
|
90
|
+
const count = (s) => [...s].length;
|
|
91
|
+
const paren = (s) => count(s) <= 1 || s.startsWith("(") && s.endsWith(")") ? s : `(${s})`;
|
|
92
|
+
const sub = (s) => digitsVia(s, SUB_DIGIT) ?? (count(s) > 1 ? `_(${s})` : `_${s}`);
|
|
93
|
+
const sup = (s) => digitsVia(s, SUP_DIGIT) ?? (count(s) > 1 ? `^(${s})` : `^${s}`);
|
|
94
|
+
const one = (n) => {
|
|
95
|
+
switch (n.t) {
|
|
96
|
+
case "chr":
|
|
97
|
+
return n.ch;
|
|
98
|
+
case "frac":
|
|
99
|
+
return `${paren(astToLinear(n.num))}/${paren(astToLinear(n.den))}`;
|
|
100
|
+
case "rad": {
|
|
101
|
+
const deg = astToLinear(n.deg);
|
|
102
|
+
return `${deg ? sup(deg) : ""}\u221A(${astToLinear(n.body)})`;
|
|
103
|
+
}
|
|
104
|
+
case "scr": {
|
|
105
|
+
const lo = astToLinear(n.sub);
|
|
106
|
+
const hi = astToLinear(n.sup);
|
|
107
|
+
return astToLinear(n.base) + (lo ? sub(lo) : "") + (hi ? sup(hi) : "");
|
|
108
|
+
}
|
|
109
|
+
case "fence":
|
|
110
|
+
return n.l + astToLinear(n.body) + n.r;
|
|
111
|
+
case "big": {
|
|
112
|
+
const lo = astToLinear(n.lo);
|
|
113
|
+
const hi = astToLinear(n.hi);
|
|
114
|
+
return n.op + (lo ? sub(lo) : "") + (hi ? sup(hi) : "") + paren(astToLinear(n.body));
|
|
115
|
+
}
|
|
116
|
+
case "func":
|
|
117
|
+
return `${astToLinear(n.name)}\u2061${paren(astToLinear(n.body))}`;
|
|
118
|
+
case "acc":
|
|
119
|
+
return astToLinear(n.body) + n.chr;
|
|
120
|
+
case "lim": {
|
|
121
|
+
const l = astToLinear(n.lim);
|
|
122
|
+
return astToLinear(n.base) + (l ? n.below ? sub(l) : sup(l) : "");
|
|
123
|
+
}
|
|
124
|
+
case "mat": {
|
|
125
|
+
const lines = [];
|
|
126
|
+
for (let i = 0; i < n.cells.length; i += n.cols)
|
|
127
|
+
lines.push(
|
|
128
|
+
n.cells.slice(i, i + n.cols).map((c) => astToLinear(c)).join("&")
|
|
129
|
+
);
|
|
130
|
+
return `(${lines.join("@")})`;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
return row.map(one).join("");
|
|
135
|
+
}
|
|
136
|
+
function isEqRow(v) {
|
|
137
|
+
if (!Array.isArray(v)) return false;
|
|
138
|
+
return v.every((n) => {
|
|
139
|
+
if (typeof n !== "object" || n === null) return false;
|
|
140
|
+
const t = n.t;
|
|
141
|
+
if (t === "chr") return typeof n.ch === "string";
|
|
142
|
+
if (t === "frac")
|
|
143
|
+
return isEqRow(n.num) && isEqRow(n.den);
|
|
144
|
+
if (t === "rad")
|
|
145
|
+
return isEqRow(n.deg) && isEqRow(n.body);
|
|
146
|
+
if (t === "scr")
|
|
147
|
+
return isEqRow(n.base) && isEqRow(n.sub) && isEqRow(n.sup);
|
|
148
|
+
if (t === "fence")
|
|
149
|
+
return typeof n.l === "string" && typeof n.r === "string" && isEqRow(n.body);
|
|
150
|
+
if (t === "big")
|
|
151
|
+
return typeof n.op === "string" && isEqRow(n.lo) && isEqRow(n.hi) && isEqRow(n.body);
|
|
152
|
+
if (t === "func")
|
|
153
|
+
return isEqRow(n.name) && isEqRow(n.body);
|
|
154
|
+
if (t === "acc")
|
|
155
|
+
return typeof n.chr === "string" && isEqRow(n.body);
|
|
156
|
+
if (t === "lim")
|
|
157
|
+
return typeof n.below === "boolean" && isEqRow(n.base) && isEqRow(n.lim);
|
|
158
|
+
if (t === "mat") {
|
|
159
|
+
const m = n;
|
|
160
|
+
return typeof m.cols === "number" && m.cols > 0 && Array.isArray(m.cells) && m.cells.every((c) => isEqRow(c));
|
|
161
|
+
}
|
|
162
|
+
return false;
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
var frac = () => ({ t: "frac", num: [], den: [] });
|
|
166
|
+
var scr = (slots) => ({
|
|
167
|
+
t: "scr",
|
|
168
|
+
base: [],
|
|
169
|
+
sub: [],
|
|
170
|
+
sup: [],
|
|
171
|
+
slots
|
|
172
|
+
});
|
|
173
|
+
var rad = (showDeg) => ({
|
|
174
|
+
t: "rad",
|
|
175
|
+
deg: [],
|
|
176
|
+
body: [],
|
|
177
|
+
showDeg
|
|
178
|
+
});
|
|
179
|
+
var fence = (l, r) => ({
|
|
180
|
+
t: "fence",
|
|
181
|
+
l,
|
|
182
|
+
r,
|
|
183
|
+
body: []
|
|
184
|
+
});
|
|
185
|
+
var upright = (s) => [...s].map((ch) => ({ t: "chr", ch }));
|
|
186
|
+
var func = (name) => ({
|
|
187
|
+
t: "func",
|
|
188
|
+
name: upright(name),
|
|
189
|
+
body: []
|
|
190
|
+
});
|
|
191
|
+
var acc = (chr) => ({ t: "acc", chr, body: [] });
|
|
192
|
+
var mat = (rows, cols) => ({
|
|
193
|
+
t: "mat",
|
|
194
|
+
cols,
|
|
195
|
+
cells: Array.from({ length: rows * cols }, () => [])
|
|
196
|
+
});
|
|
197
|
+
var braced = (l, r, rows, cols) => ({
|
|
198
|
+
t: "fence",
|
|
199
|
+
l,
|
|
200
|
+
r,
|
|
201
|
+
body: [mat(rows, cols)]
|
|
202
|
+
});
|
|
203
|
+
var lim = (name, below = true) => ({
|
|
204
|
+
t: "lim",
|
|
205
|
+
base: upright(name),
|
|
206
|
+
lim: [],
|
|
207
|
+
below
|
|
208
|
+
});
|
|
209
|
+
var big = (op, limits = false) => ({
|
|
210
|
+
t: "big",
|
|
211
|
+
op,
|
|
212
|
+
lo: [],
|
|
213
|
+
hi: [],
|
|
214
|
+
body: [],
|
|
215
|
+
showLo: limits,
|
|
216
|
+
showHi: limits
|
|
217
|
+
});
|
|
218
|
+
var EQ_STRUCTURES = [
|
|
219
|
+
{ group: "Fraction", name: "Stacked", node: frac(), focus: ["num"] },
|
|
220
|
+
{ group: "Script", name: "Superscript", node: scr("sup"), focus: ["sup"] },
|
|
221
|
+
{ group: "Script", name: "Subscript", node: scr("sub"), focus: ["sub"] },
|
|
222
|
+
{ group: "Script", name: "Sub and super", node: scr("both"), focus: ["sub"] },
|
|
223
|
+
{ group: "Radical", name: "Square root", node: rad(false), focus: ["body"] },
|
|
224
|
+
{ group: "Radical", name: "Nth root", node: rad(true), focus: ["deg"] },
|
|
225
|
+
{ group: "Integral", name: "Integral", node: big("\u222B"), focus: ["body"] },
|
|
226
|
+
{ group: "Integral", name: "Definite", node: big("\u222B", true), focus: ["lo"] },
|
|
227
|
+
{ group: "Integral", name: "Double", node: big("\u222C"), focus: ["body"] },
|
|
228
|
+
{ group: "Integral", name: "Contour", node: big("\u222E"), focus: ["body"] },
|
|
229
|
+
{
|
|
230
|
+
group: "Large operator",
|
|
231
|
+
name: "Summation",
|
|
232
|
+
node: big("\u2211"),
|
|
233
|
+
focus: ["body"]
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
group: "Large operator",
|
|
237
|
+
name: "Sum with limits",
|
|
238
|
+
node: big("\u2211", true),
|
|
239
|
+
focus: ["lo"]
|
|
240
|
+
},
|
|
241
|
+
{ group: "Large operator", name: "Product", node: big("\u220F"), focus: ["body"] },
|
|
242
|
+
{
|
|
243
|
+
group: "Large operator",
|
|
244
|
+
name: "Product with limits",
|
|
245
|
+
node: big("\u220F", true),
|
|
246
|
+
focus: ["lo"]
|
|
247
|
+
},
|
|
248
|
+
{ group: "Large operator", name: "Union", node: big("\u22C3"), focus: ["body"] },
|
|
249
|
+
{
|
|
250
|
+
group: "Large operator",
|
|
251
|
+
name: "Intersection",
|
|
252
|
+
node: big("\u22C2"),
|
|
253
|
+
focus: ["body"]
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
group: "Bracket",
|
|
257
|
+
name: "Parentheses",
|
|
258
|
+
node: fence("(", ")"),
|
|
259
|
+
focus: ["body"]
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
group: "Bracket",
|
|
263
|
+
name: "Brackets",
|
|
264
|
+
node: fence("[", "]"),
|
|
265
|
+
focus: ["body"]
|
|
266
|
+
},
|
|
267
|
+
{ group: "Bracket", name: "Braces", node: fence("{", "}"), focus: ["body"] },
|
|
268
|
+
{
|
|
269
|
+
group: "Bracket",
|
|
270
|
+
name: "Absolute value",
|
|
271
|
+
node: fence("|", "|"),
|
|
272
|
+
focus: ["body"]
|
|
273
|
+
},
|
|
274
|
+
{ group: "Bracket", name: "Norm", node: fence("\u2016", "\u2016"), focus: ["body"] },
|
|
275
|
+
{ group: "Bracket", name: "Angle", node: fence("\u27E8", "\u27E9"), focus: ["body"] },
|
|
276
|
+
{ group: "Bracket", name: "Floor", node: fence("\u230A", "\u230B"), focus: ["body"] },
|
|
277
|
+
{ group: "Bracket", name: "Ceiling", node: fence("\u2308", "\u2309"), focus: ["body"] },
|
|
278
|
+
{ group: "Function", name: "sin", node: func("sin"), focus: ["body"] },
|
|
279
|
+
{ group: "Function", name: "cos", node: func("cos"), focus: ["body"] },
|
|
280
|
+
{ group: "Function", name: "tan", node: func("tan"), focus: ["body"] },
|
|
281
|
+
{ group: "Function", name: "cot", node: func("cot"), focus: ["body"] },
|
|
282
|
+
{ group: "Function", name: "ln", node: func("ln"), focus: ["body"] },
|
|
283
|
+
{ group: "Function", name: "log", node: func("log"), focus: ["body"] },
|
|
284
|
+
{ group: "Function", name: "exp", node: func("exp"), focus: ["body"] },
|
|
285
|
+
// The name is empty and editable — for anything the list does not carry.
|
|
286
|
+
{ group: "Function", name: "Custom", node: func(""), focus: ["name"] },
|
|
287
|
+
{ group: "Accent", name: "Bar", node: acc("\u0305"), focus: ["body"] },
|
|
288
|
+
{ group: "Accent", name: "Vector", node: acc("\u20D7"), focus: ["body"] },
|
|
289
|
+
{ group: "Accent", name: "Hat", node: acc("\u0302"), focus: ["body"] },
|
|
290
|
+
{ group: "Accent", name: "Tilde", node: acc("\u0303"), focus: ["body"] },
|
|
291
|
+
{ group: "Accent", name: "Dot", node: acc("\u0307"), focus: ["body"] },
|
|
292
|
+
{ group: "Accent", name: "Double dot", node: acc("\u0308"), focus: ["body"] },
|
|
293
|
+
{ group: "Limit", name: "Limit", node: lim("lim"), focus: ["lim"] },
|
|
294
|
+
{ group: "Limit", name: "Maximum", node: lim("max"), focus: ["lim"] },
|
|
295
|
+
{ group: "Limit", name: "Minimum", node: lim("min"), focus: ["lim"] },
|
|
296
|
+
{ group: "Limit", name: "Over", node: lim("", false), focus: ["base"] },
|
|
297
|
+
{ group: "Matrix", name: "1\xD72", node: mat(1, 2), focus: ["c0"] },
|
|
298
|
+
{ group: "Matrix", name: "2\xD71", node: mat(2, 1), focus: ["c0"] },
|
|
299
|
+
{ group: "Matrix", name: "2\xD72", node: mat(2, 2), focus: ["c0"] },
|
|
300
|
+
{ group: "Matrix", name: "3\xD73", node: mat(3, 3), focus: ["c0"] },
|
|
301
|
+
{
|
|
302
|
+
group: "Matrix",
|
|
303
|
+
name: "Bracketed 2\xD72",
|
|
304
|
+
node: braced("[", "]", 2, 2),
|
|
305
|
+
focus: ["body", 0, "c0"]
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
group: "Matrix",
|
|
309
|
+
name: "Determinant 2\xD72",
|
|
310
|
+
node: braced("|", "|", 2, 2),
|
|
311
|
+
focus: ["body", 0, "c0"]
|
|
312
|
+
},
|
|
313
|
+
// Two and three equations under one brace — how a system is set in
|
|
314
|
+
// Vietnamese exam papers, and awkward to build out of the pieces.
|
|
315
|
+
{
|
|
316
|
+
group: "Matrix",
|
|
317
|
+
name: "System of 2",
|
|
318
|
+
node: braced("{", "", 2, 1),
|
|
319
|
+
focus: ["body", 0, "c0"]
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
group: "Matrix",
|
|
323
|
+
name: "System of 3",
|
|
324
|
+
node: braced("{", "", 3, 1),
|
|
325
|
+
focus: ["body", 0, "c0"]
|
|
326
|
+
}
|
|
327
|
+
];
|
|
328
|
+
|
|
329
|
+
// packages/model/src/lib/model.ts
|
|
74
330
|
function dataJson(el, name) {
|
|
75
331
|
const raw = el.getAttribute(name);
|
|
76
332
|
if (!raw) return null;
|
|
@@ -292,6 +548,42 @@ var schema = new import_prosemirror_model.Schema({
|
|
|
292
548
|
parseDOM: [{ tag: "br.column-break" }],
|
|
293
549
|
toDOM: () => ["br", { class: "column-break" }]
|
|
294
550
|
},
|
|
551
|
+
// An equation with 2D structure — the AST (EqNode[], contracts) rides
|
|
552
|
+
// `ast`. An inline ATOM: the layout engine typesets it into a vector box
|
|
553
|
+
// sized by `sizePt`; editing goes through the equation plugin's slot
|
|
554
|
+
// editor, never the hidden text editor. toDOM carries the linear
|
|
555
|
+
// spelling as text, so the a11y mirror and copy read the math.
|
|
556
|
+
equation: {
|
|
557
|
+
inline: true,
|
|
558
|
+
group: "inline",
|
|
559
|
+
atom: true,
|
|
560
|
+
attrs: { ast: {}, sizePt: { default: 12 } },
|
|
561
|
+
parseDOM: [
|
|
562
|
+
{
|
|
563
|
+
tag: "span[data-eq]",
|
|
564
|
+
getAttrs: (el) => {
|
|
565
|
+
const ast = dataJson(el, "data-eq");
|
|
566
|
+
if (!isEqRow(ast)) return false;
|
|
567
|
+
const size = Number(el.getAttribute("data-eq-size"));
|
|
568
|
+
return {
|
|
569
|
+
ast,
|
|
570
|
+
sizePt: Number.isFinite(size) && size > 0 ? size : 12
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
],
|
|
575
|
+
toDOM(node) {
|
|
576
|
+
const ast = node.attrs["ast"];
|
|
577
|
+
return [
|
|
578
|
+
"span",
|
|
579
|
+
{
|
|
580
|
+
"data-eq": JSON.stringify(ast),
|
|
581
|
+
"data-eq-size": String(node.attrs["sizePt"])
|
|
582
|
+
},
|
|
583
|
+
astToLinear(isEqRow(ast) ? ast : [])
|
|
584
|
+
];
|
|
585
|
+
}
|
|
586
|
+
},
|
|
295
587
|
// Inline image. `src` is typically a data URL (the importer inlines the
|
|
296
588
|
// embedded media); width/height are CSS pixels, null if unspecified.
|
|
297
589
|
image: {
|
|
@@ -315,6 +607,27 @@ var schema = new import_prosemirror_model.Schema({
|
|
|
315
607
|
// { kind: 'rect'|'line', stroke?, strokeWidth?, fill?, flipV? } — src
|
|
316
608
|
// is then '' and the box paints as vector. Null for real bitmaps.
|
|
317
609
|
shape: { default: null },
|
|
610
|
+
// Replayed metafile (VectorImageSpec) — how MathType/OLE equation
|
|
611
|
+
// previews (vector WMF) paint. `src` keeps the original metafile
|
|
612
|
+
// data URL for export; the painter draws the ops instead. Null for
|
|
613
|
+
// bitmaps and preset shapes.
|
|
614
|
+
vector: { default: null },
|
|
615
|
+
// The equation's LINEAR text recovered from the metafile's embedded
|
|
616
|
+
// MTEF (MathType semantics) — what "Convert to editable equation"
|
|
617
|
+
// replaces the picture with. Null when the picture carries none.
|
|
618
|
+
equation: { default: null },
|
|
619
|
+
// The same equation as an AST (EqNode[]) — what conversion turns
|
|
620
|
+
// into a real 2D equation node. Null when undecodable.
|
|
621
|
+
equationAst: { default: null },
|
|
622
|
+
// `o:OLEObject/@ProgID` when this box is an EMBEDDED OBJECT rather
|
|
623
|
+
// than a picture ("Equation.DSMT4" for MathType). The bitmap is only
|
|
624
|
+
// the object's preview, so the editor offers object tools, not the
|
|
625
|
+
// picture toolkit. Null for real pictures.
|
|
626
|
+
oleProgId: { default: null },
|
|
627
|
+
// w:position on the run holding a legacy object — baseline shift in
|
|
628
|
+
// px, positive UP (same convention as InlineRun.raise). MathType
|
|
629
|
+
// lowers every equation so its baseline meets the text line's.
|
|
630
|
+
raise: { default: 0 },
|
|
318
631
|
// Textbox (wps:txbx) content riding a shape: { paragraphs: <paragraph
|
|
319
632
|
// node JSON>[], inset?: {l,t,r,b} px }. The layout engine flows the
|
|
320
633
|
// paragraphs inside the shape's box (paint-only, not editable v1).
|
|
@@ -679,6 +992,15 @@ var schema = new import_prosemirror_model.Schema({
|
|
|
679
992
|
0
|
|
680
993
|
]
|
|
681
994
|
},
|
|
995
|
+
// m:oMath — the run belongs to an equation. Linear v1: the letterforms
|
|
996
|
+
// live in the TEXT as Unicode math alphanumerics (𝑥, 𝒫, ℝ — see
|
|
997
|
+
// math.ts), so the mark is semantic, not visual: it scopes math
|
|
998
|
+
// autocorrect, keeps the region addressable for the coming in-place
|
|
999
|
+
// editor, and tells the exporter to wrap these runs back into m:oMath.
|
|
1000
|
+
math: {
|
|
1001
|
+
parseDOM: [{ tag: "span[data-math]" }],
|
|
1002
|
+
toDOM: () => ["span", { "data-math": "1" }, 0]
|
|
1003
|
+
},
|
|
682
1004
|
// w:highlight / w:shd w:fill — run background color ("#RRGGBB")
|
|
683
1005
|
highlight: {
|
|
684
1006
|
attrs: { color: {} },
|
package/dist/index.js
CHANGED
|
@@ -39,6 +39,262 @@ function fieldAt(doc, pos) {
|
|
|
39
39
|
|
|
40
40
|
// packages/model/src/lib/model.ts
|
|
41
41
|
import { Schema } from "prosemirror-model";
|
|
42
|
+
|
|
43
|
+
// packages/contracts/dist/index.js
|
|
44
|
+
var FIELD_SET = {
|
|
45
|
+
family: true,
|
|
46
|
+
sizePt: true,
|
|
47
|
+
bold: true,
|
|
48
|
+
italic: true,
|
|
49
|
+
letterSpacing: true,
|
|
50
|
+
scaleX: true,
|
|
51
|
+
kerning: true
|
|
52
|
+
};
|
|
53
|
+
var FIELDS = Object.keys(FIELD_SET);
|
|
54
|
+
var SUB_DIGIT = "\u2080\u2081\u2082\u2083\u2084\u2085\u2086\u2087\u2088\u2089";
|
|
55
|
+
var SUP_DIGIT = "\u2070\xB9\xB2\xB3\u2074\u2075\u2076\u2077\u2078\u2079";
|
|
56
|
+
var digitsVia = (s, alphabet) => /^[0-9]+$/.test(s) ? [...s].map((d) => alphabet[Number(d)]).join("") : null;
|
|
57
|
+
function astToLinear(row) {
|
|
58
|
+
const count = (s) => [...s].length;
|
|
59
|
+
const paren = (s) => count(s) <= 1 || s.startsWith("(") && s.endsWith(")") ? s : `(${s})`;
|
|
60
|
+
const sub = (s) => digitsVia(s, SUB_DIGIT) ?? (count(s) > 1 ? `_(${s})` : `_${s}`);
|
|
61
|
+
const sup = (s) => digitsVia(s, SUP_DIGIT) ?? (count(s) > 1 ? `^(${s})` : `^${s}`);
|
|
62
|
+
const one = (n) => {
|
|
63
|
+
switch (n.t) {
|
|
64
|
+
case "chr":
|
|
65
|
+
return n.ch;
|
|
66
|
+
case "frac":
|
|
67
|
+
return `${paren(astToLinear(n.num))}/${paren(astToLinear(n.den))}`;
|
|
68
|
+
case "rad": {
|
|
69
|
+
const deg = astToLinear(n.deg);
|
|
70
|
+
return `${deg ? sup(deg) : ""}\u221A(${astToLinear(n.body)})`;
|
|
71
|
+
}
|
|
72
|
+
case "scr": {
|
|
73
|
+
const lo = astToLinear(n.sub);
|
|
74
|
+
const hi = astToLinear(n.sup);
|
|
75
|
+
return astToLinear(n.base) + (lo ? sub(lo) : "") + (hi ? sup(hi) : "");
|
|
76
|
+
}
|
|
77
|
+
case "fence":
|
|
78
|
+
return n.l + astToLinear(n.body) + n.r;
|
|
79
|
+
case "big": {
|
|
80
|
+
const lo = astToLinear(n.lo);
|
|
81
|
+
const hi = astToLinear(n.hi);
|
|
82
|
+
return n.op + (lo ? sub(lo) : "") + (hi ? sup(hi) : "") + paren(astToLinear(n.body));
|
|
83
|
+
}
|
|
84
|
+
case "func":
|
|
85
|
+
return `${astToLinear(n.name)}\u2061${paren(astToLinear(n.body))}`;
|
|
86
|
+
case "acc":
|
|
87
|
+
return astToLinear(n.body) + n.chr;
|
|
88
|
+
case "lim": {
|
|
89
|
+
const l = astToLinear(n.lim);
|
|
90
|
+
return astToLinear(n.base) + (l ? n.below ? sub(l) : sup(l) : "");
|
|
91
|
+
}
|
|
92
|
+
case "mat": {
|
|
93
|
+
const lines = [];
|
|
94
|
+
for (let i = 0; i < n.cells.length; i += n.cols)
|
|
95
|
+
lines.push(
|
|
96
|
+
n.cells.slice(i, i + n.cols).map((c) => astToLinear(c)).join("&")
|
|
97
|
+
);
|
|
98
|
+
return `(${lines.join("@")})`;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
return row.map(one).join("");
|
|
103
|
+
}
|
|
104
|
+
function isEqRow(v) {
|
|
105
|
+
if (!Array.isArray(v)) return false;
|
|
106
|
+
return v.every((n) => {
|
|
107
|
+
if (typeof n !== "object" || n === null) return false;
|
|
108
|
+
const t = n.t;
|
|
109
|
+
if (t === "chr") return typeof n.ch === "string";
|
|
110
|
+
if (t === "frac")
|
|
111
|
+
return isEqRow(n.num) && isEqRow(n.den);
|
|
112
|
+
if (t === "rad")
|
|
113
|
+
return isEqRow(n.deg) && isEqRow(n.body);
|
|
114
|
+
if (t === "scr")
|
|
115
|
+
return isEqRow(n.base) && isEqRow(n.sub) && isEqRow(n.sup);
|
|
116
|
+
if (t === "fence")
|
|
117
|
+
return typeof n.l === "string" && typeof n.r === "string" && isEqRow(n.body);
|
|
118
|
+
if (t === "big")
|
|
119
|
+
return typeof n.op === "string" && isEqRow(n.lo) && isEqRow(n.hi) && isEqRow(n.body);
|
|
120
|
+
if (t === "func")
|
|
121
|
+
return isEqRow(n.name) && isEqRow(n.body);
|
|
122
|
+
if (t === "acc")
|
|
123
|
+
return typeof n.chr === "string" && isEqRow(n.body);
|
|
124
|
+
if (t === "lim")
|
|
125
|
+
return typeof n.below === "boolean" && isEqRow(n.base) && isEqRow(n.lim);
|
|
126
|
+
if (t === "mat") {
|
|
127
|
+
const m = n;
|
|
128
|
+
return typeof m.cols === "number" && m.cols > 0 && Array.isArray(m.cells) && m.cells.every((c) => isEqRow(c));
|
|
129
|
+
}
|
|
130
|
+
return false;
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
var frac = () => ({ t: "frac", num: [], den: [] });
|
|
134
|
+
var scr = (slots) => ({
|
|
135
|
+
t: "scr",
|
|
136
|
+
base: [],
|
|
137
|
+
sub: [],
|
|
138
|
+
sup: [],
|
|
139
|
+
slots
|
|
140
|
+
});
|
|
141
|
+
var rad = (showDeg) => ({
|
|
142
|
+
t: "rad",
|
|
143
|
+
deg: [],
|
|
144
|
+
body: [],
|
|
145
|
+
showDeg
|
|
146
|
+
});
|
|
147
|
+
var fence = (l, r) => ({
|
|
148
|
+
t: "fence",
|
|
149
|
+
l,
|
|
150
|
+
r,
|
|
151
|
+
body: []
|
|
152
|
+
});
|
|
153
|
+
var upright = (s) => [...s].map((ch) => ({ t: "chr", ch }));
|
|
154
|
+
var func = (name) => ({
|
|
155
|
+
t: "func",
|
|
156
|
+
name: upright(name),
|
|
157
|
+
body: []
|
|
158
|
+
});
|
|
159
|
+
var acc = (chr) => ({ t: "acc", chr, body: [] });
|
|
160
|
+
var mat = (rows, cols) => ({
|
|
161
|
+
t: "mat",
|
|
162
|
+
cols,
|
|
163
|
+
cells: Array.from({ length: rows * cols }, () => [])
|
|
164
|
+
});
|
|
165
|
+
var braced = (l, r, rows, cols) => ({
|
|
166
|
+
t: "fence",
|
|
167
|
+
l,
|
|
168
|
+
r,
|
|
169
|
+
body: [mat(rows, cols)]
|
|
170
|
+
});
|
|
171
|
+
var lim = (name, below = true) => ({
|
|
172
|
+
t: "lim",
|
|
173
|
+
base: upright(name),
|
|
174
|
+
lim: [],
|
|
175
|
+
below
|
|
176
|
+
});
|
|
177
|
+
var big = (op, limits = false) => ({
|
|
178
|
+
t: "big",
|
|
179
|
+
op,
|
|
180
|
+
lo: [],
|
|
181
|
+
hi: [],
|
|
182
|
+
body: [],
|
|
183
|
+
showLo: limits,
|
|
184
|
+
showHi: limits
|
|
185
|
+
});
|
|
186
|
+
var EQ_STRUCTURES = [
|
|
187
|
+
{ group: "Fraction", name: "Stacked", node: frac(), focus: ["num"] },
|
|
188
|
+
{ group: "Script", name: "Superscript", node: scr("sup"), focus: ["sup"] },
|
|
189
|
+
{ group: "Script", name: "Subscript", node: scr("sub"), focus: ["sub"] },
|
|
190
|
+
{ group: "Script", name: "Sub and super", node: scr("both"), focus: ["sub"] },
|
|
191
|
+
{ group: "Radical", name: "Square root", node: rad(false), focus: ["body"] },
|
|
192
|
+
{ group: "Radical", name: "Nth root", node: rad(true), focus: ["deg"] },
|
|
193
|
+
{ group: "Integral", name: "Integral", node: big("\u222B"), focus: ["body"] },
|
|
194
|
+
{ group: "Integral", name: "Definite", node: big("\u222B", true), focus: ["lo"] },
|
|
195
|
+
{ group: "Integral", name: "Double", node: big("\u222C"), focus: ["body"] },
|
|
196
|
+
{ group: "Integral", name: "Contour", node: big("\u222E"), focus: ["body"] },
|
|
197
|
+
{
|
|
198
|
+
group: "Large operator",
|
|
199
|
+
name: "Summation",
|
|
200
|
+
node: big("\u2211"),
|
|
201
|
+
focus: ["body"]
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
group: "Large operator",
|
|
205
|
+
name: "Sum with limits",
|
|
206
|
+
node: big("\u2211", true),
|
|
207
|
+
focus: ["lo"]
|
|
208
|
+
},
|
|
209
|
+
{ group: "Large operator", name: "Product", node: big("\u220F"), focus: ["body"] },
|
|
210
|
+
{
|
|
211
|
+
group: "Large operator",
|
|
212
|
+
name: "Product with limits",
|
|
213
|
+
node: big("\u220F", true),
|
|
214
|
+
focus: ["lo"]
|
|
215
|
+
},
|
|
216
|
+
{ group: "Large operator", name: "Union", node: big("\u22C3"), focus: ["body"] },
|
|
217
|
+
{
|
|
218
|
+
group: "Large operator",
|
|
219
|
+
name: "Intersection",
|
|
220
|
+
node: big("\u22C2"),
|
|
221
|
+
focus: ["body"]
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
group: "Bracket",
|
|
225
|
+
name: "Parentheses",
|
|
226
|
+
node: fence("(", ")"),
|
|
227
|
+
focus: ["body"]
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
group: "Bracket",
|
|
231
|
+
name: "Brackets",
|
|
232
|
+
node: fence("[", "]"),
|
|
233
|
+
focus: ["body"]
|
|
234
|
+
},
|
|
235
|
+
{ group: "Bracket", name: "Braces", node: fence("{", "}"), focus: ["body"] },
|
|
236
|
+
{
|
|
237
|
+
group: "Bracket",
|
|
238
|
+
name: "Absolute value",
|
|
239
|
+
node: fence("|", "|"),
|
|
240
|
+
focus: ["body"]
|
|
241
|
+
},
|
|
242
|
+
{ group: "Bracket", name: "Norm", node: fence("\u2016", "\u2016"), focus: ["body"] },
|
|
243
|
+
{ group: "Bracket", name: "Angle", node: fence("\u27E8", "\u27E9"), focus: ["body"] },
|
|
244
|
+
{ group: "Bracket", name: "Floor", node: fence("\u230A", "\u230B"), focus: ["body"] },
|
|
245
|
+
{ group: "Bracket", name: "Ceiling", node: fence("\u2308", "\u2309"), focus: ["body"] },
|
|
246
|
+
{ group: "Function", name: "sin", node: func("sin"), focus: ["body"] },
|
|
247
|
+
{ group: "Function", name: "cos", node: func("cos"), focus: ["body"] },
|
|
248
|
+
{ group: "Function", name: "tan", node: func("tan"), focus: ["body"] },
|
|
249
|
+
{ group: "Function", name: "cot", node: func("cot"), focus: ["body"] },
|
|
250
|
+
{ group: "Function", name: "ln", node: func("ln"), focus: ["body"] },
|
|
251
|
+
{ group: "Function", name: "log", node: func("log"), focus: ["body"] },
|
|
252
|
+
{ group: "Function", name: "exp", node: func("exp"), focus: ["body"] },
|
|
253
|
+
// The name is empty and editable — for anything the list does not carry.
|
|
254
|
+
{ group: "Function", name: "Custom", node: func(""), focus: ["name"] },
|
|
255
|
+
{ group: "Accent", name: "Bar", node: acc("\u0305"), focus: ["body"] },
|
|
256
|
+
{ group: "Accent", name: "Vector", node: acc("\u20D7"), focus: ["body"] },
|
|
257
|
+
{ group: "Accent", name: "Hat", node: acc("\u0302"), focus: ["body"] },
|
|
258
|
+
{ group: "Accent", name: "Tilde", node: acc("\u0303"), focus: ["body"] },
|
|
259
|
+
{ group: "Accent", name: "Dot", node: acc("\u0307"), focus: ["body"] },
|
|
260
|
+
{ group: "Accent", name: "Double dot", node: acc("\u0308"), focus: ["body"] },
|
|
261
|
+
{ group: "Limit", name: "Limit", node: lim("lim"), focus: ["lim"] },
|
|
262
|
+
{ group: "Limit", name: "Maximum", node: lim("max"), focus: ["lim"] },
|
|
263
|
+
{ group: "Limit", name: "Minimum", node: lim("min"), focus: ["lim"] },
|
|
264
|
+
{ group: "Limit", name: "Over", node: lim("", false), focus: ["base"] },
|
|
265
|
+
{ group: "Matrix", name: "1\xD72", node: mat(1, 2), focus: ["c0"] },
|
|
266
|
+
{ group: "Matrix", name: "2\xD71", node: mat(2, 1), focus: ["c0"] },
|
|
267
|
+
{ group: "Matrix", name: "2\xD72", node: mat(2, 2), focus: ["c0"] },
|
|
268
|
+
{ group: "Matrix", name: "3\xD73", node: mat(3, 3), focus: ["c0"] },
|
|
269
|
+
{
|
|
270
|
+
group: "Matrix",
|
|
271
|
+
name: "Bracketed 2\xD72",
|
|
272
|
+
node: braced("[", "]", 2, 2),
|
|
273
|
+
focus: ["body", 0, "c0"]
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
group: "Matrix",
|
|
277
|
+
name: "Determinant 2\xD72",
|
|
278
|
+
node: braced("|", "|", 2, 2),
|
|
279
|
+
focus: ["body", 0, "c0"]
|
|
280
|
+
},
|
|
281
|
+
// Two and three equations under one brace — how a system is set in
|
|
282
|
+
// Vietnamese exam papers, and awkward to build out of the pieces.
|
|
283
|
+
{
|
|
284
|
+
group: "Matrix",
|
|
285
|
+
name: "System of 2",
|
|
286
|
+
node: braced("{", "", 2, 1),
|
|
287
|
+
focus: ["body", 0, "c0"]
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
group: "Matrix",
|
|
291
|
+
name: "System of 3",
|
|
292
|
+
node: braced("{", "", 3, 1),
|
|
293
|
+
focus: ["body", 0, "c0"]
|
|
294
|
+
}
|
|
295
|
+
];
|
|
296
|
+
|
|
297
|
+
// packages/model/src/lib/model.ts
|
|
42
298
|
function dataJson(el, name) {
|
|
43
299
|
const raw = el.getAttribute(name);
|
|
44
300
|
if (!raw) return null;
|
|
@@ -260,6 +516,42 @@ var schema = new Schema({
|
|
|
260
516
|
parseDOM: [{ tag: "br.column-break" }],
|
|
261
517
|
toDOM: () => ["br", { class: "column-break" }]
|
|
262
518
|
},
|
|
519
|
+
// An equation with 2D structure — the AST (EqNode[], contracts) rides
|
|
520
|
+
// `ast`. An inline ATOM: the layout engine typesets it into a vector box
|
|
521
|
+
// sized by `sizePt`; editing goes through the equation plugin's slot
|
|
522
|
+
// editor, never the hidden text editor. toDOM carries the linear
|
|
523
|
+
// spelling as text, so the a11y mirror and copy read the math.
|
|
524
|
+
equation: {
|
|
525
|
+
inline: true,
|
|
526
|
+
group: "inline",
|
|
527
|
+
atom: true,
|
|
528
|
+
attrs: { ast: {}, sizePt: { default: 12 } },
|
|
529
|
+
parseDOM: [
|
|
530
|
+
{
|
|
531
|
+
tag: "span[data-eq]",
|
|
532
|
+
getAttrs: (el) => {
|
|
533
|
+
const ast = dataJson(el, "data-eq");
|
|
534
|
+
if (!isEqRow(ast)) return false;
|
|
535
|
+
const size = Number(el.getAttribute("data-eq-size"));
|
|
536
|
+
return {
|
|
537
|
+
ast,
|
|
538
|
+
sizePt: Number.isFinite(size) && size > 0 ? size : 12
|
|
539
|
+
};
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
],
|
|
543
|
+
toDOM(node) {
|
|
544
|
+
const ast = node.attrs["ast"];
|
|
545
|
+
return [
|
|
546
|
+
"span",
|
|
547
|
+
{
|
|
548
|
+
"data-eq": JSON.stringify(ast),
|
|
549
|
+
"data-eq-size": String(node.attrs["sizePt"])
|
|
550
|
+
},
|
|
551
|
+
astToLinear(isEqRow(ast) ? ast : [])
|
|
552
|
+
];
|
|
553
|
+
}
|
|
554
|
+
},
|
|
263
555
|
// Inline image. `src` is typically a data URL (the importer inlines the
|
|
264
556
|
// embedded media); width/height are CSS pixels, null if unspecified.
|
|
265
557
|
image: {
|
|
@@ -283,6 +575,27 @@ var schema = new Schema({
|
|
|
283
575
|
// { kind: 'rect'|'line', stroke?, strokeWidth?, fill?, flipV? } — src
|
|
284
576
|
// is then '' and the box paints as vector. Null for real bitmaps.
|
|
285
577
|
shape: { default: null },
|
|
578
|
+
// Replayed metafile (VectorImageSpec) — how MathType/OLE equation
|
|
579
|
+
// previews (vector WMF) paint. `src` keeps the original metafile
|
|
580
|
+
// data URL for export; the painter draws the ops instead. Null for
|
|
581
|
+
// bitmaps and preset shapes.
|
|
582
|
+
vector: { default: null },
|
|
583
|
+
// The equation's LINEAR text recovered from the metafile's embedded
|
|
584
|
+
// MTEF (MathType semantics) — what "Convert to editable equation"
|
|
585
|
+
// replaces the picture with. Null when the picture carries none.
|
|
586
|
+
equation: { default: null },
|
|
587
|
+
// The same equation as an AST (EqNode[]) — what conversion turns
|
|
588
|
+
// into a real 2D equation node. Null when undecodable.
|
|
589
|
+
equationAst: { default: null },
|
|
590
|
+
// `o:OLEObject/@ProgID` when this box is an EMBEDDED OBJECT rather
|
|
591
|
+
// than a picture ("Equation.DSMT4" for MathType). The bitmap is only
|
|
592
|
+
// the object's preview, so the editor offers object tools, not the
|
|
593
|
+
// picture toolkit. Null for real pictures.
|
|
594
|
+
oleProgId: { default: null },
|
|
595
|
+
// w:position on the run holding a legacy object — baseline shift in
|
|
596
|
+
// px, positive UP (same convention as InlineRun.raise). MathType
|
|
597
|
+
// lowers every equation so its baseline meets the text line's.
|
|
598
|
+
raise: { default: 0 },
|
|
286
599
|
// Textbox (wps:txbx) content riding a shape: { paragraphs: <paragraph
|
|
287
600
|
// node JSON>[], inset?: {l,t,r,b} px }. The layout engine flows the
|
|
288
601
|
// paragraphs inside the shape's box (paint-only, not editable v1).
|
|
@@ -647,6 +960,15 @@ var schema = new Schema({
|
|
|
647
960
|
0
|
|
648
961
|
]
|
|
649
962
|
},
|
|
963
|
+
// m:oMath — the run belongs to an equation. Linear v1: the letterforms
|
|
964
|
+
// live in the TEXT as Unicode math alphanumerics (𝑥, 𝒫, ℝ — see
|
|
965
|
+
// math.ts), so the mark is semantic, not visual: it scopes math
|
|
966
|
+
// autocorrect, keeps the region addressable for the coming in-place
|
|
967
|
+
// editor, and tells the exporter to wrap these runs back into m:oMath.
|
|
968
|
+
math: {
|
|
969
|
+
parseDOM: [{ tag: "span[data-math]" }],
|
|
970
|
+
toDOM: () => ["span", { "data-math": "1" }, 0]
|
|
971
|
+
},
|
|
650
972
|
// w:highlight / w:shd w:fill — run background color ("#RRGGBB")
|
|
651
973
|
highlight: {
|
|
652
974
|
attrs: { color: {} },
|
package/dist/lib/model.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { Schema } from 'prosemirror-model';
|
|
|
8
8
|
* extend THIS schema so the importer, layout engine, and (canvas) painter all
|
|
9
9
|
* agree on one document model.
|
|
10
10
|
*/
|
|
11
|
-
export declare const schema: Schema<"paragraph" | "
|
|
11
|
+
export declare const schema: Schema<"paragraph" | "text" | "table" | "doc" | "hard_break" | "column_break" | "equation" | "image" | "page_field" | "table_row" | "table_cell", "letterSpacing" | "link" | "strike" | "underline" | "strong" | "em" | "dstrike" | "smallCaps" | "textColor" | "fontSize" | "vertAlign" | "kern" | "charScale" | "position" | "math" | "highlight" | "fontFamily" | "footnote" | "carryRPr">;
|
|
12
12
|
/** Concrete schema type, handy for typing Node/Mark across packages. */
|
|
13
13
|
export type BapbongSchema = typeof schema;
|
|
14
14
|
/**
|
|
@@ -17,7 +17,7 @@ export type BapbongSchema = typeof schema;
|
|
|
17
17
|
* (@user). Comment bodies are stored as this schema's JSON on the comment
|
|
18
18
|
* thread, kept separate from the document schema.
|
|
19
19
|
*/
|
|
20
|
-
export declare const commentSchema: Schema<"paragraph" | "
|
|
20
|
+
export declare const commentSchema: Schema<"paragraph" | "text" | "doc" | "mention", never>;
|
|
21
21
|
export type CommentSchema = typeof commentSchema;
|
|
22
22
|
/** Paragraph horizontal alignment (mirrors w:jc). */
|
|
23
23
|
export type Align = 'left' | 'center' | 'right' | 'justify';
|
package/dist/lib/model.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/lib/model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/lib/model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AA2F3C;;;;;;;;GAQG;AACH,eAAO,MAAM,MAAM,+XA2uBjB,CAAC;AAEH,wEAAwE;AACxE,MAAM,MAAM,aAAa,GAAG,OAAO,MAAM,CAAC;AAE1C;;;;;GAKG;AACH,eAAO,MAAM,aAAa,yDA0CxB,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,OAAO,aAAa,CAAC;AAEjD,qDAAqD;AACrD,MAAM,MAAM,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;AAE5D;+EAC+E;AAC/E,MAAM,WAAW,MAAM;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,2EAA2E;AAC3E,MAAM,WAAW,OAAO;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;IACxC;;;6EAGyE;IACzE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,IAAI,CAAC;CACvC;AA0BD;;;4EAG4E;AAC5E,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shadow-garden/bapbong-model",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "bapbong — ProseMirror document model / schema",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -54,6 +54,7 @@
|
|
|
54
54
|
}
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"prosemirror-model": "^1.25.7"
|
|
57
|
+
"prosemirror-model": "^1.25.7",
|
|
58
|
+
"@shadow-garden/bapbong-contracts": "^0.15.0"
|
|
58
59
|
}
|
|
59
60
|
}
|