@shbernal/ts-pptx 3.0.0 → 3.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.
Files changed (74) hide show
  1. package/README.md +60 -0
  2. package/dist/{autopage-MxulehqQ.js → autopage-QQyfRtoK.js} +3 -3
  3. package/dist/{autopage-MxulehqQ.js.map → autopage-QQyfRtoK.js.map} +1 -1
  4. package/dist/browser.d.ts +5 -5
  5. package/dist/browser.d.ts.map +1 -1
  6. package/dist/browser.js +5 -5
  7. package/dist/{diagnostics-BqBTmA3a.d.ts → diagnostics-Chjz_4_Q.d.ts} +7 -7
  8. package/dist/{diagnostics-BqBTmA3a.d.ts.map → diagnostics-Chjz_4_Q.d.ts.map} +1 -1
  9. package/dist/{enums-oLLeaSW3.d.ts → enums-CoXnxiCI.d.ts} +5 -5
  10. package/dist/{enums-oLLeaSW3.d.ts.map → enums-CoXnxiCI.d.ts.map} +1 -1
  11. package/dist/{errors-BENA-Xuw.d.ts → errors-BVLCFr-t.d.ts} +25 -3
  12. package/dist/errors-BVLCFr-t.d.ts.map +1 -0
  13. package/dist/{errors-DGE9zh3U.js → errors-Bvln0H-7.js} +21 -2
  14. package/dist/errors-Bvln0H-7.js.map +1 -0
  15. package/dist/{fit-DGSwMMNs.js → fit-DhMbQG5O.js} +0 -0
  16. package/dist/fit-DhMbQG5O.js.map +1 -0
  17. package/dist/{html-dom--J-Xuucf.js → html-dom-DajBuobe.js} +5 -5
  18. package/dist/html-dom-DajBuobe.js.map +1 -0
  19. package/dist/html.d.ts +3 -3
  20. package/dist/html.js +2 -2
  21. package/dist/index.d.ts +5 -5
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +5 -5
  24. package/dist/inspect.d.ts +1 -1
  25. package/dist/inspect.js +4 -4
  26. package/dist/math.d.ts +1 -1
  27. package/dist/math.d.ts.map +1 -1
  28. package/dist/math.js +98 -2
  29. package/dist/math.js.map +1 -1
  30. package/dist/measure.d.ts +3 -3
  31. package/dist/measure.js +2 -2
  32. package/dist/node.d.ts +5 -5
  33. package/dist/node.d.ts.map +1 -1
  34. package/dist/node.js +4 -4
  35. package/dist/package-CaOLXSNi.d.ts.map +1 -1
  36. package/dist/{pres-2WsBGimU.d.ts → pres-C-EU3SkN.d.ts} +3 -3
  37. package/dist/{pres-2WsBGimU.d.ts.map → pres-C-EU3SkN.d.ts.map} +1 -1
  38. package/dist/{presentation-DAcOfzsP.js → presentation-CxnUVhK9.js} +103 -27
  39. package/dist/presentation-CxnUVhK9.js.map +1 -0
  40. package/dist/{presentation-CTVPpiwP.d.ts → presentation-Osx1cDdJ.d.ts} +161 -46
  41. package/dist/presentation-Osx1cDdJ.d.ts.map +1 -0
  42. package/dist/{presentation-types-BVw0EknS.d.ts → presentation-types-Dj4riuDs.d.ts} +2 -2
  43. package/dist/{presentation-types-BVw0EknS.d.ts.map → presentation-types-Dj4riuDs.d.ts.map} +1 -1
  44. package/dist/read.d.ts +5 -5
  45. package/dist/read.js +3 -3
  46. package/dist/script.d.ts +32 -4
  47. package/dist/script.d.ts.map +1 -1
  48. package/dist/script.js +0 -0
  49. package/dist/script.js.map +1 -1
  50. package/dist/{shapes-BWifcHDV.js → shapes-DoJBPrwN.js} +104 -65
  51. package/dist/shapes-DoJBPrwN.js.map +1 -0
  52. package/dist/{slide-YuSCGa45.d.ts → slide-BTfn1Pyp.d.ts} +99 -16
  53. package/dist/slide-BTfn1Pyp.d.ts.map +1 -0
  54. package/dist/{st-enums-CgadEyPM.js → st-enums-evQG2A7Z.js} +2 -2
  55. package/dist/{st-enums-CgadEyPM.js.map → st-enums-evQG2A7Z.js.map} +1 -1
  56. package/dist/{text-120VFSDm.js → text-C4P9MNdf.js} +168 -85
  57. package/dist/text-C4P9MNdf.js.map +1 -0
  58. package/dist/{units-B-JUKwCS.js → units-C7QM1KgH.js} +2 -2
  59. package/dist/{units-B-JUKwCS.js.map → units-C7QM1KgH.js.map} +1 -1
  60. package/dist/{units-internal-CiFWZWk4.js → units-internal-CR8s8YQa.js} +3 -3
  61. package/dist/{units-internal-CiFWZWk4.js.map → units-internal-CR8s8YQa.js.map} +1 -1
  62. package/dist/zip.d.ts +2 -2
  63. package/dist/zip.js +1 -1
  64. package/package.json +18 -17
  65. package/skills/ts-pptx-upstream/SKILL.md +340 -0
  66. package/dist/errors-BENA-Xuw.d.ts.map +0 -1
  67. package/dist/errors-DGE9zh3U.js.map +0 -1
  68. package/dist/fit-DGSwMMNs.js.map +0 -1
  69. package/dist/html-dom--J-Xuucf.js.map +0 -1
  70. package/dist/presentation-CTVPpiwP.d.ts.map +0 -1
  71. package/dist/presentation-DAcOfzsP.js.map +0 -1
  72. package/dist/shapes-BWifcHDV.js.map +0 -1
  73. package/dist/slide-YuSCGa45.d.ts.map +0 -1
  74. package/dist/text-120VFSDm.js.map +0 -1
@@ -1,10 +1,10 @@
1
1
  import { n as warn, r as warnOnce } from "./diagnostics-DYQC7xLV.js";
2
- import { n as InvalidOptionError, o as UnsupportedFeatureError, r as MediaError, t as InternalError } from "./errors-DGE9zh3U.js";
3
- import { a as FIXED_PCT_PER_PERCENT, d as emuToInches, g as pixelsToEmu, i as EMU_PER_POINT, l as STANDARD_LAYOUTS, m as inchesToEmu, r as EMU_PER_INCH, s as PERCENT_SCALE, t as ANGLE_UNITS_PER_DEGREE, v as ptToHundredths } from "./units-B-JUKwCS.js";
4
- import { $ as connectorPresetFor, C as DEF_PRES_LAYOUT_NAME, D as DEF_TEXT_GLOW, E as DEF_SLIDE_MARGIN_IN, F as PIECHART_COLORS, G as PlaceholderType, I as REGEX_HEX_COLOR, K as SchemeColor, L as SLDNUMFLDID, M as LAYOUT_IDX_SERIES_BASE, N as LETTERS, O as DEF_TEXT_SHADOW, Q as asChartType, R as XML_DECL, S as DEF_PRES_LAYOUT, T as DEF_SHAPE_SHADOW, Z as VALID_SHAPE_PRESETS, _ as DEF_CELL_BORDER, a as lineWidthToEmu, b as DEF_CHART_GRIDLINE, c as resolveTableColWidthsEmu, d as AXIS_ID_CATEGORY_PRIMARY, et as isChartExType, f as AXIS_ID_CATEGORY_SECONDARY, g as BARCHART_COLORS, h as AXIS_ID_VALUE_SECONDARY, i as inch2Emu, k as IMG_BROKEN, l as transparencyToAlpha, m as AXIS_ID_VALUE_PRIMARY, n as convertRotationDegrees, o as marginToEmu, p as AXIS_ID_SERIES_PRIMARY, r as getSmartParseNumber, s as opacityToAlpha, t as convertArcAngle, u as valToPts, v as DEF_CELL_MARGIN_IN, x as DEF_FONT_COLOR, y as DEF_CHART_BORDER } from "./units-internal-CiFWZWk4.js";
5
- import { E as svgMarkupToDataUri, S as getImageSizeFromBase64, T as decodeBase64ToBytes, a as PRESET_MATERIALS, g as PACKAGE_REL_NS, h as OFFICE_REL, i as PRESET_LINE_DASHES, n as LIGHT_RIGS, r as LIGHT_RIG_DIRECTIONS, s as TEXT_HORZ_OVERFLOW, t as BEVEL_PRESETS, u as checkEnumOrWarn, x as fitSrcRectPercents } from "./st-enums-CgadEyPM.js";
6
- import { t as getSlidesForTableRows } from "./autopage-MxulehqQ.js";
7
- import { _ as parseFontMetrics, m as FontMetricsRegistry, n as measureText, r as computeTableLayout, t as applyMeasuredFit } from "./fit-DGSwMMNs.js";
2
+ import { n as InvalidOptionError, o as UnsupportedFeatureError, r as MediaError, t as InternalError } from "./errors-Bvln0H-7.js";
3
+ import { a as FIXED_PCT_PER_PERCENT, d as emuToInches, g as pixelsToEmu, i as EMU_PER_POINT, l as STANDARD_LAYOUTS, m as inchesToEmu, r as EMU_PER_INCH, s as PERCENT_SCALE, t as ANGLE_UNITS_PER_DEGREE, v as ptToHundredths } from "./units-C7QM1KgH.js";
4
+ import { $ as connectorPresetFor, C as DEF_PRES_LAYOUT_NAME, D as DEF_TEXT_GLOW, E as DEF_SLIDE_MARGIN_IN, F as PIECHART_COLORS, G as PlaceholderType, I as REGEX_HEX_COLOR, K as SchemeColor, L as SLDNUMFLDID, M as LAYOUT_IDX_SERIES_BASE, N as LETTERS, O as DEF_TEXT_SHADOW, Q as asChartType, R as XML_DECL, S as DEF_PRES_LAYOUT, T as DEF_SHAPE_SHADOW, Z as VALID_SHAPE_PRESETS, _ as DEF_CELL_BORDER, a as lineWidthToEmu, b as DEF_CHART_GRIDLINE, c as resolveTableColWidthsEmu, d as AXIS_ID_CATEGORY_PRIMARY, et as isChartExType, f as AXIS_ID_CATEGORY_SECONDARY, g as BARCHART_COLORS, h as AXIS_ID_VALUE_SECONDARY, i as inch2Emu, k as IMG_BROKEN, l as transparencyToAlpha, m as AXIS_ID_VALUE_PRIMARY, n as convertRotationDegrees, o as marginToEmu, p as AXIS_ID_SERIES_PRIMARY, r as getSmartParseNumber, s as opacityToAlpha, t as convertArcAngle, u as valToPts, v as DEF_CELL_MARGIN_IN, x as DEF_FONT_COLOR, y as DEF_CHART_BORDER } from "./units-internal-CR8s8YQa.js";
5
+ import { E as svgMarkupToDataUri, S as getImageSizeFromBase64, T as decodeBase64ToBytes, a as PRESET_MATERIALS, g as PACKAGE_REL_NS, h as OFFICE_REL, i as PRESET_LINE_DASHES, n as LIGHT_RIGS, r as LIGHT_RIG_DIRECTIONS, s as TEXT_HORZ_OVERFLOW, t as BEVEL_PRESETS, u as checkEnumOrWarn, x as fitSrcRectPercents } from "./st-enums-evQG2A7Z.js";
6
+ import { t as getSlidesForTableRows } from "./autopage-QQyfRtoK.js";
7
+ import { _ as parseFontMetrics, m as FontMetricsRegistry, n as measureText, r as computeTableLayout, t as applyMeasuredFit } from "./fit-DhMbQG5O.js";
8
8
  import { a as flattenEmbeddedFaces, i as FONT_REL_TYPE, n as FONT_DATA_CONTENT_TYPE, o as serializeEmbeddedFontLst, r as FONT_DATA_EXTENSION, t as EMBEDDED_FONT_SLOTS } from "./embedded-fonts-MaynAHa9.js";
9
9
  import { ZipWriter } from "./zip.js";
10
10
  //#region src/media/content-type.ts
@@ -2332,7 +2332,7 @@ function applyTableHeaderColumnSugar(tableRows, opt) {
2332
2332
  options: {}
2333
2333
  } : {
2334
2334
  ...cell,
2335
- options: { ...cell.options || {} }
2335
+ options: { ...cell.options }
2336
2336
  };
2337
2337
  const colDef = cols ? cols[colCursor] : void 0;
2338
2338
  colCursor += cellObj.options?.colspan || 1;
@@ -3205,6 +3205,12 @@ function genXmlColorSelection(props) {
3205
3205
  internalElements += alphaFromTransparency(props.transparency);
3206
3206
  }
3207
3207
  switch (fillType) {
3208
+ case "none":
3209
+ outText += voidEl("a:noFill");
3210
+ break;
3211
+ case "inherit":
3212
+ outText += "";
3213
+ break;
3208
3214
  case "solid":
3209
3215
  outText += el("a:solidFill", null, raw(createColorElement(colorVal, internalElements)));
3210
3216
  break;
@@ -4822,6 +4828,27 @@ function makeSurfaceScene(opts) {
4822
4828
  * {@link ./data-refs}.
4823
4829
  */
4824
4830
  /**
4831
+ * Whether a chart-area/plot-area `fill` says anything the fill dispatch can act on.
4832
+ *
4833
+ * `c:spPr` is `a:CT_ShapeProperties` — the same optional `EG_FillProperties` group the
4834
+ * shape path writes into — so gradient, pattern and an omitted fill child are all legal
4835
+ * here. The gate used to be `fill?.color`, which meant every spelling carrying no colour
4836
+ * (`gradient`, `pattern`, `image`, `inherit`) fell to the no-fill arm and did nothing.
4837
+ *
4838
+ * The gate cannot simply be `fill != null`. `normalizeChartOptions` defaults
4839
+ * `plotArea.fill` to `{}`, so every chart in existence arrives here with a fill object,
4840
+ * and a presence check would paint each one a default grey. The same is true of the one
4841
+ * input a caller can write by hand: `{ transparency: 50 }` alone is not a fill, since
4842
+ * there is no colour for the alpha to apply to. Both stay no-fill.
4843
+ *
4844
+ * A payload with no `type` (`{ gradient }`, `{ pattern }`) is likewise not stated, which
4845
+ * matches the shape path: only `line` infers its type from a bare `gradient`, fills have
4846
+ * always wanted `type: 'gradient'` spelled out.
4847
+ */
4848
+ function isStatedFill(fill) {
4849
+ return Boolean(fill?.color || fill?.type);
4850
+ }
4851
+ /**
4825
4852
  * Build the chartSpace/chart header: chartSpace open, title (or autoTitleDeleted),
4826
4853
  * optional 3D view, and the plotArea open with optional manual layout.
4827
4854
  */
@@ -4977,7 +5004,7 @@ function makeChartPlotAreaPropsXml(rel) {
4977
5004
  strXml += "</c:dTable>";
4978
5005
  }
4979
5006
  strXml += " <c:spPr>";
4980
- strXml += plotArea.fill?.color ? genXmlColorSelection(plotArea.fill) : "<a:noFill/>";
5007
+ strXml += isStatedFill(plotArea.fill) ? genXmlColorSelection(plotArea.fill) : "<a:noFill/>";
4981
5008
  strXml += plotArea.border ? `<a:ln w="${valToPts(resolveBorderWidth(plotArea.border, 1))}" cap="flat">${genXmlColorSelection({
4982
5009
  color: plotArea.border.color ?? "363636",
4983
5010
  transparency: plotArea.border.transparency
@@ -5076,7 +5103,7 @@ function makeXmlCharts(rel) {
5076
5103
  if (rel.opts._type === "scatter") strXml += "<c:showDLblsOverMax val=\"1\"/>";
5077
5104
  strXml += "</c:chart>";
5078
5105
  strXml += "<c:spPr>";
5079
- strXml += chartArea.fill?.color ? genXmlColorSelection(chartArea.fill) : "<a:noFill/>";
5106
+ strXml += isStatedFill(chartArea.fill) ? genXmlColorSelection(chartArea.fill) : "<a:noFill/>";
5080
5107
  strXml += chartArea.border ? `<a:ln w="${valToPts(resolveBorderWidth(chartArea.border, 1))}" cap="flat">${genXmlColorSelection({
5081
5108
  color: chartArea.border.color ?? "363636",
5082
5109
  transparency: chartArea.border.transparency
@@ -5939,7 +5966,7 @@ function bakeSlideContent(slides, fontMetrics) {
5939
5966
  * This **mirrors** the allocation in `slideObjectToXml`, which hands out ids as it walks the tree.
5940
5967
  * A reference that must name an id *before* the walk reaches it — a connector's `<a:stCxn>`, an
5941
5968
  * animation's `<p:spTgt spid>` — cannot wait for that, so it resolves through this map instead.
5942
- * The two must stay in step: `test/regression/group-shapes.test.js` parses the emitted `cNvPr` ids
5969
+ * The two must stay in step: `test/regression/shape/group-shapes.test.js` parses the emitted `cNvPr` ids
5943
5970
  * back out and asserts each reference points at the shape it names, so drift fails there.
5944
5971
  * @param slideObjects - the slide's top-level objects
5945
5972
  * @returns each object's `<p:cNvPr>` id, keyed by object identity, in id order
@@ -6393,6 +6420,28 @@ function clampCharSpacingSpc(charSpacingPts) {
6393
6420
  if (clamped !== raw) warnOnce("text/char-spacing-out-of-range", `charSpacing ${charSpacingPts} is outside the valid range -4000..4000pt; using ${clamped / 100}.`);
6394
6421
  return clamped;
6395
6422
  }
6423
+ /**
6424
+ * Clamp a paragraph's left margin (points) into ST_TextMargin (0..4032pt, i.e. 0..51206400 EMU);
6425
+ * returns EMU for `a:pPr/@marL`. The type is unsigned — a negative margin is not a narrower one,
6426
+ * it is a value PowerPoint reports as needing repair.
6427
+ */
6428
+ function clampParaMarginEmu(marginPts) {
6429
+ const raw = valToPts(marginPts);
6430
+ const clamped = Math.min(51206400, Math.max(0, raw));
6431
+ if (clamped !== raw) warnOnce("text/paragraph-margin-out-of-range", `paraMarginLeft ${marginPts} is outside the valid range 0-4032pt; using ${clamped / EMU_PER_POINT}.`);
6432
+ return clamped;
6433
+ }
6434
+ /**
6435
+ * Clamp a first-line indent (points) into ST_TextIndent (-4032..4032pt); returns EMU for
6436
+ * `a:pPr/@indent`. Unlike the margin this one is signed: a negative indent is the hanging
6437
+ * indent every bulleted paragraph uses.
6438
+ */
6439
+ function clampParaIndentEmu(indentPts) {
6440
+ const raw = valToPts(indentPts);
6441
+ const clamped = Math.min(51206400, Math.max(-51206400, raw));
6442
+ if (clamped !== raw) warnOnce("text/paragraph-indent-out-of-range", `paraIndent ${indentPts} is outside the valid range -4032..4032pt; using ${clamped / EMU_PER_POINT}.`);
6443
+ return clamped;
6444
+ }
6396
6445
  /** Clamp line spacing (points) into ST_TextSpacingPoint (0..1584pt); returns hundredths for `<a:spcPts val>`. */
6397
6446
  function clampLineSpacingPts(lineSpacingPts) {
6398
6447
  const raw = ptToHundredths(lineSpacingPts);
@@ -6620,6 +6669,37 @@ const HLINK_TEXT_COLOR_EXT = el("a:extLst", null, raw(el("a:ext", { uri: "{A12FA
6620
6669
  closePrefix: " "
6621
6670
  });
6622
6671
  /**
6672
+ * Whether a `bullet` value makes the paragraph DRAW a bullet (a glyph, a number or a picture).
6673
+ *
6674
+ * Two call sites downstream of the emitter act on "this paragraph has a bullet" rather than on
6675
+ * "this paragraph says something about its bullet", and both were plain truthiness tests until
6676
+ * `'inherit'` — a truthy string that draws nothing — joined the union. Left as truthiness they
6677
+ * would have broken the line grouping (every run starting its own paragraph) and eaten a real
6678
+ * leading `•` from text that emits no `a:buChar` to duplicate it.
6679
+ * @param {TextPropsOptions['bullet']} bullet - the option value
6680
+ * @return {boolean} true when bullet markup is emitted
6681
+ */
6682
+ function emitsBulletMarkup(bullet) {
6683
+ return !!bullet && bullet !== "inherit";
6684
+ }
6685
+ /**
6686
+ * One paragraph margin attribute's value in EMU, or `null` when the attribute is not written.
6687
+ *
6688
+ * Three inputs, because the option has three states and so does the attribute: an explicit
6689
+ * number is clamped and written, `'inherit'` writes nothing, and an absent option falls back to
6690
+ * whatever the `bullet` arm decided — which is also `null` for `bullet: 'inherit'`, the one arm
6691
+ * that states nothing on its own.
6692
+ * @param {number|'inherit'|undefined} option - `paraMarginLeft` / `paraIndent` as given
6693
+ * @param {number|null} fallbackEmu - the bullet arm's default, `null` for no attribute
6694
+ * @param {Function} clamp - the attribute's ST_* range clamp (points in, EMU out)
6695
+ * @return {number|null} the EMU value to write, or null to omit the attribute
6696
+ */
6697
+ function resolveParagraphMargin(option, fallbackEmu, clamp) {
6698
+ if (option === void 0) return fallbackEmu;
6699
+ if (option === "inherit") return null;
6700
+ return clamp(option);
6701
+ }
6702
+ /**
6623
6703
  * Generate XML Paragraph Properties
6624
6704
  * @param {SlideObject|TextProps} textObj - text object
6625
6705
  * @param {boolean} isDefault - array of default relations
@@ -6634,44 +6714,47 @@ function genXmlParagraphProperties(textObj, isDefault) {
6634
6714
  let strXmlTabStops = "";
6635
6715
  const tag = isDefault ? "a:lvl1pPr" : "a:pPr";
6636
6716
  let bulletMarL = valToPts(27);
6717
+ let defaultMarL = null;
6718
+ let defaultIndent = null;
6719
+ let indentBeforeMarL = false;
6637
6720
  let paragraphPropXml = `<${tag}${opts.rtlMode ? " rtl=\"1\" " : ""}`;
6638
- if (opts.align) switch (opts.align) {
6639
- case "left":
6640
- paragraphPropXml += " algn=\"l\"";
6641
- break;
6642
- case "right":
6643
- paragraphPropXml += " algn=\"r\"";
6644
- break;
6645
- case "center":
6646
- paragraphPropXml += " algn=\"ctr\"";
6647
- break;
6648
- case "justify":
6649
- paragraphPropXml += " algn=\"just\"";
6650
- break;
6651
- default: paragraphPropXml += "";
6652
- }
6653
- if (opts.lineSpacing) strXmlLnSpc = el("a:lnSpc", null, raw(voidEl("a:spcPts", { val: clampLineSpacingPts(opts.lineSpacing) })));
6654
- else if (opts.lineSpacingMultiple) strXmlLnSpc = el("a:lnSpc", null, raw(voidEl("a:spcPct", { val: Math.round(opts.lineSpacingMultiple * PERCENT_SCALE) })));
6655
- if (opts.indentLevel && !isNaN(Number(opts.indentLevel)) && opts.indentLevel > 0) paragraphPropXml += ` lvl="${opts.indentLevel}"`;
6656
- if (opts.paraSpaceBefore && !isNaN(Number(opts.paraSpaceBefore)) && opts.paraSpaceBefore > 0) strXmlParaSpc += el("a:spcBef", null, raw(voidEl("a:spcPts", { val: ptToHundredths(opts.paraSpaceBefore) })));
6657
- if (opts.paraSpaceAfter && !isNaN(Number(opts.paraSpaceAfter)) && opts.paraSpaceAfter > 0) strXmlParaSpc += el("a:spcAft", null, raw(voidEl("a:spcPts", { val: ptToHundredths(opts.paraSpaceAfter) })));
6658
- if (typeof opts.bullet === "object") {
6659
- const bulletImage = opts.bullet.image;
6660
- const isPictureBullet = !!(bulletImage && (bulletImage.path || bulletImage.data));
6661
- if (opts.bullet?.indent) bulletMarL = valToPts(opts.bullet.indent);
6662
- if (opts.bullet.color && !isPictureBullet) strXmlBulletColor = el("a:buClr", null, raw(createColorElement(opts.bullet.color)));
6663
- let bulletSizePct;
6664
- if (opts.bullet.size !== void 0) {
6665
- const bulletSize = Number(opts.bullet.size);
6666
- if (isNaN(bulletSize) || bulletSize < 25 || bulletSize > 400) warn("bullet/size-out-of-range", "`bullet.size` must be a percentage between 25 and 400!");
6667
- else bulletSizePct = Math.round(bulletSize * FIXED_PCT_PER_PERCENT);
6721
+ {
6722
+ if (opts.align) switch (opts.align) {
6723
+ case "left":
6724
+ paragraphPropXml += " algn=\"l\"";
6725
+ break;
6726
+ case "right":
6727
+ paragraphPropXml += " algn=\"r\"";
6728
+ break;
6729
+ case "center":
6730
+ paragraphPropXml += " algn=\"ctr\"";
6731
+ break;
6732
+ case "justify":
6733
+ paragraphPropXml += " algn=\"just\"";
6734
+ break;
6735
+ default: paragraphPropXml += "";
6668
6736
  }
6669
- const strXmlBulletSize = bulletSizePct === void 0 ? "" : voidEl("a:buSzPct", { val: bulletSizePct });
6670
- const strXmlBulletFont = opts.bullet.fontFace ? voidEl("a:buFont", { typeface: opts.bullet.fontFace }) : "";
6671
- const bulletIndentAttrs = () => ` marL="${opts.indentLevel && opts.indentLevel > 0 ? bulletMarL + bulletMarL * opts.indentLevel : bulletMarL}" indent="-${bulletMarL}"`;
6672
- if (isPictureBullet) {
6673
- paragraphPropXml += bulletIndentAttrs();
6674
- if (opts.bullet._rId) {
6737
+ if (opts.lineSpacing) strXmlLnSpc = el("a:lnSpc", null, raw(voidEl("a:spcPts", { val: clampLineSpacingPts(opts.lineSpacing) })));
6738
+ else if (opts.lineSpacingMultiple) strXmlLnSpc = el("a:lnSpc", null, raw(voidEl("a:spcPct", { val: Math.round(opts.lineSpacingMultiple * PERCENT_SCALE) })));
6739
+ if (opts.indentLevel && !isNaN(Number(opts.indentLevel)) && opts.indentLevel > 0) paragraphPropXml += ` lvl="${opts.indentLevel}"`;
6740
+ if (opts.paraSpaceBefore && !isNaN(Number(opts.paraSpaceBefore)) && opts.paraSpaceBefore > 0) strXmlParaSpc += el("a:spcBef", null, raw(voidEl("a:spcPts", { val: ptToHundredths(opts.paraSpaceBefore) })));
6741
+ if (opts.paraSpaceAfter && !isNaN(Number(opts.paraSpaceAfter)) && opts.paraSpaceAfter > 0) strXmlParaSpc += el("a:spcAft", null, raw(voidEl("a:spcPts", { val: ptToHundredths(opts.paraSpaceAfter) })));
6742
+ if (typeof opts.bullet === "object") {
6743
+ const bulletImage = opts.bullet.image;
6744
+ const isPictureBullet = !!(bulletImage && (bulletImage.path || bulletImage.data));
6745
+ if (opts.bullet?.indent) bulletMarL = valToPts(opts.bullet.indent);
6746
+ defaultMarL = opts.indentLevel && opts.indentLevel > 0 ? bulletMarL + bulletMarL * opts.indentLevel : bulletMarL;
6747
+ defaultIndent = -bulletMarL;
6748
+ if (opts.bullet.color && !isPictureBullet) strXmlBulletColor = el("a:buClr", null, raw(createColorElement(opts.bullet.color)));
6749
+ let bulletSizePct;
6750
+ if (opts.bullet.size !== void 0) {
6751
+ const bulletSize = Number(opts.bullet.size);
6752
+ if (isNaN(bulletSize) || bulletSize < 25 || bulletSize > 400) warn("bullet/size-out-of-range", "`bullet.size` must be a percentage between 25 and 400!");
6753
+ else bulletSizePct = Math.round(bulletSize * FIXED_PCT_PER_PERCENT);
6754
+ }
6755
+ const strXmlBulletSize = bulletSizePct === void 0 ? "" : voidEl("a:buSzPct", { val: bulletSizePct });
6756
+ const strXmlBulletFont = opts.bullet.fontFace ? voidEl("a:buFont", { typeface: opts.bullet.fontFace }) : "";
6757
+ if (isPictureBullet) if (opts.bullet._rId) {
6675
6758
  const svgExt = opts.bullet._rIdSvg ? el("a:extLst", null, raw(el("a:ext", { uri: "{96DAC541-7B7A-43D3-8B79-37D633B846F1}" }, raw(voidEl("asvg:svgBlip", {
6676
6759
  "xmlns:asvg": "http://schemas.microsoft.com/office/drawing/2016/SVG/main",
6677
6760
  "r:embed": `rId${opts.bullet._rIdSvg}`
@@ -6681,38 +6764,41 @@ function genXmlParagraphProperties(textObj, isDefault) {
6681
6764
  warn("bullet/image-embed-failed", "picture `bullet.image` could not be embedded; using a default bullet glyph");
6682
6765
  strXmlBullet = strXmlBulletSize + strXmlBulletFont + buChar("&#x2022;");
6683
6766
  }
6684
- } else if (opts.bullet.type && opts.bullet.type.toString().toLowerCase() === "number") {
6685
- paragraphPropXml += bulletIndentAttrs();
6686
- strXmlBullet = strXmlBulletSize + (strXmlBulletFont || voidEl("a:buFont", { typeface: "+mj-lt" })) + voidEl("a:buAutoNum", {
6767
+ else if (opts.bullet.type && opts.bullet.type.toString().toLowerCase() === "number") strXmlBullet = strXmlBulletSize + (strXmlBulletFont || voidEl("a:buFont", { typeface: "+mj-lt" })) + voidEl("a:buAutoNum", {
6687
6768
  type: opts.bullet.numberType || "arabicPeriod",
6688
6769
  startAt: opts.bullet.numberStartAt || "1"
6689
6770
  });
6690
- } else if (opts.bullet.characterCode) {
6691
- let bulletCode = `&#x${opts.bullet.characterCode};`;
6692
- if (!/^[0-9A-Fa-f]{4}$/.test(opts.bullet.characterCode)) {
6693
- warn("bullet/invalid-character-code", "`bullet.characterCode` should be a 4-digit unicode character (ex: 22AB)!");
6694
- bulletCode = "&#x2022;";
6695
- }
6696
- paragraphPropXml += bulletIndentAttrs();
6697
- strXmlBullet = strXmlBulletSize + strXmlBulletFont + buChar(bulletCode);
6698
- } else {
6699
- paragraphPropXml += bulletIndentAttrs();
6700
- strXmlBullet = strXmlBulletSize + strXmlBulletFont + buChar("&#x2022;");
6771
+ else if (opts.bullet.characterCode) {
6772
+ let bulletCode = `&#x${opts.bullet.characterCode};`;
6773
+ if (!/^[0-9A-Fa-f]{4}$/.test(opts.bullet.characterCode)) {
6774
+ warn("bullet/invalid-character-code", "`bullet.characterCode` should be a 4-digit unicode character (ex: 22AB)!");
6775
+ bulletCode = "&#x2022;";
6776
+ }
6777
+ strXmlBullet = strXmlBulletSize + strXmlBulletFont + buChar(bulletCode);
6778
+ } else strXmlBullet = strXmlBulletSize + strXmlBulletFont + buChar("&#x2022;");
6779
+ } else if (opts.bullet === "inherit") {} else if (opts.bullet) {
6780
+ defaultMarL = opts.indentLevel && opts.indentLevel > 0 ? bulletMarL + bulletMarL * opts.indentLevel : bulletMarL;
6781
+ defaultIndent = -bulletMarL;
6782
+ strXmlBullet = buChar("&#x2022;");
6783
+ } else if (!opts.bullet) {
6784
+ defaultMarL = 0;
6785
+ defaultIndent = 0;
6786
+ indentBeforeMarL = true;
6787
+ strXmlBullet = voidEl("a:buNone");
6701
6788
  }
6702
- } else if (opts.bullet) {
6703
- paragraphPropXml += ` marL="${opts.indentLevel && opts.indentLevel > 0 ? bulletMarL + bulletMarL * opts.indentLevel : bulletMarL}" indent="-${bulletMarL}"`;
6704
- strXmlBullet = buChar("&#x2022;");
6705
- } else if (!opts.bullet) {
6706
- paragraphPropXml += " indent=\"0\" marL=\"0\"";
6707
- strXmlBullet = voidEl("a:buNone");
6708
- }
6709
- if (opts.tabStops && Array.isArray(opts.tabStops)) strXmlTabStops = el("a:tabLst", null, raw(opts.tabStops.map((stop) => voidEl("a:tab", {
6710
- pos: inch2Emu(stop.position || 1),
6711
- algn: stop.alignment || "l"
6712
- })).join("")));
6713
- paragraphPropXml += ">" + strXmlLnSpc + strXmlParaSpc + strXmlBulletColor + strXmlBullet + strXmlTabStops;
6714
- if (isDefault) paragraphPropXml += genXmlTextRunProperties(opts, true);
6715
- paragraphPropXml += "</" + tag + ">";
6789
+ const marLEmu = resolveParagraphMargin(opts.paraMarginLeft, defaultMarL, clampParaMarginEmu);
6790
+ const indentEmu = resolveParagraphMargin(opts.paraIndent, defaultIndent, clampParaIndentEmu);
6791
+ const marLAttr = marLEmu === null ? "" : ` marL="${marLEmu}"`;
6792
+ const indentAttr = indentEmu === null ? "" : ` indent="${indentEmu}"`;
6793
+ paragraphPropXml += indentBeforeMarL ? indentAttr + marLAttr : marLAttr + indentAttr;
6794
+ if (opts.tabStops && Array.isArray(opts.tabStops)) strXmlTabStops = el("a:tabLst", null, raw(opts.tabStops.map((stop) => voidEl("a:tab", {
6795
+ pos: inch2Emu(stop.position || 1),
6796
+ algn: stop.alignment || "l"
6797
+ })).join("")));
6798
+ paragraphPropXml += ">" + strXmlLnSpc + strXmlParaSpc + strXmlBulletColor + strXmlBullet + strXmlTabStops;
6799
+ if (isDefault) paragraphPropXml += genXmlTextRunProperties(opts, true);
6800
+ paragraphPropXml += "</" + tag + ">";
6801
+ }
6716
6802
  return paragraphPropXml;
6717
6803
  }
6718
6804
  /**
@@ -6833,7 +6919,7 @@ function groupRunsIntoLines(arrTextObjects, opts) {
6833
6919
  arrLines.push(arrTexts);
6834
6920
  arrTexts = [];
6835
6921
  }
6836
- } else if (arrTexts.length > 0 && textObj.options.bullet && arrTexts.length > 0) {
6922
+ } else if (arrTexts.length > 0 && emitsBulletMarkup(textObj.options.bullet)) {
6837
6923
  arrLines.push(arrTexts);
6838
6924
  arrTexts = [];
6839
6925
  textObj.options.breakLine = false;
@@ -6863,7 +6949,6 @@ function renderTextParagraphsXml(arrLines, slideObj, opts) {
6863
6949
  }
6864
6950
  let reqsClosingFontSize = false;
6865
6951
  let paraXml = "";
6866
- let paragraphPropXml = `<a:pPr ${line[0]?.options?.rtlMode ? " rtl=\"1\" " : ""}`;
6867
6952
  let paragraphPropEmitted = false;
6868
6953
  line.forEach((textObj, idx) => {
6869
6954
  textObj.options._lineIdx = idx;
@@ -6874,20 +6959,18 @@ function renderTextParagraphsXml(arrLines, slideObj, opts) {
6874
6959
  textObj.options.indentLevel = textObj.options.indentLevel || opts.indentLevel;
6875
6960
  textObj.options.paraSpaceBefore = textObj.options.paraSpaceBefore || opts.paraSpaceBefore;
6876
6961
  textObj.options.paraSpaceAfter = textObj.options.paraSpaceAfter || opts.paraSpaceAfter;
6962
+ textObj.options.paraMarginLeft = textObj.options.paraMarginLeft ?? opts.paraMarginLeft;
6963
+ textObj.options.paraIndent = textObj.options.paraIndent ?? opts.paraIndent;
6877
6964
  if (!paragraphPropEmitted) {
6878
- paragraphPropXml = genXmlParagraphProperties(textObj, false);
6879
- const cleaned = paragraphPropXml.replace("<a:pPr></a:pPr>", "");
6880
- if (cleaned) {
6881
- paraXml += cleaned;
6882
- paragraphPropEmitted = true;
6883
- }
6965
+ paragraphPropEmitted = true;
6966
+ paraXml += genXmlParagraphProperties(textObj, false).replace("<a:pPr></a:pPr>", "");
6884
6967
  }
6885
6968
  const textOptions = textObj.options;
6886
6969
  Object.entries(opts).filter(([key]) => !(textObj.options.hyperlink && key === "color")).forEach(([key, val]) => {
6887
6970
  if (key !== "bullet" && !textOptions[key]) textOptions[key] = val;
6888
6971
  });
6889
6972
  let _textRunObj = textObj;
6890
- if (idx === 0 && line[0]?.options.bullet && typeof textObj.text === "string") {
6973
+ if (idx === 0 && emitsBulletMarkup(line[0]?.options.bullet) && typeof textObj.text === "string") {
6891
6974
  const _stripped = textObj.text.replace(/^[\u2022\u25E6\u25AA\u25AB\u25CF\u25CB\u2023\u2043\u2219]\s*/, "");
6892
6975
  if (_stripped !== textObj.text) _textRunObj = {
6893
6976
  text: _stripped,
@@ -11005,7 +11088,7 @@ async function writePackage(source, props) {
11005
11088
  * the OfficeGen project (Copyright 2013 Ziv Barber). This project is likewise MIT; the full
11006
11089
  * license text is in `LICENSE` at the repository root.
11007
11090
  */
11008
- const VERSION = "3.0.0";
11091
+ const VERSION = "3.2.0";
11009
11092
  function standardLayoutToPresLayout(layout) {
11010
11093
  return {
11011
11094
  name: layout.name,
@@ -11893,4 +11976,4 @@ function textRuns(runs) {
11893
11976
  //#endregion
11894
11977
  export { PresentationCore as i, textRuns as n, clipPath as r, textRun as t };
11895
11978
 
11896
- //# sourceMappingURL=text-120VFSDm.js.map
11979
+ //# sourceMappingURL=text-C4P9MNdf.js.map