@shadow-garden/bapbong-model 0.11.1 → 0.12.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
@@ -87,6 +87,7 @@ function pastedParagraphAttrs(el, heading) {
87
87
  heading,
88
88
  align: m ? m[1].toLowerCase() : null,
89
89
  borders: dataJson(el, "data-borders"),
90
+ markFont: dataJson(el, "data-mark-font"),
90
91
  carry: dataJson(el, "data-carry")
91
92
  };
92
93
  }
@@ -101,6 +102,7 @@ function pastedImageAttrs(el) {
101
102
  return {
102
103
  src,
103
104
  alt: e.getAttribute("alt") ?? "",
105
+ title: e.getAttribute("title"),
104
106
  width: dim(e.getAttribute("width")),
105
107
  height: dim(e.getAttribute("height")),
106
108
  crop: dataJson(el, "data-crop"),
@@ -147,6 +149,11 @@ var schema = new import_prosemirror_model.Schema({
147
149
  // body w:sectPr. Edited via setDocAttribute (page-setup commands) so
148
150
  // orientation/paper-size changes undo cleanly. null → A4 default.
149
151
  page: { default: null },
152
+ // DocCompat (contracts) — the Word compatibility profile settings.xml
153
+ // declares (compatibilityMode + the compat flags), resolved to the
154
+ // answers layout rules ask. Importer-set on every story doc; null
155
+ // (an editor-authored doc) reads as current Word.
156
+ compat: { default: null },
150
157
  // CommentNode[] (contracts) — comment threads keyed to `comment` marks.
151
158
  // Edited via setDocAttribute so add/reply/resolve/delete undo cleanly.
152
159
  comments: { default: null },
@@ -220,6 +227,15 @@ var schema = new import_prosemirror_model.Schema({
220
227
  // null). Painted behind the paragraph's lines, in the same box the
221
228
  // borders use.
222
229
  shading: { default: null },
230
+ // The paragraph MARK's own font ({ family?, sizePt?, bold?, italic? }
231
+ // or null) — w:pPr/w:rPr resolved through the same cascade a run gets.
232
+ // The mark is a glyph on the paragraph's LAST line (the only glyph
233
+ // when the paragraph is empty), so it takes part in that line's
234
+ // height. Importer-set on every paragraph; the font commands edit it
235
+ // when the selection takes the mark in (Word: a ¶ inside the
236
+ // selection is re-sized with the text); the exporter writes it back
237
+ // into w:pPr/w:rPr ahead of `carry.markRPr` (the rest of that rPr).
238
+ markFont: { default: null },
223
239
  // Carry-through fidelity (docx round-trip): OOXML paragraph
224
240
  // properties the model does NOT represent, preserved verbatim so a
225
241
  // customer's save never drops them. { pPr?: string, markRPr?: string }
@@ -247,6 +263,8 @@ var schema = new import_prosemirror_model.Schema({
247
263
  dom["data-borders"] = JSON.stringify(node.attrs["borders"]);
248
264
  if (node.attrs["shading"])
249
265
  dom["data-shading"] = String(node.attrs["shading"]);
266
+ if (node.attrs["markFont"])
267
+ dom["data-mark-font"] = JSON.stringify(node.attrs["markFont"]);
250
268
  if (node.attrs["carry"])
251
269
  dom["data-carry"] = JSON.stringify(node.attrs["carry"]);
252
270
  return [tag, dom, 0];
@@ -283,6 +301,9 @@ var schema = new import_prosemirror_model.Schema({
283
301
  attrs: {
284
302
  src: {},
285
303
  alt: { default: "" },
304
+ // wp:docPr @title — the "Title" field of Word's alt-text pane, kept
305
+ // separate from `alt` (@descr) so both round-trip verbatim.
306
+ title: { default: null },
286
307
  width: { default: null },
287
308
  height: { default: null },
288
309
  // wp:anchor (floating image): { wrap: 'square'|'topAndBottom'|'none',
@@ -306,7 +327,10 @@ var schema = new import_prosemirror_model.Schema({
306
327
  // keeps its size; the selected region scales to fill it.
307
328
  crop: { default: null },
308
329
  // a:ln on pic:spPr — Word's picture border, as a BorderSide, or null.
309
- outline: { default: null }
330
+ outline: { default: null },
331
+ // a:solidFill on pic:spPr — "#RRGGBB" painted behind the bitmap
332
+ // (shows through transparency), or null.
333
+ background: { default: null }
310
334
  },
311
335
  parseDOM: [{ tag: "img[src]", getAttrs: pastedImageAttrs }],
312
336
  toDOM(node) {
@@ -315,10 +339,13 @@ var schema = new import_prosemirror_model.Schema({
315
339
  src: a["src"],
316
340
  alt: a["alt"]
317
341
  };
342
+ if (a["title"]) attrs["title"] = a["title"];
318
343
  if (a["width"] != null) attrs["width"] = String(a["width"]);
319
344
  if (a["height"] != null) attrs["height"] = String(a["height"]);
320
345
  if (a["crop"]) attrs["data-crop"] = JSON.stringify(a["crop"]);
321
346
  if (a["outline"]) attrs["data-outline"] = JSON.stringify(a["outline"]);
347
+ if (a["background"])
348
+ attrs["data-background"] = a["background"];
322
349
  return ["img", attrs];
323
350
  }
324
351
  },
@@ -351,6 +378,11 @@ var schema = new import_prosemirror_model.Schema({
351
378
  borders: { default: null },
352
379
  // w:tblPr/w:jc — 'center' | 'right' table alignment, or null (left).
353
380
  align: { default: null },
381
+ // w:tblInd resolved to px: where a left-aligned table's leading
382
+ // border sits relative to the text margin (compat-mode aware — see
383
+ // the importer). null = Word's implicit outdent by the left cell
384
+ // margin. Importer-set; the element itself rides carry for export.
385
+ indent: { default: null },
354
386
  // Carry-through fidelity: unmodelled w:tblPr children (tblStyle,
355
387
  // tblLayout, tblLook, tblInd, floating tblpPr, …) as one raw XML
356
388
  // string ({ tblPr: string }), or null. Importer-set; the exporter
@@ -367,6 +399,7 @@ var schema = new import_prosemirror_model.Schema({
367
399
  borders: dataJson(el, "data-borders"),
368
400
  cellPadding: dataJson(el, "data-cell-padding"),
369
401
  align: el.getAttribute("data-align"),
402
+ indent: dataJson(el, "data-indent"),
370
403
  carry: dataJson(el, "data-carry")
371
404
  })
372
405
  }
@@ -378,6 +411,7 @@ var schema = new import_prosemirror_model.Schema({
378
411
  if (a["cellPadding"])
379
412
  dom["data-cell-padding"] = JSON.stringify(a["cellPadding"]);
380
413
  if (a["align"]) dom["data-align"] = String(a["align"]);
414
+ if (a["indent"] != null) dom["data-indent"] = String(a["indent"]);
381
415
  if (a["carry"]) dom["data-carry"] = JSON.stringify(a["carry"]);
382
416
  return ["table", dom, ["tbody", 0]];
383
417
  }
@@ -703,27 +737,37 @@ var schema = new import_prosemirror_model.Schema({
703
737
  },
704
738
  // w:footnoteReference — the carrier text is the superscript number; `num`
705
739
  // lets the layout engine match the reference to its page-bottom body.
740
+ // `id` is the ORIGINAL w:id from footnotes.xml: that part is carried
741
+ // byte-for-byte on save, so the exported reference must point at the
742
+ // source id, not the display number (Word reserves -1/0 and reuses ids
743
+ // freely — they rarely equal 1..N in document order).
706
744
  footnote: {
707
- attrs: { num: {} },
745
+ attrs: { num: {}, id: { default: null } },
708
746
  inclusive: false,
709
747
  parseDOM: [
710
748
  {
711
749
  tag: "sup[data-footnote]",
712
750
  // `el` is an HTMLElement at runtime; this package has no DOM lib, so
713
751
  // narrow structurally rather than naming the type.
714
- getAttrs: (el) => ({
715
- num: Number(
716
- el.getAttribute(
717
- "data-footnote"
718
- )
719
- ) || 0
720
- })
752
+ getAttrs: (el) => {
753
+ const get = (n) => el.getAttribute(
754
+ n
755
+ );
756
+ return {
757
+ num: Number(get("data-footnote")) || 0,
758
+ id: get("data-footnote-id")
759
+ };
760
+ }
721
761
  }
722
762
  ],
723
763
  toDOM(mark) {
764
+ const id = mark.attrs["id"];
724
765
  return [
725
766
  "sup",
726
- { "data-footnote": String(mark.attrs["num"]) },
767
+ {
768
+ "data-footnote": String(mark.attrs["num"]),
769
+ ...id != null ? { "data-footnote-id": id } : {}
770
+ },
727
771
  0
728
772
  ];
729
773
  }
package/dist/index.js CHANGED
@@ -55,6 +55,7 @@ function pastedParagraphAttrs(el, heading) {
55
55
  heading,
56
56
  align: m ? m[1].toLowerCase() : null,
57
57
  borders: dataJson(el, "data-borders"),
58
+ markFont: dataJson(el, "data-mark-font"),
58
59
  carry: dataJson(el, "data-carry")
59
60
  };
60
61
  }
@@ -69,6 +70,7 @@ function pastedImageAttrs(el) {
69
70
  return {
70
71
  src,
71
72
  alt: e.getAttribute("alt") ?? "",
73
+ title: e.getAttribute("title"),
72
74
  width: dim(e.getAttribute("width")),
73
75
  height: dim(e.getAttribute("height")),
74
76
  crop: dataJson(el, "data-crop"),
@@ -115,6 +117,11 @@ var schema = new Schema({
115
117
  // body w:sectPr. Edited via setDocAttribute (page-setup commands) so
116
118
  // orientation/paper-size changes undo cleanly. null → A4 default.
117
119
  page: { default: null },
120
+ // DocCompat (contracts) — the Word compatibility profile settings.xml
121
+ // declares (compatibilityMode + the compat flags), resolved to the
122
+ // answers layout rules ask. Importer-set on every story doc; null
123
+ // (an editor-authored doc) reads as current Word.
124
+ compat: { default: null },
118
125
  // CommentNode[] (contracts) — comment threads keyed to `comment` marks.
119
126
  // Edited via setDocAttribute so add/reply/resolve/delete undo cleanly.
120
127
  comments: { default: null },
@@ -188,6 +195,15 @@ var schema = new Schema({
188
195
  // null). Painted behind the paragraph's lines, in the same box the
189
196
  // borders use.
190
197
  shading: { default: null },
198
+ // The paragraph MARK's own font ({ family?, sizePt?, bold?, italic? }
199
+ // or null) — w:pPr/w:rPr resolved through the same cascade a run gets.
200
+ // The mark is a glyph on the paragraph's LAST line (the only glyph
201
+ // when the paragraph is empty), so it takes part in that line's
202
+ // height. Importer-set on every paragraph; the font commands edit it
203
+ // when the selection takes the mark in (Word: a ¶ inside the
204
+ // selection is re-sized with the text); the exporter writes it back
205
+ // into w:pPr/w:rPr ahead of `carry.markRPr` (the rest of that rPr).
206
+ markFont: { default: null },
191
207
  // Carry-through fidelity (docx round-trip): OOXML paragraph
192
208
  // properties the model does NOT represent, preserved verbatim so a
193
209
  // customer's save never drops them. { pPr?: string, markRPr?: string }
@@ -215,6 +231,8 @@ var schema = new Schema({
215
231
  dom["data-borders"] = JSON.stringify(node.attrs["borders"]);
216
232
  if (node.attrs["shading"])
217
233
  dom["data-shading"] = String(node.attrs["shading"]);
234
+ if (node.attrs["markFont"])
235
+ dom["data-mark-font"] = JSON.stringify(node.attrs["markFont"]);
218
236
  if (node.attrs["carry"])
219
237
  dom["data-carry"] = JSON.stringify(node.attrs["carry"]);
220
238
  return [tag, dom, 0];
@@ -251,6 +269,9 @@ var schema = new Schema({
251
269
  attrs: {
252
270
  src: {},
253
271
  alt: { default: "" },
272
+ // wp:docPr @title — the "Title" field of Word's alt-text pane, kept
273
+ // separate from `alt` (@descr) so both round-trip verbatim.
274
+ title: { default: null },
254
275
  width: { default: null },
255
276
  height: { default: null },
256
277
  // wp:anchor (floating image): { wrap: 'square'|'topAndBottom'|'none',
@@ -274,7 +295,10 @@ var schema = new Schema({
274
295
  // keeps its size; the selected region scales to fill it.
275
296
  crop: { default: null },
276
297
  // a:ln on pic:spPr — Word's picture border, as a BorderSide, or null.
277
- outline: { default: null }
298
+ outline: { default: null },
299
+ // a:solidFill on pic:spPr — "#RRGGBB" painted behind the bitmap
300
+ // (shows through transparency), or null.
301
+ background: { default: null }
278
302
  },
279
303
  parseDOM: [{ tag: "img[src]", getAttrs: pastedImageAttrs }],
280
304
  toDOM(node) {
@@ -283,10 +307,13 @@ var schema = new Schema({
283
307
  src: a["src"],
284
308
  alt: a["alt"]
285
309
  };
310
+ if (a["title"]) attrs["title"] = a["title"];
286
311
  if (a["width"] != null) attrs["width"] = String(a["width"]);
287
312
  if (a["height"] != null) attrs["height"] = String(a["height"]);
288
313
  if (a["crop"]) attrs["data-crop"] = JSON.stringify(a["crop"]);
289
314
  if (a["outline"]) attrs["data-outline"] = JSON.stringify(a["outline"]);
315
+ if (a["background"])
316
+ attrs["data-background"] = a["background"];
290
317
  return ["img", attrs];
291
318
  }
292
319
  },
@@ -319,6 +346,11 @@ var schema = new Schema({
319
346
  borders: { default: null },
320
347
  // w:tblPr/w:jc — 'center' | 'right' table alignment, or null (left).
321
348
  align: { default: null },
349
+ // w:tblInd resolved to px: where a left-aligned table's leading
350
+ // border sits relative to the text margin (compat-mode aware — see
351
+ // the importer). null = Word's implicit outdent by the left cell
352
+ // margin. Importer-set; the element itself rides carry for export.
353
+ indent: { default: null },
322
354
  // Carry-through fidelity: unmodelled w:tblPr children (tblStyle,
323
355
  // tblLayout, tblLook, tblInd, floating tblpPr, …) as one raw XML
324
356
  // string ({ tblPr: string }), or null. Importer-set; the exporter
@@ -335,6 +367,7 @@ var schema = new Schema({
335
367
  borders: dataJson(el, "data-borders"),
336
368
  cellPadding: dataJson(el, "data-cell-padding"),
337
369
  align: el.getAttribute("data-align"),
370
+ indent: dataJson(el, "data-indent"),
338
371
  carry: dataJson(el, "data-carry")
339
372
  })
340
373
  }
@@ -346,6 +379,7 @@ var schema = new Schema({
346
379
  if (a["cellPadding"])
347
380
  dom["data-cell-padding"] = JSON.stringify(a["cellPadding"]);
348
381
  if (a["align"]) dom["data-align"] = String(a["align"]);
382
+ if (a["indent"] != null) dom["data-indent"] = String(a["indent"]);
349
383
  if (a["carry"]) dom["data-carry"] = JSON.stringify(a["carry"]);
350
384
  return ["table", dom, ["tbody", 0]];
351
385
  }
@@ -671,27 +705,37 @@ var schema = new Schema({
671
705
  },
672
706
  // w:footnoteReference — the carrier text is the superscript number; `num`
673
707
  // lets the layout engine match the reference to its page-bottom body.
708
+ // `id` is the ORIGINAL w:id from footnotes.xml: that part is carried
709
+ // byte-for-byte on save, so the exported reference must point at the
710
+ // source id, not the display number (Word reserves -1/0 and reuses ids
711
+ // freely — they rarely equal 1..N in document order).
674
712
  footnote: {
675
- attrs: { num: {} },
713
+ attrs: { num: {}, id: { default: null } },
676
714
  inclusive: false,
677
715
  parseDOM: [
678
716
  {
679
717
  tag: "sup[data-footnote]",
680
718
  // `el` is an HTMLElement at runtime; this package has no DOM lib, so
681
719
  // narrow structurally rather than naming the type.
682
- getAttrs: (el) => ({
683
- num: Number(
684
- el.getAttribute(
685
- "data-footnote"
686
- )
687
- ) || 0
688
- })
720
+ getAttrs: (el) => {
721
+ const get = (n) => el.getAttribute(
722
+ n
723
+ );
724
+ return {
725
+ num: Number(get("data-footnote")) || 0,
726
+ id: get("data-footnote-id")
727
+ };
728
+ }
689
729
  }
690
730
  ],
691
731
  toDOM(mark) {
732
+ const id = mark.attrs["id"];
692
733
  return [
693
734
  "sup",
694
- { "data-footnote": String(mark.attrs["num"]) },
735
+ {
736
+ "data-footnote": String(mark.attrs["num"]),
737
+ ...id != null ? { "data-footnote-id": id } : {}
738
+ },
695
739
  0
696
740
  ];
697
741
  }
@@ -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;AAwF3C;;;;;;;;GAQG;AACH,eAAO,MAAM,MAAM,yWA8nBjB,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;AA0F3C;;;;;;;;GAQG;AACH,eAAO,MAAM,MAAM,yWAwqBjB,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.11.1",
3
+ "version": "0.12.0",
4
4
  "description": "bapbong — ProseMirror document model / schema",
5
5
  "license": "MIT",
6
6
  "repository": {