format: apply repo prettier (3.8.1) to the folded skills tree

963 markdown files reformatted with the repository's pinned prettier so
pnpm format:check covers the folded tree like every other repo file.

The formatter's embedded-language pass also normalized code fences
(TS semicolons, closed HTML tags in examples, lowercased CSS hex colors,
one renumbered list that skipped an index). Alphanumeric token deltas vs
the fold commit were audited file-by-file; all are formatter-equivalent
markup normalizations plus the four sanitized skills.
This commit is contained in:
fargo
2026-08-19 14:37:17 -05:00
parent d2eeb64433
commit 1a822493ba
962 changed files with 29594 additions and 27188 deletions
+219 -108
View File
@@ -3,22 +3,23 @@
## Setup & Basic Structure
```javascript
const pptxgen = require("pptxgenjs");
const pptxgen = require('pptxgenjs');
let pres = new pptxgen();
pres.layout = 'LAYOUT_16x9'; // or 'LAYOUT_16x10', 'LAYOUT_4x3', 'LAYOUT_WIDE'
pres.layout = 'LAYOUT_16x9'; // or 'LAYOUT_16x10', 'LAYOUT_4x3', 'LAYOUT_WIDE'
pres.author = 'Your Name';
pres.title = 'Presentation Title';
let slide = pres.addSlide();
slide.addText("Hello World!", { x: 0.5, y: 0.5, fontSize: 36, color: "363636" });
slide.addText('Hello World!', { x: 0.5, y: 0.5, fontSize: 36, color: '363636' });
pres.writeFile({ fileName: "Presentation.pptx" });
pres.writeFile({ fileName: 'Presentation.pptx' });
```
## Layout Dimensions
Slide dimensions (coordinates in inches):
- `LAYOUT_16x9`: 10" × 5.625" (default)
- `LAYOUT_16x10`: 10" × 6.25"
- `LAYOUT_4x3`: 10" × 7.5"
@@ -30,31 +31,48 @@ Slide dimensions (coordinates in inches):
```javascript
// Basic text
slide.addText("Simple Text", {
x: 1, y: 1, w: 8, h: 2, fontSize: 24, fontFace: "Arial",
color: "363636", bold: true, align: "center", valign: "middle"
slide.addText('Simple Text', {
x: 1,
y: 1,
w: 8,
h: 2,
fontSize: 24,
fontFace: 'Arial',
color: '363636',
bold: true,
align: 'center',
valign: 'middle',
});
// Character spacing (use charSpacing, not letterSpacing which is silently ignored)
slide.addText("SPACED TEXT", { x: 1, y: 1, w: 8, h: 1, charSpacing: 6 });
slide.addText('SPACED TEXT', { x: 1, y: 1, w: 8, h: 1, charSpacing: 6 });
// Rich text arrays
slide.addText([
{ text: "Bold ", options: { bold: true } },
{ text: "Italic ", options: { italic: true } }
], { x: 1, y: 3, w: 8, h: 1 });
slide.addText(
[
{ text: 'Bold ', options: { bold: true } },
{ text: 'Italic ', options: { italic: true } },
],
{ x: 1, y: 3, w: 8, h: 1 },
);
// Multi-line text (requires breakLine: true)
slide.addText([
{ text: "Line 1", options: { breakLine: true } },
{ text: "Line 2", options: { breakLine: true } },
{ text: "Line 3" } // Last item doesn't need breakLine
], { x: 0.5, y: 0.5, w: 8, h: 2 });
slide.addText(
[
{ text: 'Line 1', options: { breakLine: true } },
{ text: 'Line 2', options: { breakLine: true } },
{ text: 'Line 3' }, // Last item doesn't need breakLine
],
{ x: 0.5, y: 0.5, w: 8, h: 2 },
);
// Text box margin (internal padding)
slide.addText("Title", {
x: 0.5, y: 0.3, w: 9, h: 0.6,
margin: 0 // Use 0 when aligning text with other elements like shapes or icons
slide.addText('Title', {
x: 0.5,
y: 0.3,
w: 9,
h: 0.6,
margin: 0, // Use 0 when aligning text with other elements like shapes or icons
});
```
@@ -86,47 +104,65 @@ slide.addText("• First item", { ... }); // Creates double bullets
```javascript
slide.addShape(pres.shapes.RECTANGLE, {
x: 0.5, y: 0.8, w: 1.5, h: 3.0,
fill: { color: "FF0000" }, line: { color: "000000", width: 2 }
x: 0.5,
y: 0.8,
w: 1.5,
h: 3.0,
fill: { color: 'FF0000' },
line: { color: '000000', width: 2 },
});
slide.addShape(pres.shapes.OVAL, { x: 4, y: 1, w: 2, h: 2, fill: { color: "0000FF" } });
slide.addShape(pres.shapes.OVAL, { x: 4, y: 1, w: 2, h: 2, fill: { color: '0000FF' } });
slide.addShape(pres.shapes.LINE, {
x: 1, y: 3, w: 5, h: 0, line: { color: "FF0000", width: 3, dashType: "dash" }
x: 1,
y: 3,
w: 5,
h: 0,
line: { color: 'FF0000', width: 3, dashType: 'dash' },
});
// With transparency
slide.addShape(pres.shapes.RECTANGLE, {
x: 1, y: 1, w: 3, h: 2,
fill: { color: "0088CC", transparency: 50 }
x: 1,
y: 1,
w: 3,
h: 2,
fill: { color: '0088CC', transparency: 50 },
});
// Rounded rectangle (rectRadius only works with ROUNDED_RECTANGLE, not RECTANGLE)
// ⚠️ Don't pair with rectangular accent overlays — they won't cover rounded corners. Use RECTANGLE instead.
slide.addShape(pres.shapes.ROUNDED_RECTANGLE, {
x: 1, y: 1, w: 3, h: 2,
fill: { color: "FFFFFF" }, rectRadius: 0.1
x: 1,
y: 1,
w: 3,
h: 2,
fill: { color: 'FFFFFF' },
rectRadius: 0.1,
});
// With shadow
slide.addShape(pres.shapes.RECTANGLE, {
x: 1, y: 1, w: 3, h: 2,
fill: { color: "FFFFFF" },
shadow: { type: "outer", color: "000000", blur: 6, offset: 2, angle: 135, opacity: 0.15 }
x: 1,
y: 1,
w: 3,
h: 2,
fill: { color: 'FFFFFF' },
shadow: { type: 'outer', color: '000000', blur: 6, offset: 2, angle: 135, opacity: 0.15 },
});
```
Shadow options:
| Property | Type | Range | Notes |
|----------|------|-------|-------|
| `type` | string | `"outer"`, `"inner"` | |
| `color` | string | 6-char hex (e.g. `"000000"`) | No `#` prefix, no 8-char hex — see Common Pitfalls |
| `blur` | number | 0-100 pt | |
| `offset` | number | 0-200 pt | **Must be non-negative** — negative values corrupt the file |
| `angle` | number | 0-359 degrees | Direction the shadow falls (135 = bottom-right, 270 = upward) |
| `opacity` | number | 0.0-1.0 | Use this for transparency, never encode in color string |
| Property | Type | Range | Notes |
| --------- | ------ | ---------------------------- | ------------------------------------------------------------- |
| `type` | string | `"outer"`, `"inner"` | |
| `color` | string | 6-char hex (e.g. `"000000"`) | No `#` prefix, no 8-char hex — see Common Pitfalls |
| `blur` | number | 0-100 pt | |
| `offset` | number | 0-200 pt | **Must be non-negative** — negative values corrupt the file |
| `angle` | number | 0-359 degrees | Direction the shadow falls (135 = bottom-right, 270 = upward) |
| `opacity` | number | 0.0-1.0 | Use this for transparency, never encode in color string |
To cast a shadow upward (e.g. on a footer bar), use `angle: 270` with a positive offset — do **not** use a negative offset.
@@ -140,28 +176,31 @@ To cast a shadow upward (e.g. on a footer bar), use `angle: 270` with a positive
```javascript
// From file path
slide.addImage({ path: "images/chart.png", x: 1, y: 1, w: 5, h: 3 });
slide.addImage({ path: 'images/chart.png', x: 1, y: 1, w: 5, h: 3 });
// From URL
slide.addImage({ path: "https://example.com/image.jpg", x: 1, y: 1, w: 5, h: 3 });
slide.addImage({ path: 'https://example.com/image.jpg', x: 1, y: 1, w: 5, h: 3 });
// From base64 (faster, no file I/O)
slide.addImage({ data: "image/png;base64,iVBORw0KGgo...", x: 1, y: 1, w: 5, h: 3 });
slide.addImage({ data: 'image/png;base64,iVBORw0KGgo...', x: 1, y: 1, w: 5, h: 3 });
```
### Image Options
```javascript
slide.addImage({
path: "image.png",
x: 1, y: 1, w: 5, h: 3,
rotate: 45, // 0-359 degrees
rounding: true, // Circular crop
transparency: 50, // 0-100
flipH: true, // Horizontal flip
flipV: false, // Vertical flip
altText: "Description", // Accessibility
hyperlink: { url: "https://example.com" }
path: 'image.png',
x: 1,
y: 1,
w: 5,
h: 3,
rotate: 45, // 0-359 degrees
rounding: true, // Circular crop
transparency: 50, // 0-100
flipH: true, // Horizontal flip
flipV: false, // Vertical flip
altText: 'Description', // Accessibility
hyperlink: { url: 'https://example.com' },
});
```
@@ -181,11 +220,13 @@ slide.addImage({
### Calculate Dimensions (preserve aspect ratio)
```javascript
const origWidth = 1978, origHeight = 923, maxHeight = 3.0;
const origWidth = 1978,
origHeight = 923,
maxHeight = 3.0;
const calcWidth = maxHeight * (origWidth / origHeight);
const centerX = (10 - calcWidth) / 2;
slide.addImage({ path: "image.png", x: centerX, y: 1.2, w: calcWidth, h: maxHeight });
slide.addImage({ path: 'image.png', x: centerX, y: 1.2, w: calcWidth, h: maxHeight });
```
### Supported Formats
@@ -202,32 +243,35 @@ Use react-icons to generate SVG icons, then rasterize to PNG for universal compa
### Setup
```javascript
const React = require("react");
const ReactDOMServer = require("react-dom/server");
const sharp = require("sharp");
const { FaCheckCircle, FaChartLine } = require("react-icons/fa");
const React = require('react');
const ReactDOMServer = require('react-dom/server');
const sharp = require('sharp');
const { FaCheckCircle, FaChartLine } = require('react-icons/fa');
function renderIconSvg(IconComponent, color = "#000000", size = 256) {
function renderIconSvg(IconComponent, color = '#000000', size = 256) {
return ReactDOMServer.renderToStaticMarkup(
React.createElement(IconComponent, { color, size: String(size) })
React.createElement(IconComponent, { color, size: String(size) }),
);
}
async function iconToBase64Png(IconComponent, color, size = 256) {
const svg = renderIconSvg(IconComponent, color, size);
const pngBuffer = await sharp(Buffer.from(svg)).png().toBuffer();
return "image/png;base64," + pngBuffer.toString("base64");
return 'image/png;base64,' + pngBuffer.toString('base64');
}
```
### Add Icon to Slide
```javascript
const iconData = await iconToBase64Png(FaCheckCircle, "#4472C4", 256);
const iconData = await iconToBase64Png(FaCheckCircle, '#4472C4', 256);
slide.addImage({
data: iconData,
x: 1, y: 1, w: 0.5, h: 0.5 // Size in inches
x: 1,
y: 1,
w: 0.5,
h: 0.5, // Size in inches
});
```
@@ -238,6 +282,7 @@ slide.addImage({
Install: `npm install -g react-icons react react-dom sharp`
Popular icon sets in react-icons:
- `react-icons/fa` - Font Awesome
- `react-icons/md` - Material Design
- `react-icons/hi` - Heroicons
@@ -249,16 +294,16 @@ Popular icon sets in react-icons:
```javascript
// Solid color
slide.background = { color: "F1F1F1" };
slide.background = { color: 'F1F1F1' };
// Color with transparency
slide.background = { color: "FF3399", transparency: 50 };
slide.background = { color: 'FF3399', transparency: 50 };
// Image from URL
slide.background = { path: "https://example.com/bg.jpg" };
slide.background = { path: 'https://example.com/bg.jpg' };
// Image from base64
slide.background = { data: "image/png;base64,iVBORw0KGgo..." };
slide.background = { data: 'image/png;base64,iVBORw0KGgo...' };
```
---
@@ -266,18 +311,25 @@ slide.background = { data: "image/png;base64,iVBORw0KGgo..." };
## Tables
```javascript
slide.addTable([
["Header 1", "Header 2"],
["Cell 1", "Cell 2"]
], {
x: 1, y: 1, w: 8, h: 2,
border: { pt: 1, color: "999999" }, fill: { color: "F1F1F1" }
});
slide.addTable(
[
['Header 1', 'Header 2'],
['Cell 1', 'Cell 2'],
],
{
x: 1,
y: 1,
w: 8,
h: 2,
border: { pt: 1, color: '999999' },
fill: { color: 'F1F1F1' },
},
);
// Advanced with merged cells
let tableData = [
[{ text: "Header", options: { fill: { color: "6699CC" }, color: "FFFFFF", bold: true } }, "Cell"],
[{ text: "Merged", options: { colspan: 2 } }]
[{ text: 'Header', options: { fill: { color: '6699CC' }, color: 'FFFFFF', bold: true } }, 'Cell'],
[{ text: 'Merged', options: { colspan: 2 } }],
];
slide.addTable(tableData, { x: 1, y: 3.5, w: 8, colW: [4, 4] });
```
@@ -288,22 +340,51 @@ slide.addTable(tableData, { x: 1, y: 3.5, w: 8, colW: [4, 4] });
```javascript
// Bar chart
slide.addChart(pres.charts.BAR, [{
name: "Sales", labels: ["Q1", "Q2", "Q3", "Q4"], values: [4500, 5500, 6200, 7100]
}], {
x: 0.5, y: 0.6, w: 6, h: 3, barDir: 'col',
showTitle: true, title: 'Quarterly Sales'
});
slide.addChart(
pres.charts.BAR,
[
{
name: 'Sales',
labels: ['Q1', 'Q2', 'Q3', 'Q4'],
values: [4500, 5500, 6200, 7100],
},
],
{
x: 0.5,
y: 0.6,
w: 6,
h: 3,
barDir: 'col',
showTitle: true,
title: 'Quarterly Sales',
},
);
// Line chart
slide.addChart(pres.charts.LINE, [{
name: "Temp", labels: ["Jan", "Feb", "Mar"], values: [32, 35, 42]
}], { x: 0.5, y: 4, w: 6, h: 3, lineSize: 3, lineSmooth: true });
slide.addChart(
pres.charts.LINE,
[
{
name: 'Temp',
labels: ['Jan', 'Feb', 'Mar'],
values: [32, 35, 42],
},
],
{ x: 0.5, y: 4, w: 6, h: 3, lineSize: 3, lineSmooth: true },
);
// Pie chart
slide.addChart(pres.charts.PIE, [{
name: "Share", labels: ["A", "B", "Other"], values: [35, 45, 20]
}], { x: 7, y: 1, w: 5, h: 4, showPercent: true });
slide.addChart(
pres.charts.PIE,
[
{
name: 'Share',
labels: ['A', 'B', 'Other'],
values: [35, 45, 20],
},
],
{ x: 7, y: 1, w: 5, h: 4, showPercent: true },
);
```
### Better-Looking Charts
@@ -312,26 +393,30 @@ Default charts look dated. Apply these options for a modern, clean appearance:
```javascript
slide.addChart(pres.charts.BAR, chartData, {
x: 0.5, y: 1, w: 9, h: 4, barDir: "col",
x: 0.5,
y: 1,
w: 9,
h: 4,
barDir: 'col',
// Custom colors (match your presentation palette)
chartColors: ["0D9488", "14B8A6", "5EEAD4"],
chartColors: ['0D9488', '14B8A6', '5EEAD4'],
// Clean background
chartArea: { fill: { color: "FFFFFF" }, roundedCorners: true },
chartArea: { fill: { color: 'FFFFFF' }, roundedCorners: true },
// Muted axis labels
catAxisLabelColor: "64748B",
valAxisLabelColor: "64748B",
catAxisLabelColor: '64748B',
valAxisLabelColor: '64748B',
// Subtle grid (value axis only)
valGridLine: { color: "E2E8F0", size: 0.5 },
catGridLine: { style: "none" },
valGridLine: { color: 'E2E8F0', size: 0.5 },
catGridLine: { style: 'none' },
// Data labels on bars
showValue: true,
dataLabelPosition: "outEnd",
dataLabelColor: "1E293B",
dataLabelPosition: 'outEnd',
dataLabelColor: '1E293B',
// Hide legend for single series
showLegend: false,
@@ -339,6 +424,7 @@ slide.addChart(pres.charts.BAR, chartData, {
```
**Key styling options:**
- `chartColors: [...]` - hex colors for series/segments
- `chartArea: { fill, border, roundedCorners }` - chart background
- `catGridLine/valGridLine: { color, style, size }` - grid lines (`style: "none"` to hide)
@@ -351,14 +437,17 @@ slide.addChart(pres.charts.BAR, chartData, {
```javascript
pres.defineSlideMaster({
title: 'TITLE_SLIDE', background: { color: '283A5E' },
objects: [{
placeholder: { options: { name: 'title', type: 'title', x: 1, y: 2, w: 8, h: 2 } }
}]
title: 'TITLE_SLIDE',
background: { color: '283A5E' },
objects: [
{
placeholder: { options: { name: 'title', type: 'title', x: 1, y: 2, w: 8, h: 2 } },
},
],
});
let titleSlide = pres.addSlide({ masterName: "TITLE_SLIDE" });
titleSlide.addText("My Title", { placeholder: "title" });
let titleSlide = pres.addSlide({ masterName: 'TITLE_SLIDE' });
titleSlide.addText('My Title', { placeholder: 'title' });
```
---
@@ -368,12 +457,14 @@ titleSlide.addText("My Title", { placeholder: "title" });
⚠️ These issues cause file corruption, visual bugs, or broken output. Avoid them.
1. **NEVER use "#" with hex colors** - causes file corruption
```javascript
color: "FF0000" // ✅ CORRECT
color: "#FF0000" // ❌ WRONG
color: 'FF0000'; // ✅ CORRECT
color: '#FF0000'; // ❌ WRONG
```
2. **NEVER encode opacity in hex color strings** - 8-char colors (e.g., `"00000020"`) corrupt the file. Use the `opacity` property instead.
```javascript
shadow: { type: "outer", blur: 6, offset: 2, color: "00000020" } // ❌ CORRUPTS FILE
shadow: { type: "outer", blur: 6, offset: 2, color: "000000", opacity: 0.12 } // ✅ CORRECT
@@ -388,6 +479,7 @@ titleSlide.addText("My Title", { placeholder: "title" });
6. **Each presentation needs fresh instance** - don't reuse `pptxgen()` objects
7. **NEVER reuse option objects across calls** - PptxGenJS mutates objects in-place (e.g. converting shadow values to EMU). Sharing one object between multiple calls corrupts the second shape.
```javascript
const shadow = { type: "outer", blur: 6, offset: 2, color: "000000", opacity: 0.15 };
slide.addShape(pres.shapes.RECTANGLE, { shadow, ... }); // ❌ second call gets already-converted values
@@ -399,14 +491,33 @@ titleSlide.addText("My Title", { placeholder: "title" });
```
8. **Don't use `ROUNDED_RECTANGLE` with accent borders** - rectangular overlay bars won't cover rounded corners. Use `RECTANGLE` instead.
```javascript
// ❌ WRONG: Accent bar doesn't cover rounded corners
slide.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 1, y: 1, w: 3, h: 1.5, fill: { color: "FFFFFF" } });
slide.addShape(pres.shapes.RECTANGLE, { x: 1, y: 1, w: 0.08, h: 1.5, fill: { color: "0891B2" } });
slide.addShape(pres.shapes.ROUNDED_RECTANGLE, {
x: 1,
y: 1,
w: 3,
h: 1.5,
fill: { color: 'FFFFFF' },
});
slide.addShape(pres.shapes.RECTANGLE, {
x: 1,
y: 1,
w: 0.08,
h: 1.5,
fill: { color: '0891B2' },
});
// ✅ CORRECT: Use RECTANGLE for clean alignment
slide.addShape(pres.shapes.RECTANGLE, { x: 1, y: 1, w: 3, h: 1.5, fill: { color: "FFFFFF" } });
slide.addShape(pres.shapes.RECTANGLE, { x: 1, y: 1, w: 0.08, h: 1.5, fill: { color: "0891B2" } });
slide.addShape(pres.shapes.RECTANGLE, { x: 1, y: 1, w: 3, h: 1.5, fill: { color: 'FFFFFF' } });
slide.addShape(pres.shapes.RECTANGLE, {
x: 1,
y: 1,
w: 0.08,
h: 1.5,
fill: { color: '0891B2' },
});
```
---