@shadow-garden/bapbong-model 0.14.0 → 0.16.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 CHANGED
@@ -170,11 +170,13 @@ var scr = (slots) => ({
170
170
  sup: [],
171
171
  slots
172
172
  });
173
- var rad = (showDeg) => ({
173
+ var rad = (deg) => ({
174
174
  t: "rad",
175
- deg: [],
175
+ // A degree the template fills in — the 3 of a cube root — is content like
176
+ // any other: the caret can reach it and type over it.
177
+ deg: deg ? upright(deg) : [],
176
178
  body: [],
177
- showDeg
179
+ showDeg: deg !== null
178
180
  });
179
181
  var fence = (l, r) => ({
180
182
  t: "fence",
@@ -189,6 +191,11 @@ var func = (name) => ({
189
191
  body: []
190
192
  });
191
193
  var acc = (chr) => ({ t: "acc", chr, body: [] });
194
+ var funcSub = (name) => ({
195
+ t: "func",
196
+ name: [{ t: "scr", base: upright(name), sub: [], sup: [], slots: "sub" }],
197
+ body: []
198
+ });
192
199
  var mat = (rows, cols) => ({
193
200
  t: "mat",
194
201
  cols,
@@ -200,11 +207,10 @@ var braced = (l, r, rows, cols) => ({
200
207
  r,
201
208
  body: [mat(rows, cols)]
202
209
  });
203
- var lim = (name, below = true) => ({
204
- t: "lim",
205
- base: upright(name),
206
- lim: [],
207
- below
210
+ var limFunc = (name) => ({
211
+ t: "func",
212
+ name: [{ t: "lim", base: upright(name), lim: [], below: true }],
213
+ body: []
208
214
  });
209
215
  var big = (op, limits = false) => ({
210
216
  t: "big",
@@ -217,11 +223,17 @@ var big = (op, limits = false) => ({
217
223
  });
218
224
  var EQ_STRUCTURES = [
219
225
  { 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"] },
226
+ { group: "Script", name: "Superscript", node: scr("sup"), focus: ["base"] },
227
+ { group: "Script", name: "Subscript", node: scr("sub"), focus: ["base"] },
228
+ {
229
+ group: "Script",
230
+ name: "Sub and super",
231
+ node: scr("both"),
232
+ focus: ["base"]
233
+ },
234
+ { group: "Radical", name: "Square root", node: rad(null), focus: ["body"] },
235
+ { group: "Radical", name: "Cube root", node: rad("3"), focus: ["body"] },
236
+ { group: "Radical", name: "Nth root", node: rad(""), focus: ["deg"] },
225
237
  { group: "Integral", name: "Integral", node: big("\u222B"), focus: ["body"] },
226
238
  { group: "Integral", name: "Definite", node: big("\u222B", true), focus: ["lo"] },
227
239
  { group: "Integral", name: "Double", node: big("\u222C"), focus: ["body"] },
@@ -279,8 +291,14 @@ var EQ_STRUCTURES = [
279
291
  { group: "Function", name: "cos", node: func("cos"), focus: ["body"] },
280
292
  { group: "Function", name: "tan", node: func("tan"), focus: ["body"] },
281
293
  { 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"] },
294
+ { group: "Function", name: "sec", node: func("sec"), focus: ["body"] },
295
+ { group: "Function", name: "csc", node: func("csc"), focus: ["body"] },
296
+ { group: "Function", name: "arcsin", node: func("arcsin"), focus: ["body"] },
297
+ { group: "Function", name: "arccos", node: func("arccos"), focus: ["body"] },
298
+ { group: "Function", name: "arctan", node: func("arctan"), focus: ["body"] },
299
+ { group: "Function", name: "sinh", node: func("sinh"), focus: ["body"] },
300
+ { group: "Function", name: "cosh", node: func("cosh"), focus: ["body"] },
301
+ { group: "Function", name: "tanh", node: func("tanh"), focus: ["body"] },
284
302
  { group: "Function", name: "exp", node: func("exp"), focus: ["body"] },
285
303
  // The name is empty and editable — for anything the list does not carry.
286
304
  { group: "Function", name: "Custom", node: func(""), focus: ["name"] },
@@ -290,10 +308,37 @@ var EQ_STRUCTURES = [
290
308
  { group: "Accent", name: "Tilde", node: acc("\u0303"), focus: ["body"] },
291
309
  { group: "Accent", name: "Dot", node: acc("\u0307"), focus: ["body"] },
292
310
  { 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"] },
311
+ // Word keeps the logarithms and the limit operators in ONE gallery, and so
312
+ // do we: they are the same shape — a name that may carry something under
313
+ // or beside it, applied to an expression.
314
+ // The base rides the NAME, not the argument, and the caret opens on it —
315
+ // it is the part you came to this entry to type.
316
+ {
317
+ group: "Limit and log",
318
+ name: "log base",
319
+ node: funcSub("log"),
320
+ focus: ["name", 0, "sub"]
321
+ },
322
+ { group: "Limit and log", name: "log", node: func("log"), focus: ["body"] },
323
+ {
324
+ group: "Limit and log",
325
+ name: "lim",
326
+ node: limFunc("lim"),
327
+ focus: ["name", 0, "lim"]
328
+ },
329
+ {
330
+ group: "Limit and log",
331
+ name: "min",
332
+ node: limFunc("min"),
333
+ focus: ["name", 0, "lim"]
334
+ },
335
+ {
336
+ group: "Limit and log",
337
+ name: "max",
338
+ node: limFunc("max"),
339
+ focus: ["name", 0, "lim"]
340
+ },
341
+ { group: "Limit and log", name: "ln", node: func("ln"), focus: ["body"] },
297
342
  { group: "Matrix", name: "1\xD72", node: mat(1, 2), focus: ["c0"] },
298
343
  { group: "Matrix", name: "2\xD71", node: mat(2, 1), focus: ["c0"] },
299
344
  { group: "Matrix", name: "2\xD72", node: mat(2, 2), focus: ["c0"] },
@@ -362,7 +407,8 @@ function pastedImageAttrs(el) {
362
407
  width: dim(e.getAttribute("width")),
363
408
  height: dim(e.getAttribute("height")),
364
409
  crop: dataJson(el, "data-crop"),
365
- outline: dataJson(el, "data-outline")
410
+ outline: dataJson(el, "data-outline"),
411
+ effectExtent: dataJson(el, "data-effect-extent")
366
412
  };
367
413
  }
368
414
  function pastedLinkAttrs(el) {
@@ -382,8 +428,8 @@ function pastedCellAttrs(el) {
382
428
  colspan: span("colspan"),
383
429
  rowspan: span("rowspan"),
384
430
  colwidth: dataJson(el, "data-colwidth"),
385
- background: bg ? bg[1].trim() : null,
386
- vAlign: e.getAttribute("data-valign"),
431
+ background: bg ? bg[1].trim() : e.getAttribute("data-background") === "none" ? false : null,
432
+ vAlign: e.getAttribute("data-valign") === "none" ? false : e.getAttribute("data-valign"),
387
433
  borders: dataJson(el, "data-borders"),
388
434
  diagonals: dataJson(el, "data-diagonals"),
389
435
  padding: dataJson(el, "data-padding"),
@@ -413,6 +459,21 @@ var schema = new import_prosemirror_model.Schema({
413
459
  // CommentNode[] (contracts) — comment threads keyed to `comment` marks.
414
460
  // Edited via setDocAttribute so add/reply/resolve/delete undo cleanly.
415
461
  comments: { default: null },
462
+ // TableStyleSheet (contracts) — every table style the document's
463
+ // tables name, fully resolved (basedOn rolled up, theme colours hex).
464
+ // LIVE data, not a bake: tables carry styleId/look attrs and the
465
+ // layout applies the sheet per cell, so flipping a tblLook gate or
466
+ // switching styles is one small attr transaction. Importer-set;
467
+ // extended when the editor applies a style the sheet lacks.
468
+ tableStyles: { default: null },
469
+ // { spacing?: ParagraphSpacing } | null — the document's default
470
+ // paragraph properties (w:docDefaults/w:pPrDefault), the FLOOR of
471
+ // every paragraph's cascade. Live data like the sheet: a paragraph's
472
+ // `spacing` attr carries only what sits ABOVE the table-style slot
473
+ // (its style, numbering, direct formatting), and the layout stacks
474
+ // floor → table-style cell layer → attr. Importer-set; null for an
475
+ // editor-authored doc (whose paragraphs then carry everything).
476
+ paragraphDefaults: { default: null },
416
477
  // Per-section header/footer story OVERRIDES, keyed by section index →
417
478
  // story ('headers'|'footers') → variant ('default'|'first'|'even') →
418
479
  // the full story doc as JSON. The first chrome EDIT the model supports
@@ -452,6 +513,10 @@ var schema = new import_prosemirror_model.Schema({
452
513
  // w:spacing — { before?, after?, line?, lineRule?, beforeAuto?,
453
514
  // afterAuto? }, or null. The two *Auto flags record that Word computes
454
515
  // the gap itself; before/after hold what it works out to here.
516
+ // Carries the cascade ABOVE the table-style slot only (paragraph
517
+ // style, numbering, direct): the document defaults live in
518
+ // doc.attrs.paragraphDefaults and a table style's pPr in the sheet,
519
+ // and the layout stacks floor → cell layer → this attr.
455
520
  spacing: { default: null },
456
521
  // w:bookmarkStart names anchored in this paragraph (["_Toc89595219"]),
457
522
  // or null. Link hrefs of the form "#name" resolve against these —
@@ -641,6 +706,12 @@ var schema = new import_prosemirror_model.Schema({
641
706
  crop: { default: null },
642
707
  // a:ln on pic:spPr — Word's picture border, as a BorderSide, or null.
643
708
  outline: { default: null },
709
+ // wp:effectExtent — { l, t, r, b } in EMU, verbatim from the file, or
710
+ // null. The room Word keeps around the extent for what paints
711
+ // outside it (a picture border sits centred on the edge). Word CLIPS
712
+ // an inline picture to extent + effectExtent, so this has to survive
713
+ // a save or a framed photo loses the outer half of its top edge.
714
+ effectExtent: { default: null },
644
715
  // a:solidFill on pic:spPr — "#RRGGBB" painted behind the bitmap
645
716
  // (shows through transparency), or null.
646
717
  background: { default: null }
@@ -657,6 +728,8 @@ var schema = new import_prosemirror_model.Schema({
657
728
  if (a["height"] != null) attrs["height"] = String(a["height"]);
658
729
  if (a["crop"]) attrs["data-crop"] = JSON.stringify(a["crop"]);
659
730
  if (a["outline"]) attrs["data-outline"] = JSON.stringify(a["outline"]);
731
+ if (a["effectExtent"])
732
+ attrs["data-effect-extent"] = JSON.stringify(a["effectExtent"]);
660
733
  if (a["background"])
661
734
  attrs["data-background"] = a["background"];
662
735
  return ["img", attrs];
@@ -696,6 +769,14 @@ var schema = new import_prosemirror_model.Schema({
696
769
  // the importer). null = Word's implicit outdent by the left cell
697
770
  // margin. Importer-set; the element itself rides carry for export.
698
771
  indent: { default: null },
772
+ // w:tblStyle — the table style this table names, or null. The style's
773
+ // definition lives in doc.attrs.tableStyles; the LAYOUT applies it,
774
+ // so this attr (with `look`) is the whole apply-a-style transaction.
775
+ styleId: { default: null },
776
+ // w:tblLook — the six conditional-formatting gates (TableLook,
777
+ // contracts), or null for Word's default 04A0 (firstRow + firstCol +
778
+ // hBand on).
779
+ look: { default: null },
699
780
  // Carry-through fidelity: unmodelled w:tblPr children (tblStyle,
700
781
  // tblLayout, tblLook, tblInd, floating tblpPr, …) as one raw XML
701
782
  // string ({ tblPr: string }), or null. Importer-set; the exporter
@@ -713,6 +794,8 @@ var schema = new import_prosemirror_model.Schema({
713
794
  cellPadding: dataJson(el, "data-cell-padding"),
714
795
  align: el.getAttribute("data-align"),
715
796
  indent: dataJson(el, "data-indent"),
797
+ styleId: el.getAttribute("data-style-id"),
798
+ look: dataJson(el, "data-look"),
716
799
  carry: dataJson(el, "data-carry")
717
800
  })
718
801
  }
@@ -725,6 +808,8 @@ var schema = new import_prosemirror_model.Schema({
725
808
  dom["data-cell-padding"] = JSON.stringify(a["cellPadding"]);
726
809
  if (a["align"]) dom["data-align"] = String(a["align"]);
727
810
  if (a["indent"] != null) dom["data-indent"] = String(a["indent"]);
811
+ if (a["styleId"]) dom["data-style-id"] = String(a["styleId"]);
812
+ if (a["look"]) dom["data-look"] = JSON.stringify(a["look"]);
728
813
  if (a["carry"]) dom["data-carry"] = JSON.stringify(a["carry"]);
729
814
  return ["table", dom, ["tbody", 0]];
730
815
  }
@@ -773,10 +858,13 @@ var schema = new import_prosemirror_model.Schema({
773
858
  rowspan: { default: 1 },
774
859
  colwidth: { default: null },
775
860
  // px widths of the spanned columns, or null
861
+ // w:shd w:fill — cell fill "#RRGGBB". `false` is an EXPLICIT no-fill
862
+ // (w:fill="auto"), which must beat a table style's fill; null means
863
+ // the cell says nothing and the style layer may paint.
776
864
  background: { default: null },
777
- // w:shd w:fill cell fill "#RRGGBB"
865
+ // w:vAlign'center' | 'bottom' (top is Word's default). `false` is
866
+ // an explicit reset ("top"/"both" declared), beating a style's.
778
867
  vAlign: { default: null },
779
- // w:vAlign — 'center' | 'bottom' (top default)
780
868
  borders: { default: null },
781
869
  // w:tcBorders per-side visibility override
782
870
  // w:tcBorders/w:tl2br + w:br2tl — rules across the cell's corners
@@ -799,10 +887,13 @@ var schema = new import_prosemirror_model.Schema({
799
887
  attrs["rowspan"] = String(node.attrs["rowspan"]);
800
888
  if (node.attrs["background"])
801
889
  attrs["style"] = `background-color: ${node.attrs["background"]}`;
890
+ else if (node.attrs["background"] === false)
891
+ attrs["data-background"] = "none";
802
892
  if (node.attrs["colwidth"])
803
893
  attrs["data-colwidth"] = JSON.stringify(node.attrs["colwidth"]);
804
894
  if (node.attrs["vAlign"])
805
895
  attrs["data-valign"] = String(node.attrs["vAlign"]);
896
+ else if (node.attrs["vAlign"] === false) attrs["data-valign"] = "none";
806
897
  if (node.attrs["borders"])
807
898
  attrs["data-borders"] = JSON.stringify(node.attrs["borders"]);
808
899
  if (node.attrs["diagonals"])
package/dist/index.js CHANGED
@@ -138,11 +138,13 @@ var scr = (slots) => ({
138
138
  sup: [],
139
139
  slots
140
140
  });
141
- var rad = (showDeg) => ({
141
+ var rad = (deg) => ({
142
142
  t: "rad",
143
- deg: [],
143
+ // A degree the template fills in — the 3 of a cube root — is content like
144
+ // any other: the caret can reach it and type over it.
145
+ deg: deg ? upright(deg) : [],
144
146
  body: [],
145
- showDeg
147
+ showDeg: deg !== null
146
148
  });
147
149
  var fence = (l, r) => ({
148
150
  t: "fence",
@@ -157,6 +159,11 @@ var func = (name) => ({
157
159
  body: []
158
160
  });
159
161
  var acc = (chr) => ({ t: "acc", chr, body: [] });
162
+ var funcSub = (name) => ({
163
+ t: "func",
164
+ name: [{ t: "scr", base: upright(name), sub: [], sup: [], slots: "sub" }],
165
+ body: []
166
+ });
160
167
  var mat = (rows, cols) => ({
161
168
  t: "mat",
162
169
  cols,
@@ -168,11 +175,10 @@ var braced = (l, r, rows, cols) => ({
168
175
  r,
169
176
  body: [mat(rows, cols)]
170
177
  });
171
- var lim = (name, below = true) => ({
172
- t: "lim",
173
- base: upright(name),
174
- lim: [],
175
- below
178
+ var limFunc = (name) => ({
179
+ t: "func",
180
+ name: [{ t: "lim", base: upright(name), lim: [], below: true }],
181
+ body: []
176
182
  });
177
183
  var big = (op, limits = false) => ({
178
184
  t: "big",
@@ -185,11 +191,17 @@ var big = (op, limits = false) => ({
185
191
  });
186
192
  var EQ_STRUCTURES = [
187
193
  { 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"] },
194
+ { group: "Script", name: "Superscript", node: scr("sup"), focus: ["base"] },
195
+ { group: "Script", name: "Subscript", node: scr("sub"), focus: ["base"] },
196
+ {
197
+ group: "Script",
198
+ name: "Sub and super",
199
+ node: scr("both"),
200
+ focus: ["base"]
201
+ },
202
+ { group: "Radical", name: "Square root", node: rad(null), focus: ["body"] },
203
+ { group: "Radical", name: "Cube root", node: rad("3"), focus: ["body"] },
204
+ { group: "Radical", name: "Nth root", node: rad(""), focus: ["deg"] },
193
205
  { group: "Integral", name: "Integral", node: big("\u222B"), focus: ["body"] },
194
206
  { group: "Integral", name: "Definite", node: big("\u222B", true), focus: ["lo"] },
195
207
  { group: "Integral", name: "Double", node: big("\u222C"), focus: ["body"] },
@@ -247,8 +259,14 @@ var EQ_STRUCTURES = [
247
259
  { group: "Function", name: "cos", node: func("cos"), focus: ["body"] },
248
260
  { group: "Function", name: "tan", node: func("tan"), focus: ["body"] },
249
261
  { 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"] },
262
+ { group: "Function", name: "sec", node: func("sec"), focus: ["body"] },
263
+ { group: "Function", name: "csc", node: func("csc"), focus: ["body"] },
264
+ { group: "Function", name: "arcsin", node: func("arcsin"), focus: ["body"] },
265
+ { group: "Function", name: "arccos", node: func("arccos"), focus: ["body"] },
266
+ { group: "Function", name: "arctan", node: func("arctan"), focus: ["body"] },
267
+ { group: "Function", name: "sinh", node: func("sinh"), focus: ["body"] },
268
+ { group: "Function", name: "cosh", node: func("cosh"), focus: ["body"] },
269
+ { group: "Function", name: "tanh", node: func("tanh"), focus: ["body"] },
252
270
  { group: "Function", name: "exp", node: func("exp"), focus: ["body"] },
253
271
  // The name is empty and editable — for anything the list does not carry.
254
272
  { group: "Function", name: "Custom", node: func(""), focus: ["name"] },
@@ -258,10 +276,37 @@ var EQ_STRUCTURES = [
258
276
  { group: "Accent", name: "Tilde", node: acc("\u0303"), focus: ["body"] },
259
277
  { group: "Accent", name: "Dot", node: acc("\u0307"), focus: ["body"] },
260
278
  { 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"] },
279
+ // Word keeps the logarithms and the limit operators in ONE gallery, and so
280
+ // do we: they are the same shape — a name that may carry something under
281
+ // or beside it, applied to an expression.
282
+ // The base rides the NAME, not the argument, and the caret opens on it —
283
+ // it is the part you came to this entry to type.
284
+ {
285
+ group: "Limit and log",
286
+ name: "log base",
287
+ node: funcSub("log"),
288
+ focus: ["name", 0, "sub"]
289
+ },
290
+ { group: "Limit and log", name: "log", node: func("log"), focus: ["body"] },
291
+ {
292
+ group: "Limit and log",
293
+ name: "lim",
294
+ node: limFunc("lim"),
295
+ focus: ["name", 0, "lim"]
296
+ },
297
+ {
298
+ group: "Limit and log",
299
+ name: "min",
300
+ node: limFunc("min"),
301
+ focus: ["name", 0, "lim"]
302
+ },
303
+ {
304
+ group: "Limit and log",
305
+ name: "max",
306
+ node: limFunc("max"),
307
+ focus: ["name", 0, "lim"]
308
+ },
309
+ { group: "Limit and log", name: "ln", node: func("ln"), focus: ["body"] },
265
310
  { group: "Matrix", name: "1\xD72", node: mat(1, 2), focus: ["c0"] },
266
311
  { group: "Matrix", name: "2\xD71", node: mat(2, 1), focus: ["c0"] },
267
312
  { group: "Matrix", name: "2\xD72", node: mat(2, 2), focus: ["c0"] },
@@ -330,7 +375,8 @@ function pastedImageAttrs(el) {
330
375
  width: dim(e.getAttribute("width")),
331
376
  height: dim(e.getAttribute("height")),
332
377
  crop: dataJson(el, "data-crop"),
333
- outline: dataJson(el, "data-outline")
378
+ outline: dataJson(el, "data-outline"),
379
+ effectExtent: dataJson(el, "data-effect-extent")
334
380
  };
335
381
  }
336
382
  function pastedLinkAttrs(el) {
@@ -350,8 +396,8 @@ function pastedCellAttrs(el) {
350
396
  colspan: span("colspan"),
351
397
  rowspan: span("rowspan"),
352
398
  colwidth: dataJson(el, "data-colwidth"),
353
- background: bg ? bg[1].trim() : null,
354
- vAlign: e.getAttribute("data-valign"),
399
+ background: bg ? bg[1].trim() : e.getAttribute("data-background") === "none" ? false : null,
400
+ vAlign: e.getAttribute("data-valign") === "none" ? false : e.getAttribute("data-valign"),
355
401
  borders: dataJson(el, "data-borders"),
356
402
  diagonals: dataJson(el, "data-diagonals"),
357
403
  padding: dataJson(el, "data-padding"),
@@ -381,6 +427,21 @@ var schema = new Schema({
381
427
  // CommentNode[] (contracts) — comment threads keyed to `comment` marks.
382
428
  // Edited via setDocAttribute so add/reply/resolve/delete undo cleanly.
383
429
  comments: { default: null },
430
+ // TableStyleSheet (contracts) — every table style the document's
431
+ // tables name, fully resolved (basedOn rolled up, theme colours hex).
432
+ // LIVE data, not a bake: tables carry styleId/look attrs and the
433
+ // layout applies the sheet per cell, so flipping a tblLook gate or
434
+ // switching styles is one small attr transaction. Importer-set;
435
+ // extended when the editor applies a style the sheet lacks.
436
+ tableStyles: { default: null },
437
+ // { spacing?: ParagraphSpacing } | null — the document's default
438
+ // paragraph properties (w:docDefaults/w:pPrDefault), the FLOOR of
439
+ // every paragraph's cascade. Live data like the sheet: a paragraph's
440
+ // `spacing` attr carries only what sits ABOVE the table-style slot
441
+ // (its style, numbering, direct formatting), and the layout stacks
442
+ // floor → table-style cell layer → attr. Importer-set; null for an
443
+ // editor-authored doc (whose paragraphs then carry everything).
444
+ paragraphDefaults: { default: null },
384
445
  // Per-section header/footer story OVERRIDES, keyed by section index →
385
446
  // story ('headers'|'footers') → variant ('default'|'first'|'even') →
386
447
  // the full story doc as JSON. The first chrome EDIT the model supports
@@ -420,6 +481,10 @@ var schema = new Schema({
420
481
  // w:spacing — { before?, after?, line?, lineRule?, beforeAuto?,
421
482
  // afterAuto? }, or null. The two *Auto flags record that Word computes
422
483
  // the gap itself; before/after hold what it works out to here.
484
+ // Carries the cascade ABOVE the table-style slot only (paragraph
485
+ // style, numbering, direct): the document defaults live in
486
+ // doc.attrs.paragraphDefaults and a table style's pPr in the sheet,
487
+ // and the layout stacks floor → cell layer → this attr.
423
488
  spacing: { default: null },
424
489
  // w:bookmarkStart names anchored in this paragraph (["_Toc89595219"]),
425
490
  // or null. Link hrefs of the form "#name" resolve against these —
@@ -609,6 +674,12 @@ var schema = new Schema({
609
674
  crop: { default: null },
610
675
  // a:ln on pic:spPr — Word's picture border, as a BorderSide, or null.
611
676
  outline: { default: null },
677
+ // wp:effectExtent — { l, t, r, b } in EMU, verbatim from the file, or
678
+ // null. The room Word keeps around the extent for what paints
679
+ // outside it (a picture border sits centred on the edge). Word CLIPS
680
+ // an inline picture to extent + effectExtent, so this has to survive
681
+ // a save or a framed photo loses the outer half of its top edge.
682
+ effectExtent: { default: null },
612
683
  // a:solidFill on pic:spPr — "#RRGGBB" painted behind the bitmap
613
684
  // (shows through transparency), or null.
614
685
  background: { default: null }
@@ -625,6 +696,8 @@ var schema = new Schema({
625
696
  if (a["height"] != null) attrs["height"] = String(a["height"]);
626
697
  if (a["crop"]) attrs["data-crop"] = JSON.stringify(a["crop"]);
627
698
  if (a["outline"]) attrs["data-outline"] = JSON.stringify(a["outline"]);
699
+ if (a["effectExtent"])
700
+ attrs["data-effect-extent"] = JSON.stringify(a["effectExtent"]);
628
701
  if (a["background"])
629
702
  attrs["data-background"] = a["background"];
630
703
  return ["img", attrs];
@@ -664,6 +737,14 @@ var schema = new Schema({
664
737
  // the importer). null = Word's implicit outdent by the left cell
665
738
  // margin. Importer-set; the element itself rides carry for export.
666
739
  indent: { default: null },
740
+ // w:tblStyle — the table style this table names, or null. The style's
741
+ // definition lives in doc.attrs.tableStyles; the LAYOUT applies it,
742
+ // so this attr (with `look`) is the whole apply-a-style transaction.
743
+ styleId: { default: null },
744
+ // w:tblLook — the six conditional-formatting gates (TableLook,
745
+ // contracts), or null for Word's default 04A0 (firstRow + firstCol +
746
+ // hBand on).
747
+ look: { default: null },
667
748
  // Carry-through fidelity: unmodelled w:tblPr children (tblStyle,
668
749
  // tblLayout, tblLook, tblInd, floating tblpPr, …) as one raw XML
669
750
  // string ({ tblPr: string }), or null. Importer-set; the exporter
@@ -681,6 +762,8 @@ var schema = new Schema({
681
762
  cellPadding: dataJson(el, "data-cell-padding"),
682
763
  align: el.getAttribute("data-align"),
683
764
  indent: dataJson(el, "data-indent"),
765
+ styleId: el.getAttribute("data-style-id"),
766
+ look: dataJson(el, "data-look"),
684
767
  carry: dataJson(el, "data-carry")
685
768
  })
686
769
  }
@@ -693,6 +776,8 @@ var schema = new Schema({
693
776
  dom["data-cell-padding"] = JSON.stringify(a["cellPadding"]);
694
777
  if (a["align"]) dom["data-align"] = String(a["align"]);
695
778
  if (a["indent"] != null) dom["data-indent"] = String(a["indent"]);
779
+ if (a["styleId"]) dom["data-style-id"] = String(a["styleId"]);
780
+ if (a["look"]) dom["data-look"] = JSON.stringify(a["look"]);
696
781
  if (a["carry"]) dom["data-carry"] = JSON.stringify(a["carry"]);
697
782
  return ["table", dom, ["tbody", 0]];
698
783
  }
@@ -741,10 +826,13 @@ var schema = new Schema({
741
826
  rowspan: { default: 1 },
742
827
  colwidth: { default: null },
743
828
  // px widths of the spanned columns, or null
829
+ // w:shd w:fill — cell fill "#RRGGBB". `false` is an EXPLICIT no-fill
830
+ // (w:fill="auto"), which must beat a table style's fill; null means
831
+ // the cell says nothing and the style layer may paint.
744
832
  background: { default: null },
745
- // w:shd w:fill cell fill "#RRGGBB"
833
+ // w:vAlign'center' | 'bottom' (top is Word's default). `false` is
834
+ // an explicit reset ("top"/"both" declared), beating a style's.
746
835
  vAlign: { default: null },
747
- // w:vAlign — 'center' | 'bottom' (top default)
748
836
  borders: { default: null },
749
837
  // w:tcBorders per-side visibility override
750
838
  // w:tcBorders/w:tl2br + w:br2tl — rules across the cell's corners
@@ -767,10 +855,13 @@ var schema = new Schema({
767
855
  attrs["rowspan"] = String(node.attrs["rowspan"]);
768
856
  if (node.attrs["background"])
769
857
  attrs["style"] = `background-color: ${node.attrs["background"]}`;
858
+ else if (node.attrs["background"] === false)
859
+ attrs["data-background"] = "none";
770
860
  if (node.attrs["colwidth"])
771
861
  attrs["data-colwidth"] = JSON.stringify(node.attrs["colwidth"]);
772
862
  if (node.attrs["vAlign"])
773
863
  attrs["data-valign"] = String(node.attrs["vAlign"]);
864
+ else if (node.attrs["vAlign"] === false) attrs["data-valign"] = "none";
774
865
  if (node.attrs["borders"])
775
866
  attrs["data-borders"] = JSON.stringify(node.attrs["borders"]);
776
867
  if (node.attrs["diagonals"])
@@ -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;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"}
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/lib/model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAmG3C;;;;;;;;GAQG;AACH,eAAO,MAAM,MAAM,+XA0xBjB,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.14.0",
3
+ "version": "0.16.0",
4
4
  "description": "bapbong — ProseMirror document model / schema",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -55,6 +55,6 @@
55
55
  },
56
56
  "dependencies": {
57
57
  "prosemirror-model": "^1.25.7",
58
- "@shadow-garden/bapbong-contracts": "^0.15.0"
58
+ "@shadow-garden/bapbong-contracts": "^0.17.0"
59
59
  }
60
60
  }