llm-dom-to-pptx 1.0.2 → 1.0.3

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/README.md CHANGED
@@ -28,7 +28,7 @@ This library depends on `PptxGenJS`.
28
28
  <script src="https://cdn.jsdelivr.net/npm/pptxgenjs@3.12.0/dist/pptxgen.min.js"></script>
29
29
 
30
30
  <!-- llm-dom-to-pptx -->
31
- <script src="https://cdn.jsdelivr.net/npm/llm-dom-to-pptx@1.0.2/dist/llm-dom-to-pptx.js"></script>
31
+ <script src="https://cdn.jsdelivr.net/npm/llm-dom-to-pptx@1.0.3/dist/llm-dom-to-pptx.js"></script>
32
32
  ```
33
33
 
34
34
  ### 2. Prepare Your HTML
@@ -1,5 +1,5 @@
1
1
  /**
2
- * LLM DOM to PPTX - v1.0.2
2
+ * LLM DOM to PPTX - v1.0.3
3
3
  * Converts Semantic HTML/CSS (e.g. from LLMs) into editable PPTX.
4
4
  *
5
5
  * Dependencies:
@@ -221,6 +221,27 @@
221
221
  breakLine: false
222
222
  };
223
223
 
224
+ // Letter Spacing (Tracking) Support
225
+ // Converts CSS letter-spacing (px/em) to PPTX charSpacing (points)
226
+ const letterSpacingStr = style.letterSpacing;
227
+ if (letterSpacingStr && letterSpacingStr !== 'normal') {
228
+ let spacingPx = 0;
229
+ if (letterSpacingStr.includes('em')) {
230
+ // e.g. "0.2em" -> 0.2 * fontSize
231
+ spacingPx = parseFloat(letterSpacingStr) * (parseFloat(style.fontSize) || 16);
232
+ } else if (letterSpacingStr.includes('px')) {
233
+ spacingPx = parseFloat(letterSpacingStr);
234
+ } else if (!isNaN(parseFloat(letterSpacingStr))) {
235
+ // Fallback if just number (unlikely in CSS computed style but safe)
236
+ spacingPx = parseFloat(letterSpacingStr);
237
+ }
238
+
239
+ // Convert px to pt (1px = 0.75pt)
240
+ if (spacingPx !== 0) {
241
+ runOpts.charSpacing = spacingPx * 0.75;
242
+ }
243
+ }
244
+
224
245
  if (colorParsed && colorParsed.transparency > 0) {
225
246
  runOpts.transparency = colorParsed.transparency;
226
247
  }
@@ -736,14 +757,37 @@
736
757
  if (tw < 0) tw = 0;
737
758
  if (th < 0) th = 0;
738
759
 
739
- const widthBuffer = pxToInch(12);
760
+ // Line Height (Leading) Support
761
+ // Convert CSS line-height to PPTX lineSpacing (Points)
762
+ let lineSpacingPoints = null;
763
+ const lhStr = style.lineHeight;
764
+ if (lhStr && lhStr !== 'normal') {
765
+ const lhPx = parseFloat(lhStr);
766
+ if (!isNaN(lhPx)) {
767
+ lineSpacingPoints = lhPx * 0.75; // px to pt
768
+ }
769
+ }
770
+
771
+ // Add small buffer to text box width to prevent premature wrapping
772
+ // due to minor font rendering differences
773
+ const widthBuffer = pxToInch(2);
774
+ let finalTx = tx;
775
+
776
+ // Adjust x position for center alignment to keep it visually centered
777
+ if (align === 'center') finalTx -= widthBuffer / 2;
740
778
 
741
779
  // We use inset:0 because we already applied padding via x/y/w/h
742
- slide.addText(runs, {
743
- x: tx, y: ty, w: tw + widthBuffer, h: th,
780
+ const textOpts = {
781
+ x: finalTx, y: ty, w: tw + widthBuffer, h: th,
744
782
  align: align, valign: valign, margin: 0, inset: 0,
745
783
  autoFit: false, wrap: true
746
- });
784
+ };
785
+
786
+ if (lineSpacingPoints) {
787
+ textOpts.lineSpacing = lineSpacingPoints;
788
+ }
789
+
790
+ slide.addText(runs, textOpts);
747
791
  }
748
792
 
749
793
  const markSeen = (n) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "llm-dom-to-pptx",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "Turn AI-generated HTML/CSS into native, editable PowerPoint slides.",
5
5
  "main": "dist/llm-dom-to-pptx.js",
6
6
  "scripts": {