chore: import upstream snapshot with attribution
Publish SDK (PyPI) / publish (push) Has been cancelled
Publish SDK (npm) / publish (@aionui/officecli-sdk) (push) Has been cancelled
SDK smoke / smoke (windows-latest) (push) Has been cancelled
Publish SDK (npm) / publish (@officecli/officecli-sdk) (push) Has been cancelled
Publish SDK (npm) / publish (@officecli/sdk) (push) Has been cancelled
Publish SDK (npm) / publish (officecli-sdk) (push) Has been cancelled
SDK smoke / smoke (macos-latest) (push) Has been cancelled
SDK smoke / smoke (ubuntu-latest) (push) Has been cancelled
Skill parity / diff (push) Has been cancelled
Publish SDK (PyPI) / publish (push) Has been cancelled
Publish SDK (npm) / publish (@aionui/officecli-sdk) (push) Has been cancelled
SDK smoke / smoke (windows-latest) (push) Has been cancelled
Publish SDK (npm) / publish (@officecli/officecli-sdk) (push) Has been cancelled
Publish SDK (npm) / publish (@officecli/sdk) (push) Has been cancelled
Publish SDK (npm) / publish (officecli-sdk) (push) Has been cancelled
SDK smoke / smoke (macos-latest) (push) Has been cancelled
SDK smoke / smoke (ubuntu-latest) (push) Has been cancelled
Skill parity / diff (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,372 @@
|
||||
# Advanced PPT Textbox Typography
|
||||
|
||||
This demo consists of three files that work together:
|
||||
|
||||
- **textboxes-advanced.sh** — Shell script that calls `officecli` commands to generate the deck.
|
||||
- **textboxes-advanced.pptx** — The generated 6-slide deck (per-paragraph overrides, paragraph indents, per-paragraph styling, per-run typography, subscript/superscript aliases, textbox meta props).
|
||||
- **textboxes-advanced.md** — This file. Covers per-paragraph and per-run overrides not shown in textboxes-basic.
|
||||
|
||||
## Regenerate
|
||||
|
||||
```bash
|
||||
cd examples/ppt
|
||||
bash textboxes/textboxes-advanced.sh
|
||||
# → textboxes/textboxes-advanced.pptx
|
||||
```
|
||||
|
||||
## Slides
|
||||
|
||||
### Slide 1 — Per-Paragraph Overrides (align / lineSpacing inside one textbox)
|
||||
|
||||
One textbox with five paragraphs; each paragraph overrides a different shape-level default.
|
||||
|
||||
```bash
|
||||
officecli create textboxes-advanced.pptx
|
||||
officecli open textboxes-advanced.pptx
|
||||
officecli add textboxes-advanced.pptx / --type slide
|
||||
|
||||
LOREM='Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus lacinia odio vitae vestibulum vestibulum.'
|
||||
|
||||
# Shape-level defaults: align=left, lineSpacing=1x
|
||||
officecli add textboxes-advanced.pptx '/slide[1]' --type textbox \
|
||||
--prop x=0.5in --prop y=1.2in --prop width=13in --prop height=5.5in \
|
||||
--prop fill=F1FAEE --prop size=14 \
|
||||
--prop text="[shape default: align=left, single-spaced] $LOREM"
|
||||
|
||||
# Each paragraph below overrides one property independently
|
||||
officecli add textboxes-advanced.pptx '/slide[1]/shape[2]' --type paragraph \
|
||||
--prop text="[paragraph override: align=center] $LOREM" --prop align=center
|
||||
|
||||
officecli add textboxes-advanced.pptx '/slide[1]/shape[2]' --type paragraph \
|
||||
--prop text="[paragraph override: align=right] $LOREM" --prop align=right
|
||||
|
||||
officecli add textboxes-advanced.pptx '/slide[1]/shape[2]' --type paragraph \
|
||||
--prop text="[paragraph override: align=justify + lineSpacing=2x] $LOREM $LOREM" \
|
||||
--prop align=justify --prop lineSpacing=2x
|
||||
|
||||
officecli add textboxes-advanced.pptx '/slide[1]/shape[2]' --type paragraph \
|
||||
--prop text="[paragraph override: lineSpacing=18pt fixed] $LOREM" \
|
||||
--prop lineSpacing=18pt
|
||||
```
|
||||
|
||||
**Features:** `--type paragraph` with `align` (center, right, justify) and `lineSpacing` (2x multiplier, 18pt fixed) override the shape defaults per-paragraph without affecting sibling paragraphs
|
||||
|
||||
---
|
||||
|
||||
### Slide 2 — Paragraph Indents (indent / marginLeft / marginRight)
|
||||
|
||||
Five textboxes showing every paragraph-level indent form: left-aligned indent, first-line indent, hanging indent, and right margin.
|
||||
|
||||
```bash
|
||||
officecli add textboxes-advanced.pptx / --type slide
|
||||
|
||||
# Reference — no indent
|
||||
officecli add textboxes-advanced.pptx '/slide[2]' --type textbox \
|
||||
--prop x=0.5in --prop y=1.3in --prop width=13in --prop height=1in \
|
||||
--prop fill=F1FAEE --prop size=14 \
|
||||
--prop text="[default: no indent] $LOREM $LOREM"
|
||||
|
||||
# marginLeft — whole paragraph body shifted right
|
||||
officecli add textboxes-advanced.pptx '/slide[2]' --type textbox \
|
||||
--prop x=0.5in --prop y=2.5in --prop width=13in --prop height=1in \
|
||||
--prop fill=A8DADC --prop size=14 \
|
||||
--prop text="[marginLeft=1in] $LOREM $LOREM" \
|
||||
--prop marginLeft=1in
|
||||
|
||||
# indent — first-line indent only (subsequent lines flush left)
|
||||
officecli add textboxes-advanced.pptx '/slide[2]' --type textbox \
|
||||
--prop x=0.5in --prop y=3.7in --prop width=13in --prop height=1in \
|
||||
--prop fill=F4A261 --prop size=14 \
|
||||
--prop text="[indent=0.5in first-line] $LOREM $LOREM" \
|
||||
--prop indent=0.5in
|
||||
|
||||
# Hanging indent — negative indent + positive marginLeft (first line extends further left)
|
||||
officecli add textboxes-advanced.pptx '/slide[2]' --type textbox \
|
||||
--prop x=0.5in --prop y=4.9in --prop width=13in --prop height=1in \
|
||||
--prop fill=A8DADC --prop size=14 \
|
||||
--prop text="[hanging: marginLeft=0.6in + indent=-0.5in] $LOREM $LOREM" \
|
||||
--prop marginLeft=0.6in --prop indent=-0.5in
|
||||
|
||||
# marginRight — text column narrowed from the right
|
||||
officecli add textboxes-advanced.pptx '/slide[2]' --type textbox \
|
||||
--prop x=0.5in --prop y=6.1in --prop width=13in --prop height=1in \
|
||||
--prop fill=F4A261 --prop size=14 \
|
||||
--prop text="[marginRight=2in] $LOREM $LOREM" \
|
||||
--prop marginRight=2in
|
||||
```
|
||||
|
||||
**Features:** `marginLeft` (left paragraph indent; in, cm, pt), `indent` (first-line indent only; negative = hanging), `marginRight` (right margin; narrows from right edge), all at both textbox-creation time and as `--type paragraph` overrides
|
||||
|
||||
---
|
||||
|
||||
### Slide 3 — Per-Paragraph Styling (bold / italic / color / size / lang)
|
||||
|
||||
One textbox where each paragraph carries its own style without needing explicit runs.
|
||||
|
||||
```bash
|
||||
officecli add textboxes-advanced.pptx / --type slide
|
||||
|
||||
# Shape default: 14pt black
|
||||
officecli add textboxes-advanced.pptx '/slide[3]' --type textbox \
|
||||
--prop x=0.5in --prop y=1.2in --prop width=13in --prop height=5in \
|
||||
--prop fill=F1FAEE --prop size=14 \
|
||||
--prop text="[shape default: 14pt black] Default paragraph styling."
|
||||
|
||||
# Each appended paragraph has a single style override — no runs needed
|
||||
officecli add textboxes-advanced.pptx '/slide[3]/shape[2]' --type paragraph \
|
||||
--prop text="[bold=true at paragraph level] Whole paragraph is bold." \
|
||||
--prop bold=true
|
||||
|
||||
officecli add textboxes-advanced.pptx '/slide[3]/shape[2]' --type paragraph \
|
||||
--prop text="[italic=true at paragraph level] Whole paragraph is italic." \
|
||||
--prop italic=true
|
||||
|
||||
officecli add textboxes-advanced.pptx '/slide[3]/shape[2]' --type paragraph \
|
||||
--prop text="[color=E63946 at paragraph level] Whole paragraph is red." \
|
||||
--prop color=E63946
|
||||
|
||||
officecli add textboxes-advanced.pptx '/slide[3]/shape[2]' --type paragraph \
|
||||
--prop text="[size=22 at paragraph level] Whole paragraph is 22pt." \
|
||||
--prop size=22
|
||||
|
||||
officecli add textboxes-advanced.pptx '/slide[3]/shape[2]' --type paragraph \
|
||||
--prop text="[lang=fr-FR at paragraph level] Lorem ipsum dolor sit amet." \
|
||||
--prop lang=fr-FR --prop color=2A9D8F
|
||||
```
|
||||
|
||||
**Features:** `--type paragraph` with `bold`, `italic`, `color`, `size`, `lang` (BCP-47) — all applied at the paragraph level without explicit runs, cheaper when the whole paragraph shares one style
|
||||
|
||||
---
|
||||
|
||||
### Slide 4 — Per-Run Typography (font / size / spacing / kern / lang)
|
||||
|
||||
Four textboxes built run-by-run, demonstrating font mixing, character spacing, kerning, and per-run language tagging inside one paragraph.
|
||||
|
||||
```bash
|
||||
officecli add textboxes-advanced.pptx / --type slide
|
||||
|
||||
# Font mixing — four fonts at different sizes in one paragraph
|
||||
officecli add textboxes-advanced.pptx '/slide[4]' --type textbox \
|
||||
--prop x=0.5in --prop y=1.5in --prop width=13in --prop height=1in \
|
||||
--prop text="" --prop size=20
|
||||
|
||||
officecli add textboxes-advanced.pptx '/slide[4]/shape[1]/p[1]' --type run \
|
||||
--prop text="Mix "
|
||||
officecli add textboxes-advanced.pptx '/slide[4]/shape[1]/p[1]' --type run \
|
||||
--prop text="Times " --prop font="Times New Roman" --prop size=24
|
||||
officecli add textboxes-advanced.pptx '/slide[4]/shape[1]/p[1]' --type run \
|
||||
--prop text="Courier " --prop font="Courier New" --prop size=18
|
||||
officecli add textboxes-advanced.pptx '/slide[4]/shape[1]/p[1]' --type run \
|
||||
--prop text="Georgia" --prop font="Georgia" --prop size=28 --prop bold=true
|
||||
|
||||
# Per-run character spacing (1/100 pt; negative = tighter, positive = looser)
|
||||
officecli add textboxes-advanced.pptx '/slide[4]' --type textbox \
|
||||
--prop x=0.5in --prop y=3in --prop width=13in --prop height=1in \
|
||||
--prop text="" --prop size=20 --prop bold=true
|
||||
|
||||
officecli add textboxes-advanced.pptx '/slide[4]/shape[2]/p[1]' --type run \
|
||||
--prop text="Normal "
|
||||
officecli add textboxes-advanced.pptx '/slide[4]/shape[2]/p[1]' --type run \
|
||||
--prop text="TIGHTENED " --prop spacing=-1 --prop color=E63946
|
||||
officecli add textboxes-advanced.pptx '/slide[4]/shape[2]/p[1]' --type run \
|
||||
--prop text="LOOSENED " --prop spacing=4 --prop color=2A9D8F
|
||||
officecli add textboxes-advanced.pptx '/slide[4]/shape[2]/p[1]' --type run \
|
||||
--prop text="EXPANDED" --prop spacing=8 --prop color=1D3557
|
||||
|
||||
# Per-run kerning threshold
|
||||
officecli add textboxes-advanced.pptx '/slide[4]' --type textbox \
|
||||
--prop x=0.5in --prop y=4.3in --prop width=13in --prop height=1in \
|
||||
--prop text="" --prop size=20 --prop bold=true
|
||||
|
||||
officecli add textboxes-advanced.pptx '/slide[4]/shape[3]/p[1]' --type run \
|
||||
--prop text="AV AT WA — kern=0 " --prop kern=0
|
||||
officecli add textboxes-advanced.pptx '/slide[4]/shape[3]/p[1]' --type run \
|
||||
--prop text="AV AT WA — kern=1" --prop kern=1 --prop color=E63946
|
||||
|
||||
# Per-run lang tag — drives spellcheck for each run independently
|
||||
officecli add textboxes-advanced.pptx '/slide[4]' --type textbox \
|
||||
--prop x=0.5in --prop y=5.6in --prop width=13in --prop height=1in \
|
||||
--prop text="" --prop size=20
|
||||
|
||||
officecli add textboxes-advanced.pptx '/slide[4]/shape[4]/p[1]' --type run \
|
||||
--prop text="English: color " --prop lang=en-US
|
||||
officecli add textboxes-advanced.pptx '/slide[4]/shape[4]/p[1]' --type run \
|
||||
--prop text="British: colour " --prop lang=en-GB --prop color=2A9D8F
|
||||
officecli add textboxes-advanced.pptx '/slide[4]/shape[4]/p[1]' --type run \
|
||||
--prop text="Français: couleur" --prop lang=fr-FR --prop color=E63946
|
||||
```
|
||||
|
||||
**Features:** `font` (per-run typeface override), `size` (per-run pt), `spacing` (character spacing in 1/100 pt per run), `kern` (kerning threshold in 1/100 pt per run), `lang` (BCP-47 per-run spellcheck tag)
|
||||
|
||||
---
|
||||
|
||||
### Slide 5 — subscript / superscript Aliases vs canonical baseline=
|
||||
|
||||
`subscript=true` and `superscript=true` are convenience aliases. `baseline=` accepts any signed integer percent for custom vertical offset.
|
||||
|
||||
```bash
|
||||
officecli add textboxes-advanced.pptx / --type slide
|
||||
|
||||
# Convenience aliases: subscript=true / superscript=true
|
||||
officecli add textboxes-advanced.pptx '/slide[5]' --type textbox \
|
||||
--prop x=0.5in --prop y=1.5in --prop width=13in --prop height=1in \
|
||||
--prop text="" --prop size=24
|
||||
|
||||
officecli add textboxes-advanced.pptx '/slide[5]/shape[1]/p[1]' --type run \
|
||||
--prop text="H"
|
||||
officecli add textboxes-advanced.pptx '/slide[5]/shape[1]/p[1]' --type run \
|
||||
--prop text="2" --prop subscript=true
|
||||
officecli add textboxes-advanced.pptx '/slide[5]/shape[1]/p[1]' --type run \
|
||||
--prop text="SO"
|
||||
officecli add textboxes-advanced.pptx '/slide[5]/shape[1]/p[1]' --type run \
|
||||
--prop text="4" --prop subscript=true
|
||||
officecli add textboxes-advanced.pptx '/slide[5]/shape[1]/p[1]' --type run \
|
||||
--prop text=" x"
|
||||
officecli add textboxes-advanced.pptx '/slide[5]/shape[1]/p[1]' --type run \
|
||||
--prop text="2" --prop superscript=true
|
||||
officecli add textboxes-advanced.pptx '/slide[5]/shape[1]/p[1]' --type run \
|
||||
--prop text=" + y"
|
||||
officecli add textboxes-advanced.pptx '/slide[5]/shape[1]/p[1]' --type run \
|
||||
--prop text="2" --prop superscript=true
|
||||
officecli add textboxes-advanced.pptx '/slide[5]/shape[1]/p[1]' --type run \
|
||||
--prop text=" = r"
|
||||
officecli add textboxes-advanced.pptx '/slide[5]/shape[1]/p[1]' --type run \
|
||||
--prop text="2" --prop superscript=true
|
||||
|
||||
# Custom baseline percent — neither alias supports this
|
||||
officecli add textboxes-advanced.pptx '/slide[5]' --type textbox \
|
||||
--prop x=0.5in --prop y=3.7in --prop width=13in --prop height=1in \
|
||||
--prop text="" --prop size=24
|
||||
|
||||
officecli add textboxes-advanced.pptx '/slide[5]/shape[3]/p[1]' --type run \
|
||||
--prop text="Custom: "
|
||||
officecli add textboxes-advanced.pptx '/slide[5]/shape[3]/p[1]' --type run \
|
||||
--prop text="50%" --prop baseline=50 --prop color=E63946
|
||||
officecli add textboxes-advanced.pptx '/slide[5]/shape[3]/p[1]' --type run \
|
||||
--prop text=" higher / "
|
||||
officecli add textboxes-advanced.pptx '/slide[5]/shape[3]/p[1]' --type run \
|
||||
--prop text="-40%" --prop baseline=-40 --prop color=2A9D8F
|
||||
officecli add textboxes-advanced.pptx '/slide[5]/shape[3]/p[1]' --type run \
|
||||
--prop text=" lower"
|
||||
|
||||
# Per-run case: cap=small / cap=all / allCaps boolean alias
|
||||
officecli add textboxes-advanced.pptx '/slide[5]' --type textbox \
|
||||
--prop x=0.5in --prop y=5.9in --prop width=13in --prop height=0.8in \
|
||||
--prop text="" --prop size=20 --prop bold=true
|
||||
|
||||
officecli add textboxes-advanced.pptx '/slide[5]/shape[4]/p[1]' --type run \
|
||||
--prop text="default "
|
||||
officecli add textboxes-advanced.pptx '/slide[5]/shape[4]/p[1]' --type run \
|
||||
--prop text="small caps " --prop cap=small --prop color=2A9D8F
|
||||
officecli add textboxes-advanced.pptx '/slide[5]/shape[4]/p[1]' --type run \
|
||||
--prop text="ALL CAPS" --prop allCaps=true --prop color=E63946
|
||||
```
|
||||
|
||||
**Features:** `subscript` (true — alias for baseline=sub, approx -25%), `superscript` (true — alias for baseline=super, approx +30%), `baseline` (signed integer %; arbitrary vertical offset), `cap` (small, all, none — per-run), `allCaps` / `smallCaps` (boolean aliases for cap=all / cap=small)
|
||||
|
||||
---
|
||||
|
||||
### Slide 6 — name / zorder / autoFit / direction / font.cs (Textbox-Specific)
|
||||
|
||||
Textbox identity, stacking, overflow, and complex-script typography.
|
||||
|
||||
```bash
|
||||
officecli add textboxes-advanced.pptx / --type slide
|
||||
|
||||
# name= — stable @name address for later targeting
|
||||
officecli add textboxes-advanced.pptx '/slide[6]' --type textbox \
|
||||
--prop x=0.5in --prop y=1.2in --prop width=5in --prop height=1.5in \
|
||||
--prop fill=F1FAEE --prop size=16 --prop bold=true \
|
||||
--prop text="This is intro-box." \
|
||||
--prop name="intro-box"
|
||||
|
||||
# zorder= — three overlapping textboxes with explicit stack depth
|
||||
officecli add textboxes-advanced.pptx '/slide[6]' --type textbox \
|
||||
--prop x=6in --prop y=1.2in --prop width=3in --prop height=2in \
|
||||
--prop fill=4472C4 --prop color=FFFFFF --prop bold=true --prop size=16 \
|
||||
--prop text="back (zorder=1)" \
|
||||
--prop name="tb-back" --prop zorder=1
|
||||
|
||||
officecli add textboxes-advanced.pptx '/slide[6]' --type textbox \
|
||||
--prop x=7in --prop y=1.6in --prop width=3in --prop height=2in \
|
||||
--prop fill=E63946 --prop color=FFFFFF --prop bold=true --prop size=16 \
|
||||
--prop text="mid (zorder=2)" \
|
||||
--prop name="tb-mid" --prop zorder=2
|
||||
|
||||
officecli add textboxes-advanced.pptx '/slide[6]' --type textbox \
|
||||
--prop x=8in --prop y=2.0in --prop width=3in --prop height=2in \
|
||||
--prop fill=2A9D8F --prop color=FFFFFF --prop bold=true --prop size=16 \
|
||||
--prop text="front (zorder=3)" \
|
||||
--prop name="tb-front" --prop zorder=3
|
||||
|
||||
# autoFit=normal — text shrinks to fit a fixed-height box
|
||||
LONGTEXT='Vivamus lacinia odio vitae vestibulum vestibulum. Sed molestie augue sit amet leo consequat posuere.'
|
||||
officecli add textboxes-advanced.pptx '/slide[6]' --type textbox \
|
||||
--prop x=0.5in --prop y=3.6in --prop width=3in --prop height=1.2in \
|
||||
--prop fill=FFE66D --prop size=16 --prop text="$LONGTEXT" \
|
||||
--prop autoFit=normal
|
||||
|
||||
# direction=rtl + font.cs — RTL textbox with complex-script font
|
||||
officecli add textboxes-advanced.pptx '/slide[6]' --type textbox \
|
||||
--prop x=0.5in --prop y=5.6in --prop width=5in --prop height=1.2in \
|
||||
--prop fill=A8DADC --prop size=20 --prop bold=true \
|
||||
--prop text="مرحبا بالعالم — 2026" \
|
||||
--prop direction=rtl --prop align=right \
|
||||
--prop font.cs="Arabic Typesetting"
|
||||
|
||||
officecli close textboxes-advanced.pptx
|
||||
officecli validate textboxes-advanced.pptx
|
||||
```
|
||||
|
||||
**Features:** `name` (stable identifier; addressable as `/slide[N]/shape[@name=...]`), `zorder` (integer stack depth; aliases: z-order, order), `autoFit` (normal — text shrinks), `direction` (rtl; aliases: dir, rtl), `font.cs` (complex-script font slot), `align=right` (combined with rtl for correct Arabic/Hebrew layout)
|
||||
|
||||
---
|
||||
|
||||
## Complete Feature Coverage
|
||||
|
||||
| Feature | Slide |
|
||||
|---------|-------|
|
||||
| **Per-paragraph align override:** center, right, justify inside one textbox | 1 |
|
||||
| **Per-paragraph lineSpacing override:** multiplier (2x) + fixed (18pt) | 1 |
|
||||
| **marginLeft:** left indent (whole paragraph) | 2 |
|
||||
| **indent:** first-line indent only (negative = hanging) | 2 |
|
||||
| **marginRight:** narrow text from right edge | 2 |
|
||||
| **Per-paragraph bold / italic:** whole paragraph style, no run needed | 3 |
|
||||
| **Per-paragraph color / size:** whole paragraph style | 3 |
|
||||
| **Per-paragraph lang:** BCP-47 spellcheck tag at paragraph scope | 3 |
|
||||
| **Per-run font:** typeface override | 4 |
|
||||
| **Per-run size:** point size override | 4 |
|
||||
| **Per-run spacing:** character spacing in 1/100 pt | 4 |
|
||||
| **Per-run kern:** kerning threshold in 1/100 pt | 4 |
|
||||
| **Per-run lang:** BCP-47 spellcheck tag at run scope | 4 |
|
||||
| **subscript / superscript:** boolean aliases for baseline=sub/super | 5 |
|
||||
| **baseline:** signed integer % — arbitrary vertical offset | 5 |
|
||||
| **Per-run cap:** small, all, none | 5 |
|
||||
| **allCaps / smallCaps:** boolean aliases for cap=all/small | 5 |
|
||||
| **name=:** stable @name addressing | 6 |
|
||||
| **zorder=:** explicit stack depth | 6 |
|
||||
| **autoFit=normal:** text shrinks to fit fixed box | 6 |
|
||||
| **direction=rtl:** RTL paragraph direction in textbox | 6 |
|
||||
| **font.cs:** complex-script font slot | 6 |
|
||||
|
||||
## Inspect the Generated File
|
||||
|
||||
```bash
|
||||
# Check per-paragraph overrides in the slide 1 textbox
|
||||
officecli get textboxes-advanced.pptx '/slide[1]/shape[2]'
|
||||
officecli query textboxes-advanced.pptx '/slide[1]/shape[2]' paragraph
|
||||
|
||||
# Inspect indent values on slide 2
|
||||
officecli get textboxes-advanced.pptx '/slide[2]/shape[3]'
|
||||
officecli get textboxes-advanced.pptx '/slide[2]/shape[4]'
|
||||
|
||||
# Get per-run font data on slide 4 shape 1
|
||||
officecli query textboxes-advanced.pptx '/slide[4]/shape[1]/p[1]' run
|
||||
|
||||
# Check baseline values on slide 5
|
||||
officecli get textboxes-advanced.pptx '/slide[5]/shape[3]'
|
||||
|
||||
# Verify name + zorder on slide 6
|
||||
officecli get textboxes-advanced.pptx '/slide[6]/shape[@name=tb-back]'
|
||||
officecli get textboxes-advanced.pptx '/slide[6]/shape[@name=tb-front]'
|
||||
```
|
||||
Binary file not shown.
@@ -0,0 +1,334 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Advanced PPT textbox typography — per-paragraph and per-run overrides that the
|
||||
basic example didn't reach. Each slide demonstrates a different scope:
|
||||
slide 1 — per-paragraph align / lineSpacing override (shape default vs paragraph)
|
||||
slide 2 — paragraph indents (indent / marginLeft / marginRight) for hanging-indent style
|
||||
slide 3 — per-paragraph styling (bold / italic / color / size / lang) without runs
|
||||
slide 4 — per-run typography (font / size / spacing / kern / lang) inside one paragraph
|
||||
slide 5 — subscript / superscript convenience aliases vs canonical baseline=
|
||||
slide 6 — name / zorder / autoFit / direction / font.cs (textbox-specific)
|
||||
|
||||
SDK twin of textboxes-advanced.sh (officecli CLI). Both produce an equivalent
|
||||
textboxes-advanced.pptx. This one drives the **officecli Python SDK**
|
||||
(`pip install officecli-sdk`): one resident is started and every slide, shape,
|
||||
paragraph and run is shipped over the named pipe in a single `doc.batch(...)`
|
||||
round-trip. Each item is the same `{"command","parent","type","props"}` dict
|
||||
you'd put in an `officecli batch` list.
|
||||
|
||||
Usage:
|
||||
pip install officecli-sdk # plus the `officecli` binary on PATH
|
||||
python3 textboxes-advanced.py
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
# --- locate the SDK: prefer an installed `officecli-sdk`, else the in-repo copy
|
||||
try:
|
||||
import officecli # pip install officecli-sdk
|
||||
except ImportError:
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)),
|
||||
"..", "..", "..", "sdk", "python"))
|
||||
import officecli
|
||||
|
||||
FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "textboxes-advanced.pptx")
|
||||
|
||||
LOREM = ("Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
|
||||
"Vivamus lacinia odio vitae vestibulum vestibulum.")
|
||||
LONGTEXT = ("Vivamus lacinia odio vitae vestibulum vestibulum. "
|
||||
"Sed molestie augue sit amet leo consequat posuere.")
|
||||
|
||||
|
||||
def add(parent, type_, **props):
|
||||
"""One `add` item in batch-shape."""
|
||||
return {"command": "add", "parent": parent, "type": type_, "props": props}
|
||||
|
||||
|
||||
def slide():
|
||||
return {"command": "add", "parent": "/", "type": "slide", "props": {}}
|
||||
|
||||
|
||||
print(f"Building {FILE} ...")
|
||||
|
||||
with officecli.create(FILE, "--force") as doc:
|
||||
items = [
|
||||
# =====================================================================
|
||||
# Slide 1 — Per-paragraph overrides (align / lineSpacing in one textbox)
|
||||
# =====================================================================
|
||||
slide(),
|
||||
add("/slide[1]", "textbox",
|
||||
text="Per-paragraph overrides inside one textbox",
|
||||
size="28", bold="true",
|
||||
x="0.5in", y="0.3in", width="12in", height="0.6in"),
|
||||
|
||||
# One textbox; shape-level defaults are align=left, lineSpacing=1x.
|
||||
# Each paragraph overrides one of them.
|
||||
add("/slide[1]", "textbox",
|
||||
x="0.5in", y="1.2in", width="13in", height="5.5in",
|
||||
fill="F1FAEE", size="14",
|
||||
text=f"[shape default: align=left, single-spaced] {LOREM}"),
|
||||
add("/slide[1]/shape[2]", "paragraph",
|
||||
text=f"[paragraph override: align=center] {LOREM}", align="center"),
|
||||
add("/slide[1]/shape[2]", "paragraph",
|
||||
text=f"[paragraph override: align=right] {LOREM}", align="right"),
|
||||
add("/slide[1]/shape[2]", "paragraph",
|
||||
text=f"[paragraph override: align=justify + lineSpacing=2x] {LOREM} {LOREM}",
|
||||
align="justify", lineSpacing="2x"),
|
||||
add("/slide[1]/shape[2]", "paragraph",
|
||||
text=f"[paragraph override: lineSpacing=18pt fixed] {LOREM}",
|
||||
lineSpacing="18pt"),
|
||||
|
||||
# =====================================================================
|
||||
# Slide 2 — Paragraph indents (indent / marginLeft / marginRight)
|
||||
# =====================================================================
|
||||
slide(),
|
||||
add("/slide[2]", "textbox",
|
||||
text="Paragraph indents — indent / marginLeft / marginRight",
|
||||
size="28", bold="true",
|
||||
x="0.5in", y="0.3in", width="12in", height="0.6in"),
|
||||
|
||||
# Reference (no indent)
|
||||
add("/slide[2]", "textbox",
|
||||
x="0.5in", y="1.3in", width="13in", height="1in",
|
||||
fill="F1FAEE", size="14",
|
||||
text=f"[default: no indent] {LOREM} {LOREM}"),
|
||||
# Left indent (whole paragraph shifted right)
|
||||
add("/slide[2]", "textbox",
|
||||
x="0.5in", y="2.5in", width="13in", height="1in",
|
||||
fill="A8DADC", size="14",
|
||||
text=f"[marginLeft=1in] {LOREM} {LOREM}",
|
||||
marginLeft="1in"),
|
||||
# First-line indent (only first line is shifted; rest flush left)
|
||||
add("/slide[2]", "textbox",
|
||||
x="0.5in", y="3.7in", width="13in", height="1in",
|
||||
fill="F4A261", size="14",
|
||||
text=f"[indent=0.5in first-line] {LOREM} {LOREM}",
|
||||
indent="0.5in"),
|
||||
# Hanging indent (negative indent + positive marginLeft pulls first line back left)
|
||||
add("/slide[2]", "textbox",
|
||||
x="0.5in", y="4.9in", width="13in", height="1in",
|
||||
fill="A8DADC", size="14",
|
||||
text=f"[hanging: marginLeft=0.6in + indent=-0.5in] {LOREM} {LOREM}",
|
||||
marginLeft="0.6in", indent="-0.5in"),
|
||||
# Right margin (text narrowed from the right)
|
||||
add("/slide[2]", "textbox",
|
||||
x="0.5in", y="6.1in", width="13in", height="1in",
|
||||
fill="F4A261", size="14",
|
||||
text=f"[marginRight=2in] {LOREM} {LOREM}",
|
||||
marginRight="2in"),
|
||||
|
||||
# =====================================================================
|
||||
# Slide 3 — Per-paragraph styling (bold / italic / color / size / lang)
|
||||
# =====================================================================
|
||||
slide(),
|
||||
add("/slide[3]", "textbox",
|
||||
text="Per-paragraph styling (no runs needed)",
|
||||
size="28", bold="true",
|
||||
x="0.5in", y="0.3in", width="12in", height="0.6in"),
|
||||
|
||||
# One textbox; each paragraph carries its own bold/italic/color/size/lang.
|
||||
add("/slide[3]", "textbox",
|
||||
x="0.5in", y="1.2in", width="13in", height="5in",
|
||||
fill="F1FAEE", size="14",
|
||||
text="[shape default: 14pt black] Default paragraph styling."),
|
||||
add("/slide[3]/shape[2]", "paragraph",
|
||||
text="[bold=true at paragraph level] Whole paragraph is bold.",
|
||||
bold="true"),
|
||||
add("/slide[3]/shape[2]", "paragraph",
|
||||
text="[italic=true at paragraph level] Whole paragraph is italic.",
|
||||
italic="true"),
|
||||
add("/slide[3]/shape[2]", "paragraph",
|
||||
text="[color=E63946 at paragraph level] Whole paragraph is red.",
|
||||
color="E63946"),
|
||||
add("/slide[3]/shape[2]", "paragraph",
|
||||
text="[size=22 at paragraph level] Whole paragraph is 22pt.",
|
||||
size="22"),
|
||||
add("/slide[3]/shape[2]", "paragraph",
|
||||
text="[lang=fr-FR at paragraph level] Lorem ipsum dolor sit amet.",
|
||||
lang="fr-FR", color="2A9D8F"),
|
||||
|
||||
# =====================================================================
|
||||
# Slide 4 — Per-run typography (font / size / spacing / kern / lang)
|
||||
# =====================================================================
|
||||
slide(),
|
||||
add("/slide[4]", "textbox",
|
||||
text="Per-run typography in one paragraph",
|
||||
size="28", bold="true",
|
||||
x="0.5in", y="0.3in", width="12in", height="0.6in"),
|
||||
|
||||
# Empty textbox we'll build run-by-run
|
||||
add("/slide[4]", "textbox",
|
||||
x="0.5in", y="1.5in", width="13in", height="1in",
|
||||
text="", size="20"),
|
||||
add("/slide[4]/shape[1]/p[1]", "run", text="Mix "),
|
||||
add("/slide[4]/shape[1]/p[1]", "run",
|
||||
text="Times ", font="Times New Roman", size="24"),
|
||||
add("/slide[4]/shape[1]/p[1]", "run",
|
||||
text="Courier ", font="Courier New", size="18"),
|
||||
add("/slide[4]/shape[1]/p[1]", "run",
|
||||
text="Georgia", font="Georgia", size="28", bold="true"),
|
||||
|
||||
# Per-run character spacing
|
||||
add("/slide[4]", "textbox",
|
||||
x="0.5in", y="3in", width="13in", height="1in",
|
||||
text="", size="20", bold="true"),
|
||||
add("/slide[4]/shape[2]/p[1]", "run", text="Normal "),
|
||||
add("/slide[4]/shape[2]/p[1]", "run",
|
||||
text="TIGHTENED ", spacing="-1", color="E63946"),
|
||||
add("/slide[4]/shape[2]/p[1]", "run",
|
||||
text="LOOSENED ", spacing="4", color="2A9D8F"),
|
||||
add("/slide[4]/shape[2]/p[1]", "run",
|
||||
text="EXPANDED", spacing="8", color="1D3557"),
|
||||
|
||||
# Per-run kerning threshold
|
||||
add("/slide[4]", "textbox",
|
||||
x="0.5in", y="4.3in", width="13in", height="1in",
|
||||
text="", size="20", bold="true"),
|
||||
add("/slide[4]/shape[3]/p[1]", "run",
|
||||
text="AV AT WA — kern=0 ", kern="0"),
|
||||
add("/slide[4]/shape[3]/p[1]", "run",
|
||||
text="AV AT WA — kern=1", kern="1", color="E63946"),
|
||||
|
||||
# Per-run lang tag (drives spellcheck per-run)
|
||||
add("/slide[4]", "textbox",
|
||||
x="0.5in", y="5.6in", width="13in", height="1in",
|
||||
text="", size="20"),
|
||||
add("/slide[4]/shape[4]/p[1]", "run",
|
||||
text="English: color ", lang="en-US"),
|
||||
add("/slide[4]/shape[4]/p[1]", "run",
|
||||
text="British: colour ", lang="en-GB", color="2A9D8F"),
|
||||
add("/slide[4]/shape[4]/p[1]", "run",
|
||||
text="Français: couleur", lang="fr-FR", color="E63946"),
|
||||
|
||||
# =====================================================================
|
||||
# Slide 5 — subscript / superscript aliases vs canonical baseline=
|
||||
# =====================================================================
|
||||
slide(),
|
||||
add("/slide[5]", "textbox",
|
||||
text="subscript / superscript aliases",
|
||||
size="28", bold="true",
|
||||
x="0.5in", y="0.3in", width="12in", height="0.6in"),
|
||||
|
||||
# Convenience form: subscript=true and superscript=true
|
||||
add("/slide[5]", "textbox",
|
||||
x="0.5in", y="1.5in", width="13in", height="1in",
|
||||
text="", size="24"),
|
||||
add("/slide[5]/shape[1]/p[1]", "run", text="H"),
|
||||
add("/slide[5]/shape[1]/p[1]", "run", text="2", subscript="true"),
|
||||
add("/slide[5]/shape[1]/p[1]", "run", text="SO"),
|
||||
add("/slide[5]/shape[1]/p[1]", "run", text="4", subscript="true"),
|
||||
add("/slide[5]/shape[1]/p[1]", "run", text=" x"),
|
||||
add("/slide[5]/shape[1]/p[1]", "run", text="2", superscript="true"),
|
||||
add("/slide[5]/shape[1]/p[1]", "run", text=" + y"),
|
||||
add("/slide[5]/shape[1]/p[1]", "run", text="2", superscript="true"),
|
||||
add("/slide[5]/shape[1]/p[1]", "run", text=" = r"),
|
||||
add("/slide[5]/shape[1]/p[1]", "run", text="2", superscript="true"),
|
||||
|
||||
add("/slide[5]", "textbox",
|
||||
text="subscript=true ≡ baseline=sub superscript=true ≡ baseline=super",
|
||||
size="14", italic="true", color="666666",
|
||||
x="0.5in", y="2.8in", width="13in", height="0.5in"),
|
||||
|
||||
# Custom baseline percent — neither alias gives you this
|
||||
add("/slide[5]", "textbox",
|
||||
x="0.5in", y="3.7in", width="13in", height="1in",
|
||||
text="", size="24"),
|
||||
add("/slide[5]/shape[3]/p[1]", "run", text="Custom: "),
|
||||
add("/slide[5]/shape[3]/p[1]", "run",
|
||||
text="50%", baseline="50", color="E63946"),
|
||||
add("/slide[5]/shape[3]/p[1]", "run", text=" higher / "),
|
||||
add("/slide[5]/shape[3]/p[1]", "run",
|
||||
text="-40%", baseline="-40", color="2A9D8F"),
|
||||
add("/slide[5]/shape[3]/p[1]", "run", text=" lower"),
|
||||
|
||||
add("/slide[5]", "textbox",
|
||||
text=("baseline= accepts signed integer percent (super≡+30, sub≡-25 by "
|
||||
"convention). Custom values give arbitrary vertical offset."),
|
||||
size="14", italic="true", color="666666",
|
||||
x="0.5in", y="5in", width="13in", height="0.6in"),
|
||||
|
||||
# Per-run case rendering — run Add accepts cap / allCaps / smallCaps
|
||||
add("/slide[5]", "textbox",
|
||||
x="0.5in", y="5.9in", width="13in", height="0.8in",
|
||||
text="", size="20", bold="true"),
|
||||
add("/slide[5]/shape[4]/p[1]", "run", text="default "),
|
||||
add("/slide[5]/shape[4]/p[1]", "run",
|
||||
text="small caps ", cap="small", color="2A9D8F"),
|
||||
add("/slide[5]/shape[4]/p[1]", "run",
|
||||
text="ALL CAPS", allCaps="true", color="E63946"),
|
||||
|
||||
add("/slide[5]", "textbox",
|
||||
text="Per-run cap=small / cap=all / cap=none, plus allCaps / smallCaps boolean aliases.",
|
||||
size="12", italic="true", color="666666",
|
||||
x="0.5in", y="6.8in", width="13in", height="0.5in"),
|
||||
|
||||
# =====================================================================
|
||||
# Slide 6 — name / zorder / autoFit / direction / font.cs
|
||||
# =====================================================================
|
||||
slide(),
|
||||
add("/slide[6]", "textbox",
|
||||
text="name / zorder / autoFit / direction / font.cs",
|
||||
size="28", bold="true",
|
||||
x="0.5in", y="0.3in", width="13in", height="0.6in"),
|
||||
|
||||
# name= — label the textbox so it can be re-addressed by @name later
|
||||
add("/slide[6]", "textbox",
|
||||
x="0.5in", y="1.2in", width="5in", height="1.5in",
|
||||
fill="F1FAEE", size="16", bold="true",
|
||||
text="This is intro-box.",
|
||||
name="intro-box"),
|
||||
add("/slide[6]", "textbox",
|
||||
text='name="intro-box" → addressable as /slide[6]/shape[@name=intro-box]',
|
||||
size="12", italic="true", color="666666",
|
||||
x="0.5in", y="2.8in", width="5in", height="0.5in"),
|
||||
|
||||
# zorder= — three overlapping textboxes with explicit stack order
|
||||
add("/slide[6]", "textbox",
|
||||
x="6in", y="1.2in", width="3in", height="2in",
|
||||
fill="4472C4", color="FFFFFF", bold="true", size="16",
|
||||
text="back (zorder=1)",
|
||||
name="tb-back", zorder="1"),
|
||||
add("/slide[6]", "textbox",
|
||||
x="7in", y="1.6in", width="3in", height="2in",
|
||||
fill="E63946", color="FFFFFF", bold="true", size="16",
|
||||
text="mid (zorder=2)",
|
||||
name="tb-mid", zorder="2"),
|
||||
add("/slide[6]", "textbox",
|
||||
x="8in", y="2.0in", width="3in", height="2in",
|
||||
fill="2A9D8F", color="FFFFFF", bold="true", size="16",
|
||||
text="front (zorder=3)",
|
||||
name="tb-front", zorder="3"),
|
||||
add("/slide[6]", "textbox",
|
||||
text="zorder= controls stack depth; aliases: z-order, order.",
|
||||
size="12", italic="true", color="666666",
|
||||
x="6in", y="4.2in", width="5in", height="0.5in"),
|
||||
|
||||
# autoFit= — overflow behavior for textbox (same as shape)
|
||||
add("/slide[6]", "textbox",
|
||||
x="0.5in", y="3.6in", width="3in", height="1.2in",
|
||||
fill="FFE66D", size="16", text=LONGTEXT,
|
||||
autoFit="normal"),
|
||||
add("/slide[6]", "textbox",
|
||||
text="autoFit=normal (shrinks text to fit)",
|
||||
size="12", italic="true", color="666666",
|
||||
x="0.5in", y="4.9in", width="3in", height="0.5in"),
|
||||
|
||||
# direction=rtl — paragraph flows right-to-left inside a textbox
|
||||
add("/slide[6]", "textbox",
|
||||
x="0.5in", y="5.6in", width="5in", height="1.2in",
|
||||
fill="A8DADC", size="20", bold="true",
|
||||
text="مرحبا بالعالم — 2026",
|
||||
direction="rtl", align="right",
|
||||
**{"font.cs": "Arabic Typesetting"}),
|
||||
add("/slide[6]", "textbox",
|
||||
text='direction=rtl + font.cs="Arabic Typesetting" (complex-script slot)',
|
||||
size="12", italic="true", color="666666",
|
||||
x="0.5in", y="6.9in", width="5in", height="0.5in"),
|
||||
]
|
||||
|
||||
doc.batch(items)
|
||||
print(f" added {len(items)} slides/shapes/paragraphs/runs")
|
||||
doc.send({"command": "save"})
|
||||
|
||||
print(f"Generated: {FILE}")
|
||||
Executable
+330
@@ -0,0 +1,330 @@
|
||||
#!/bin/bash
|
||||
# Advanced PPT textbox typography — per-paragraph and per-run overrides that the
|
||||
# basic example didn't reach. Each slide demonstrates a different scope:
|
||||
# slide 1 — per-paragraph align / lineSpacing override (shape default vs paragraph)
|
||||
# slide 2 — paragraph indents (indent / marginLeft / marginRight) for hanging-indent style
|
||||
# slide 3 — per-paragraph styling (bold / italic / color / size / lang) without runs
|
||||
# slide 4 — per-run typography (font / size / spacing / kern / lang) inside one paragraph
|
||||
# slide 5 — subscript / superscript convenience aliases vs canonical baseline=
|
||||
|
||||
# NOTE: intentionally NO `set -e`. Like the SDK twin's doc.batch, this script
|
||||
# tolerates forward-compat 'UNSUPPORTED props' warnings (officecli exit 2) and
|
||||
# keeps building so the full document is produced.
|
||||
DIR="$(dirname "$0")"
|
||||
PPTX="$DIR/textboxes-advanced.pptx"
|
||||
|
||||
rm -f "$PPTX"
|
||||
officecli create "$PPTX"
|
||||
officecli open "$PPTX"
|
||||
|
||||
LOREM='Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus lacinia odio vitae vestibulum vestibulum.'
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# Slide 1 — Per-paragraph overrides (align / lineSpacing inside one textbox)
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
officecli add "$PPTX" / --type slide
|
||||
officecli add "$PPTX" '/slide[1]' --type textbox \
|
||||
--prop text="Per-paragraph overrides inside one textbox" \
|
||||
--prop size=28 --prop bold=true \
|
||||
--prop x=0.5in --prop y=0.3in --prop width=12in --prop height=0.6in
|
||||
|
||||
# One textbox; shape-level defaults are align=left, lineSpacing=1x.
|
||||
# Each paragraph overrides one of them.
|
||||
officecli add "$PPTX" '/slide[1]' --type textbox \
|
||||
--prop x=0.5in --prop y=1.2in --prop width=13in --prop height=5.5in \
|
||||
--prop fill=F1FAEE --prop size=14 \
|
||||
--prop text="[shape default: align=left, single-spaced] $LOREM"
|
||||
|
||||
officecli add "$PPTX" '/slide[1]/shape[2]' --type paragraph \
|
||||
--prop text="[paragraph override: align=center] $LOREM" --prop align=center
|
||||
|
||||
officecli add "$PPTX" '/slide[1]/shape[2]' --type paragraph \
|
||||
--prop text="[paragraph override: align=right] $LOREM" --prop align=right
|
||||
|
||||
officecli add "$PPTX" '/slide[1]/shape[2]' --type paragraph \
|
||||
--prop text="[paragraph override: align=justify + lineSpacing=2x] $LOREM $LOREM" \
|
||||
--prop align=justify --prop lineSpacing=2x
|
||||
|
||||
officecli add "$PPTX" '/slide[1]/shape[2]' --type paragraph \
|
||||
--prop text="[paragraph override: lineSpacing=18pt fixed] $LOREM" \
|
||||
--prop lineSpacing=18pt
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# Slide 2 — Paragraph indents (indent / marginLeft / marginRight)
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
officecli add "$PPTX" / --type slide
|
||||
officecli add "$PPTX" '/slide[2]' --type textbox \
|
||||
--prop text="Paragraph indents — indent / marginLeft / marginRight" \
|
||||
--prop size=28 --prop bold=true \
|
||||
--prop x=0.5in --prop y=0.3in --prop width=12in --prop height=0.6in
|
||||
|
||||
# Reference (no indent)
|
||||
officecli add "$PPTX" '/slide[2]' --type textbox \
|
||||
--prop x=0.5in --prop y=1.3in --prop width=13in --prop height=1in \
|
||||
--prop fill=F1FAEE --prop size=14 \
|
||||
--prop text="[default: no indent] $LOREM $LOREM"
|
||||
|
||||
# Left indent (whole paragraph shifted right)
|
||||
officecli add "$PPTX" '/slide[2]' --type textbox \
|
||||
--prop x=0.5in --prop y=2.5in --prop width=13in --prop height=1in \
|
||||
--prop fill=A8DADC --prop size=14 \
|
||||
--prop text="[marginLeft=1in] $LOREM $LOREM" \
|
||||
--prop marginLeft=1in
|
||||
|
||||
# First-line indent (only first line is shifted; rest flush left)
|
||||
officecli add "$PPTX" '/slide[2]' --type textbox \
|
||||
--prop x=0.5in --prop y=3.7in --prop width=13in --prop height=1in \
|
||||
--prop fill=F4A261 --prop size=14 \
|
||||
--prop text="[indent=0.5in first-line] $LOREM $LOREM" \
|
||||
--prop indent=0.5in
|
||||
|
||||
# Hanging indent (negative indent + positive marginLeft pulls first line back left)
|
||||
officecli add "$PPTX" '/slide[2]' --type textbox \
|
||||
--prop x=0.5in --prop y=4.9in --prop width=13in --prop height=1in \
|
||||
--prop fill=A8DADC --prop size=14 \
|
||||
--prop text="[hanging: marginLeft=0.6in + indent=-0.5in] $LOREM $LOREM" \
|
||||
--prop marginLeft=0.6in --prop indent=-0.5in
|
||||
|
||||
# Right margin (text narrowed from the right)
|
||||
officecli add "$PPTX" '/slide[2]' --type textbox \
|
||||
--prop x=0.5in --prop y=6.1in --prop width=13in --prop height=1in \
|
||||
--prop fill=F4A261 --prop size=14 \
|
||||
--prop text="[marginRight=2in] $LOREM $LOREM" \
|
||||
--prop marginRight=2in
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# Slide 3 — Per-paragraph styling (bold / italic / color / size / lang)
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
officecli add "$PPTX" / --type slide
|
||||
officecli add "$PPTX" '/slide[3]' --type textbox \
|
||||
--prop text="Per-paragraph styling (no runs needed)" \
|
||||
--prop size=28 --prop bold=true \
|
||||
--prop x=0.5in --prop y=0.3in --prop width=12in --prop height=0.6in
|
||||
|
||||
# One textbox; each paragraph carries its own bold/italic/color/size/lang.
|
||||
# This is cheaper than adding a run when the whole paragraph shares one style.
|
||||
officecli add "$PPTX" '/slide[3]' --type textbox \
|
||||
--prop x=0.5in --prop y=1.2in --prop width=13in --prop height=5in \
|
||||
--prop fill=F1FAEE --prop size=14 \
|
||||
--prop text="[shape default: 14pt black] Default paragraph styling."
|
||||
|
||||
officecli add "$PPTX" '/slide[3]/shape[2]' --type paragraph \
|
||||
--prop text="[bold=true at paragraph level] Whole paragraph is bold." \
|
||||
--prop bold=true
|
||||
|
||||
officecli add "$PPTX" '/slide[3]/shape[2]' --type paragraph \
|
||||
--prop text="[italic=true at paragraph level] Whole paragraph is italic." \
|
||||
--prop italic=true
|
||||
|
||||
officecli add "$PPTX" '/slide[3]/shape[2]' --type paragraph \
|
||||
--prop text="[color=E63946 at paragraph level] Whole paragraph is red." \
|
||||
--prop color=E63946
|
||||
|
||||
officecli add "$PPTX" '/slide[3]/shape[2]' --type paragraph \
|
||||
--prop text="[size=22 at paragraph level] Whole paragraph is 22pt." \
|
||||
--prop size=22
|
||||
|
||||
officecli add "$PPTX" '/slide[3]/shape[2]' --type paragraph \
|
||||
--prop text="[lang=fr-FR at paragraph level] Lorem ipsum dolor sit amet." \
|
||||
--prop lang=fr-FR --prop color=2A9D8F
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# Slide 4 — Per-run typography (font / size / spacing / kern / lang in one paragraph)
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
officecli add "$PPTX" / --type slide
|
||||
officecli add "$PPTX" '/slide[4]' --type textbox \
|
||||
--prop text="Per-run typography in one paragraph" \
|
||||
--prop size=28 --prop bold=true \
|
||||
--prop x=0.5in --prop y=0.3in --prop width=12in --prop height=0.6in
|
||||
|
||||
# Empty textbox we'll build run-by-run
|
||||
officecli add "$PPTX" '/slide[4]' --type textbox \
|
||||
--prop x=0.5in --prop y=1.5in --prop width=13in --prop height=1in \
|
||||
--prop text="" --prop size=20
|
||||
|
||||
officecli add "$PPTX" '/slide[4]/shape[1]/p[1]' --type run --prop text="Mix "
|
||||
officecli add "$PPTX" '/slide[4]/shape[1]/p[1]' --type run \
|
||||
--prop text="Times " --prop font="Times New Roman" --prop size=24
|
||||
officecli add "$PPTX" '/slide[4]/shape[1]/p[1]' --type run \
|
||||
--prop text="Courier " --prop font="Courier New" --prop size=18
|
||||
officecli add "$PPTX" '/slide[4]/shape[1]/p[1]' --type run \
|
||||
--prop text="Georgia" --prop font="Georgia" --prop size=28 --prop bold=true
|
||||
|
||||
# Per-run character spacing
|
||||
officecli add "$PPTX" '/slide[4]' --type textbox \
|
||||
--prop x=0.5in --prop y=3in --prop width=13in --prop height=1in \
|
||||
--prop text="" --prop size=20 --prop bold=true
|
||||
|
||||
officecli add "$PPTX" '/slide[4]/shape[2]/p[1]' --type run --prop text="Normal "
|
||||
officecli add "$PPTX" '/slide[4]/shape[2]/p[1]' --type run \
|
||||
--prop text="TIGHTENED " --prop spacing=-1 --prop color=E63946
|
||||
officecli add "$PPTX" '/slide[4]/shape[2]/p[1]' --type run \
|
||||
--prop text="LOOSENED " --prop spacing=4 --prop color=2A9D8F
|
||||
officecli add "$PPTX" '/slide[4]/shape[2]/p[1]' --type run \
|
||||
--prop text="EXPANDED" --prop spacing=8 --prop color=1D3557
|
||||
|
||||
# Per-run kerning threshold
|
||||
officecli add "$PPTX" '/slide[4]' --type textbox \
|
||||
--prop x=0.5in --prop y=4.3in --prop width=13in --prop height=1in \
|
||||
--prop text="" --prop size=20 --prop bold=true
|
||||
|
||||
officecli add "$PPTX" '/slide[4]/shape[3]/p[1]' --type run \
|
||||
--prop text="AV AT WA — kern=0 " --prop kern=0
|
||||
officecli add "$PPTX" '/slide[4]/shape[3]/p[1]' --type run \
|
||||
--prop text="AV AT WA — kern=1" --prop kern=1 --prop color=E63946
|
||||
|
||||
# Per-run lang tag (drives spellcheck per-run)
|
||||
officecli add "$PPTX" '/slide[4]' --type textbox \
|
||||
--prop x=0.5in --prop y=5.6in --prop width=13in --prop height=1in \
|
||||
--prop text="" --prop size=20
|
||||
|
||||
officecli add "$PPTX" '/slide[4]/shape[4]/p[1]' --type run \
|
||||
--prop text="English: color " --prop lang=en-US
|
||||
officecli add "$PPTX" '/slide[4]/shape[4]/p[1]' --type run \
|
||||
--prop text="British: colour " --prop lang=en-GB --prop color=2A9D8F
|
||||
officecli add "$PPTX" '/slide[4]/shape[4]/p[1]' --type run \
|
||||
--prop text="Français: couleur" --prop lang=fr-FR --prop color=E63946
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# Slide 5 — subscript / superscript aliases vs canonical baseline=
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
officecli add "$PPTX" / --type slide
|
||||
officecli add "$PPTX" '/slide[5]' --type textbox \
|
||||
--prop text="subscript / superscript aliases" \
|
||||
--prop size=28 --prop bold=true \
|
||||
--prop x=0.5in --prop y=0.3in --prop width=12in --prop height=0.6in
|
||||
|
||||
# Convenience form: subscript=true and superscript=true
|
||||
officecli add "$PPTX" '/slide[5]' --type textbox \
|
||||
--prop x=0.5in --prop y=1.5in --prop width=13in --prop height=1in \
|
||||
--prop text="" --prop size=24
|
||||
|
||||
officecli add "$PPTX" '/slide[5]/shape[1]/p[1]' --type run --prop text="H"
|
||||
officecli add "$PPTX" '/slide[5]/shape[1]/p[1]' --type run \
|
||||
--prop text="2" --prop subscript=true
|
||||
officecli add "$PPTX" '/slide[5]/shape[1]/p[1]' --type run --prop text="SO"
|
||||
officecli add "$PPTX" '/slide[5]/shape[1]/p[1]' --type run \
|
||||
--prop text="4" --prop subscript=true
|
||||
officecli add "$PPTX" '/slide[5]/shape[1]/p[1]' --type run --prop text=" x"
|
||||
officecli add "$PPTX" '/slide[5]/shape[1]/p[1]' --type run \
|
||||
--prop text="2" --prop superscript=true
|
||||
officecli add "$PPTX" '/slide[5]/shape[1]/p[1]' --type run --prop text=" + y"
|
||||
officecli add "$PPTX" '/slide[5]/shape[1]/p[1]' --type run \
|
||||
--prop text="2" --prop superscript=true
|
||||
officecli add "$PPTX" '/slide[5]/shape[1]/p[1]' --type run --prop text=" = r"
|
||||
officecli add "$PPTX" '/slide[5]/shape[1]/p[1]' --type run \
|
||||
--prop text="2" --prop superscript=true
|
||||
|
||||
officecli add "$PPTX" '/slide[5]' --type textbox \
|
||||
--prop text='subscript=true ≡ baseline=sub superscript=true ≡ baseline=super' \
|
||||
--prop size=14 --prop italic=true --prop color=666666 \
|
||||
--prop x=0.5in --prop y=2.8in --prop width=13in --prop height=0.5in
|
||||
|
||||
# Custom baseline percent — neither alias gives you this
|
||||
officecli add "$PPTX" '/slide[5]' --type textbox \
|
||||
--prop x=0.5in --prop y=3.7in --prop width=13in --prop height=1in \
|
||||
--prop text="" --prop size=24
|
||||
|
||||
officecli add "$PPTX" '/slide[5]/shape[3]/p[1]' --type run --prop text="Custom: "
|
||||
officecli add "$PPTX" '/slide[5]/shape[3]/p[1]' --type run \
|
||||
--prop text="50%" --prop baseline=50 --prop color=E63946
|
||||
officecli add "$PPTX" '/slide[5]/shape[3]/p[1]' --type run --prop text=" higher / "
|
||||
officecli add "$PPTX" '/slide[5]/shape[3]/p[1]' --type run \
|
||||
--prop text="-40%" --prop baseline=-40 --prop color=2A9D8F
|
||||
officecli add "$PPTX" '/slide[5]/shape[3]/p[1]' --type run --prop text=" lower"
|
||||
|
||||
officecli add "$PPTX" '/slide[5]' --type textbox \
|
||||
--prop text='baseline= accepts signed integer percent (super≡+30, sub≡-25 by convention). Custom values give arbitrary vertical offset.' \
|
||||
--prop size=14 --prop italic=true --prop color=666666 \
|
||||
--prop x=0.5in --prop y=5in --prop width=13in --prop height=0.6in
|
||||
|
||||
# Per-run case rendering — cap on run Add accepts cap / allCaps / smallCaps
|
||||
# directly (canonical + aliases). Same enum surface as the shape-level Set.
|
||||
officecli add "$PPTX" '/slide[5]' --type textbox \
|
||||
--prop x=0.5in --prop y=5.9in --prop width=13in --prop height=0.8in \
|
||||
--prop text="" --prop size=20 --prop bold=true
|
||||
|
||||
officecli add "$PPTX" '/slide[5]/shape[4]/p[1]' --type run --prop text="default "
|
||||
officecli add "$PPTX" '/slide[5]/shape[4]/p[1]' --type run \
|
||||
--prop text="small caps " --prop cap=small --prop color=2A9D8F
|
||||
officecli add "$PPTX" '/slide[5]/shape[4]/p[1]' --type run \
|
||||
--prop text="ALL CAPS" --prop allCaps=true --prop color=E63946
|
||||
|
||||
officecli add "$PPTX" '/slide[5]' --type textbox \
|
||||
--prop text='Per-run cap=small / cap=all / cap=none, plus allCaps / smallCaps boolean aliases.' \
|
||||
--prop size=12 --prop italic=true --prop color=666666 \
|
||||
--prop x=0.5in --prop y=6.8in --prop width=13in --prop height=0.5in
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# Slide 6 — name / zorder / autoFit / direction / font.cs (textbox-specific)
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
officecli add "$PPTX" / --type slide
|
||||
officecli add "$PPTX" '/slide[6]' --type textbox \
|
||||
--prop text="name / zorder / autoFit / direction / font.cs" \
|
||||
--prop size=28 --prop bold=true \
|
||||
--prop x=0.5in --prop y=0.3in --prop width=13in --prop height=0.6in
|
||||
|
||||
# name= — label the textbox so it can be re-addressed by @name later
|
||||
officecli add "$PPTX" '/slide[6]' --type textbox \
|
||||
--prop x=0.5in --prop y=1.2in --prop width=5in --prop height=1.5in \
|
||||
--prop fill=F1FAEE --prop size=16 --prop bold=true \
|
||||
--prop text="This is intro-box." \
|
||||
--prop name="intro-box"
|
||||
|
||||
officecli add "$PPTX" '/slide[6]' --type textbox \
|
||||
--prop text='name="intro-box" → addressable as /slide[6]/shape[@name=intro-box]' \
|
||||
--prop size=12 --prop italic=true --prop color=666666 \
|
||||
--prop x=0.5in --prop y=2.8in --prop width=5in --prop height=0.5in
|
||||
|
||||
# zorder= — three overlapping textboxes with explicit stack order
|
||||
officecli add "$PPTX" '/slide[6]' --type textbox \
|
||||
--prop x=6in --prop y=1.2in --prop width=3in --prop height=2in \
|
||||
--prop fill=4472C4 --prop color=FFFFFF --prop bold=true --prop size=16 \
|
||||
--prop text="back (zorder=1)" \
|
||||
--prop name="tb-back" --prop zorder=1
|
||||
|
||||
officecli add "$PPTX" '/slide[6]' --type textbox \
|
||||
--prop x=7in --prop y=1.6in --prop width=3in --prop height=2in \
|
||||
--prop fill=E63946 --prop color=FFFFFF --prop bold=true --prop size=16 \
|
||||
--prop text="mid (zorder=2)" \
|
||||
--prop name="tb-mid" --prop zorder=2
|
||||
|
||||
officecli add "$PPTX" '/slide[6]' --type textbox \
|
||||
--prop x=8in --prop y=2.0in --prop width=3in --prop height=2in \
|
||||
--prop fill=2A9D8F --prop color=FFFFFF --prop bold=true --prop size=16 \
|
||||
--prop text="front (zorder=3)" \
|
||||
--prop name="tb-front" --prop zorder=3
|
||||
|
||||
officecli add "$PPTX" '/slide[6]' --type textbox \
|
||||
--prop text='zorder= controls stack depth; aliases: z-order, order.' \
|
||||
--prop size=12 --prop italic=true --prop color=666666 \
|
||||
--prop x=6in --prop y=4.2in --prop width=5in --prop height=0.5in
|
||||
|
||||
# autoFit= — overflow behavior for textbox (same as shape)
|
||||
LONGTEXT='Vivamus lacinia odio vitae vestibulum vestibulum. Sed molestie augue sit amet leo consequat posuere.'
|
||||
officecli add "$PPTX" '/slide[6]' --type textbox \
|
||||
--prop x=0.5in --prop y=3.6in --prop width=3in --prop height=1.2in \
|
||||
--prop fill=FFE66D --prop size=16 --prop text="$LONGTEXT" \
|
||||
--prop autoFit=normal
|
||||
|
||||
officecli add "$PPTX" '/slide[6]' --type textbox \
|
||||
--prop text='autoFit=normal (shrinks text to fit)' \
|
||||
--prop size=12 --prop italic=true --prop color=666666 \
|
||||
--prop x=0.5in --prop y=4.9in --prop width=3in --prop height=0.5in
|
||||
|
||||
# direction=rtl — paragraph flows right-to-left inside a textbox
|
||||
officecli add "$PPTX" '/slide[6]' --type textbox \
|
||||
--prop x=0.5in --prop y=5.6in --prop width=5in --prop height=1.2in \
|
||||
--prop fill=A8DADC --prop size=20 --prop bold=true \
|
||||
--prop text="مرحبا بالعالم — 2026" \
|
||||
--prop direction=rtl --prop align=right \
|
||||
--prop font.cs="Arabic Typesetting"
|
||||
|
||||
officecli add "$PPTX" '/slide[6]' --type textbox \
|
||||
--prop text='direction=rtl + font.cs="Arabic Typesetting" (complex-script slot)' \
|
||||
--prop size=12 --prop italic=true --prop color=666666 \
|
||||
--prop x=0.5in --prop y=6.9in --prop width=5in --prop height=0.5in
|
||||
|
||||
officecli close "$PPTX"
|
||||
officecli validate "$PPTX"
|
||||
echo "Created: $PPTX"
|
||||
@@ -0,0 +1,247 @@
|
||||
# Basic PPT Textboxes
|
||||
|
||||
This demo consists of three files that work together:
|
||||
|
||||
- **textboxes-basic.sh** — Shell script that calls `officecli` commands to generate the deck.
|
||||
- **textboxes-basic.pptx** — The generated 4-slide deck (alignment, multi-paragraph lists, styled runs, multilingual fonts + layout).
|
||||
- **textboxes-basic.md** — This file. Maps each slide to the features it demonstrates.
|
||||
|
||||
## Regenerate
|
||||
|
||||
```bash
|
||||
cd examples/ppt
|
||||
bash textboxes/textboxes-basic.sh
|
||||
# → textboxes/textboxes-basic.pptx
|
||||
```
|
||||
|
||||
## Slides
|
||||
|
||||
### Slide 1 — Horizontal Alignment
|
||||
|
||||
Four textboxes with identical long text, one per `align=` value.
|
||||
|
||||
```bash
|
||||
officecli create textboxes-basic.pptx
|
||||
officecli open textboxes-basic.pptx
|
||||
officecli add textboxes-basic.pptx / --type slide
|
||||
|
||||
LOREM='Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus lacinia odio vitae vestibulum vestibulum.'
|
||||
|
||||
# align=left (default)
|
||||
officecli add textboxes-basic.pptx '/slide[1]' --type textbox \
|
||||
--prop x=0.5in --prop y=1.3in --prop width=12in --prop height=1.3in \
|
||||
--prop fill=F1FAEE --prop text="[align=left] $LOREM" --prop size=14 \
|
||||
--prop align=left
|
||||
|
||||
# align=center
|
||||
officecli add textboxes-basic.pptx '/slide[1]' --type textbox \
|
||||
--prop x=0.5in --prop y=2.8in --prop width=12in --prop height=1.3in \
|
||||
--prop fill=F1FAEE --prop text="[align=center] $LOREM" --prop size=14 \
|
||||
--prop align=center
|
||||
|
||||
# align=right
|
||||
officecli add textboxes-basic.pptx '/slide[1]' --type textbox \
|
||||
--prop x=0.5in --prop y=4.3in --prop width=12in --prop height=1.3in \
|
||||
--prop fill=F1FAEE --prop text="[align=right] $LOREM" --prop size=14 \
|
||||
--prop align=right
|
||||
|
||||
# align=justify
|
||||
officecli add textboxes-basic.pptx '/slide[1]' --type textbox \
|
||||
--prop x=0.5in --prop y=5.8in --prop width=12in --prop height=1.3in \
|
||||
--prop fill=F1FAEE --prop text="[align=justify] $LOREM" --prop size=14 \
|
||||
--prop align=justify
|
||||
```
|
||||
|
||||
**Features:** `--type textbox` (alias for `--type shape` — both are textboxes in OOXML), `align` (left, center, right, justify), `fill`, `text`, `size`, `x`/`y`/`width`/`height`
|
||||
|
||||
---
|
||||
|
||||
### Slide 2 — Multi-Paragraph + Bulleted / Numbered Lists
|
||||
|
||||
Two textboxes: a bulleted list on the left and a numbered list with a sub-item on the right.
|
||||
|
||||
```bash
|
||||
officecli add textboxes-basic.pptx / --type slide
|
||||
|
||||
# Bulleted list — add title paragraph first, then append body paragraphs,
|
||||
# then apply list=bullet via Set to turn all paragraphs into bullets.
|
||||
officecli add textboxes-basic.pptx '/slide[2]' --type textbox \
|
||||
--prop x=0.5in --prop y=1.2in --prop width=6in --prop height=4in \
|
||||
--prop text="Coffee preparation steps" \
|
||||
--prop bold=true --prop size=18 --prop color=1D3557
|
||||
|
||||
officecli add textboxes-basic.pptx '/slide[2]/shape[1]' --type paragraph \
|
||||
--prop text="Grind beans to medium-fine"
|
||||
officecli add textboxes-basic.pptx '/slide[2]/shape[1]' --type paragraph \
|
||||
--prop text="Heat water to 93°C"
|
||||
officecli add textboxes-basic.pptx '/slide[2]/shape[1]' --type paragraph \
|
||||
--prop text="Bloom 30s with 2× coffee weight"
|
||||
officecli add textboxes-basic.pptx '/slide[2]/shape[1]' --type paragraph \
|
||||
--prop text="Pour remaining water in spirals"
|
||||
officecli add textboxes-basic.pptx '/slide[2]/shape[1]' --type paragraph \
|
||||
--prop text="Total brew time: 3-4 minutes"
|
||||
|
||||
# Turn all paragraphs into bullets at shape level
|
||||
officecli set textboxes-basic.pptx '/slide[2]/shape[1]' --prop list=bullet
|
||||
|
||||
# Numbered list — similar pattern
|
||||
officecli add textboxes-basic.pptx '/slide[2]' --type textbox \
|
||||
--prop x=7in --prop y=1.2in --prop width=6in --prop height=4in \
|
||||
--prop text="Release checklist" \
|
||||
--prop bold=true --prop size=18 --prop color=1D3557
|
||||
|
||||
officecli add textboxes-basic.pptx '/slide[2]/shape[2]' --type paragraph \
|
||||
--prop text="Run tests"
|
||||
officecli add textboxes-basic.pptx '/slide[2]/shape[2]' --type paragraph \
|
||||
--prop text="Tag the release"
|
||||
officecli add textboxes-basic.pptx '/slide[2]/shape[2]' --type paragraph \
|
||||
--prop text="Push to registry"
|
||||
officecli add textboxes-basic.pptx '/slide[2]/shape[2]' --type paragraph \
|
||||
--prop text="Announce in #releases"
|
||||
|
||||
officecli set textboxes-basic.pptx '/slide[2]/shape[2]' --prop list=numbered
|
||||
|
||||
# Sub-item: level=1 nests one step deeper
|
||||
officecli add textboxes-basic.pptx '/slide[2]/shape[2]' --type paragraph \
|
||||
--prop text="(verify checksum)" --prop level=1
|
||||
officecli set textboxes-basic.pptx '/slide[2]/shape[2]' --prop list=numbered
|
||||
```
|
||||
|
||||
**Features:** `--type paragraph` (appends a paragraph to the parent shape), `list` (bullet, numbered — applied via `set` at shape level), `level` (indent depth; 0 = top-level, 1 = one indent, …)
|
||||
|
||||
---
|
||||
|
||||
### Slide 3 — Styled Runs (Rich Text)
|
||||
|
||||
Three textboxes demonstrating per-run styling within a single paragraph.
|
||||
|
||||
```bash
|
||||
officecli add textboxes-basic.pptx / --type slide
|
||||
|
||||
# Empty textbox — filled run-by-run via --type run
|
||||
officecli add textboxes-basic.pptx '/slide[3]' --type textbox \
|
||||
--prop x=0.5in --prop y=1.5in --prop width=12in --prop height=1in \
|
||||
--prop text="" --prop size=20
|
||||
|
||||
# Append runs with different styles to paragraph [1]
|
||||
officecli add textboxes-basic.pptx '/slide[3]/shape[1]/p[1]' --type run \
|
||||
--prop text="The "
|
||||
officecli add textboxes-basic.pptx '/slide[3]/shape[1]/p[1]' --type run \
|
||||
--prop text="quick " --prop bold=true --prop color=E63946
|
||||
officecli add textboxes-basic.pptx '/slide[3]/shape[1]/p[1]' --type run \
|
||||
--prop text="brown " --prop italic=true --prop color=A0522D
|
||||
officecli add textboxes-basic.pptx '/slide[3]/shape[1]/p[1]' --type run \
|
||||
--prop text="fox jumps over the "
|
||||
officecli add textboxes-basic.pptx '/slide[3]/shape[1]/p[1]' --type run \
|
||||
--prop text="lazy " --prop underline=single --prop color=2A9D8F
|
||||
officecli add textboxes-basic.pptx '/slide[3]/shape[1]/p[1]' --type run \
|
||||
--prop text="dog."
|
||||
|
||||
# Superscript / subscript via baseline= (also accepts baseline=super/sub)
|
||||
officecli add textboxes-basic.pptx '/slide[3]' --type textbox \
|
||||
--prop x=0.5in --prop y=3in --prop width=12in --prop height=0.8in \
|
||||
--prop text="" --prop size=24
|
||||
|
||||
officecli add textboxes-basic.pptx '/slide[3]/shape[2]/p[1]' --type run \
|
||||
--prop text="E = mc"
|
||||
officecli add textboxes-basic.pptx '/slide[3]/shape[2]/p[1]' --type run \
|
||||
--prop text="2" --prop baseline=super
|
||||
officecli add textboxes-basic.pptx '/slide[3]/shape[2]/p[1]' --type run \
|
||||
--prop text=" and H"
|
||||
officecli add textboxes-basic.pptx '/slide[3]/shape[2]/p[1]' --type run \
|
||||
--prop text="2" --prop baseline=sub
|
||||
officecli add textboxes-basic.pptx '/slide[3]/shape[2]/p[1]' --type run \
|
||||
--prop text="O"
|
||||
|
||||
# Strikethrough + size override in one paragraph
|
||||
officecli add textboxes-basic.pptx '/slide[3]' --type textbox \
|
||||
--prop x=0.5in --prop y=4.2in --prop width=12in --prop height=0.8in \
|
||||
--prop text="" --prop size=20
|
||||
|
||||
officecli add textboxes-basic.pptx '/slide[3]/shape[3]/p[1]' --type run \
|
||||
--prop text="OLD PRICE: \$99 " --prop strike=single --prop color=999999
|
||||
officecli add textboxes-basic.pptx '/slide[3]/shape[3]/p[1]' --type run \
|
||||
--prop text="NOW \$49!" --prop bold=true --prop color=E63946 --prop size=24
|
||||
```
|
||||
|
||||
**Features:** `--type run` (appends a run to the parent `p[N]` paragraph), `bold`, `italic`, `underline` (single, double, …), `strike` (single, double), `color` (hex), `size` (pt), `baseline` (super, sub, or signed integer %)
|
||||
|
||||
---
|
||||
|
||||
### Slide 4 — Multilingual Fonts + Vertical Alignment + Padding
|
||||
|
||||
Per-script font selection, vertical text alignment within a tall box, and inner margin padding.
|
||||
|
||||
```bash
|
||||
officecli add textboxes-basic.pptx / --type slide
|
||||
|
||||
# Mixed-script textbox: font.latin for Latin text, font.ea for East Asian characters
|
||||
officecli add textboxes-basic.pptx '/slide[4]' --type textbox \
|
||||
--prop x=0.5in --prop y=1.5in --prop width=6in --prop height=2in \
|
||||
--prop fill=F1FAEE --prop margin=0.2in \
|
||||
--prop text="Hello, 世界! こんにちは、世界。" \
|
||||
--prop size=24 --prop bold=true \
|
||||
--prop font.latin="Georgia" --prop font.ea="Yu Mincho"
|
||||
|
||||
# valign — vertical text position inside a tall fixed-height box
|
||||
# top (default), middle, bottom
|
||||
X=7
|
||||
for va in top middle bottom; do
|
||||
officecli add textboxes-basic.pptx '/slide[4]' --type textbox \
|
||||
--prop x="${X}in" --prop y=1.5in --prop width=2in --prop height=3in \
|
||||
--prop fill=A8DADC --prop margin=0.15in \
|
||||
--prop text="valign=$va" --prop size=16 --prop bold=true \
|
||||
--prop valign="$va" --prop align=center
|
||||
X=$(echo "$X + 2.2" | bc -l)
|
||||
done
|
||||
|
||||
officecli close textboxes-basic.pptx
|
||||
officecli validate textboxes-basic.pptx
|
||||
```
|
||||
|
||||
**Features:** `font.latin` (Latin script font slot), `font.ea` (East Asian script font slot), `valign` (top, middle, bottom), `margin` (uniform inner padding; also `marginLeft`, `marginRight`, `marginTop`, `marginBottom`), `align=center`
|
||||
|
||||
---
|
||||
|
||||
## Complete Feature Coverage
|
||||
|
||||
| Feature | Slide |
|
||||
|---------|-------|
|
||||
| **align:** left, center, right, justify | 1 |
|
||||
| **fill:** hex color background | 1–4 |
|
||||
| **--type paragraph:** append paragraph to existing shape | 2 |
|
||||
| **list=bullet:** bulleted list at shape level | 2 |
|
||||
| **list=numbered:** numbered list at shape level | 2 |
|
||||
| **level:** indent depth for sub-items (0=top, 1=nested, …) | 2 |
|
||||
| **--type run:** append styled run to a paragraph | 3 |
|
||||
| **bold / italic:** per-run weight and style | 3 |
|
||||
| **underline:** single, double, heavy, dotted, dash | 3 |
|
||||
| **strike:** single, double | 3 |
|
||||
| **color:** per-run text color (hex) | 3 |
|
||||
| **size:** per-run font size (pt) | 3 |
|
||||
| **baseline:** super, sub, or signed integer % offset | 3 |
|
||||
| **font.latin / font.ea:** per-script font slots | 4 |
|
||||
| **valign:** top, middle, bottom | 4 |
|
||||
| **margin:** uniform inner text padding | 4 |
|
||||
| **align=center:** horizontal center within valign demo | 4 |
|
||||
|
||||
## Inspect the Generated File
|
||||
|
||||
```bash
|
||||
# List shapes on slide 1
|
||||
officecli query textboxes-basic.pptx '/slide[1]' shape
|
||||
|
||||
# Get alignment on each textbox
|
||||
officecli get textboxes-basic.pptx '/slide[1]/shape[2]'
|
||||
|
||||
# Check list type on slide 2 shapes
|
||||
officecli get textboxes-basic.pptx '/slide[2]/shape[1]'
|
||||
officecli get textboxes-basic.pptx '/slide[2]/shape[2]'
|
||||
|
||||
# Inspect paragraph [1] runs on slide 3
|
||||
officecli query textboxes-basic.pptx '/slide[3]/shape[1]/p[1]' run
|
||||
|
||||
# Get valign and font on slide 4
|
||||
officecli get textboxes-basic.pptx '/slide[4]/shape[1]'
|
||||
officecli get textboxes-basic.pptx '/slide[4]/shape[3]'
|
||||
```
|
||||
Binary file not shown.
@@ -0,0 +1,200 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Basic PowerPoint textboxes — alignment, multi-paragraph, bulleted/numbered
|
||||
lists, styled runs, per-script fonts (Latin/EastAsian), vertical alignment and
|
||||
padding. Demonstrates: type "textbox" (an alias for "shape"), type "paragraph"
|
||||
with align/level, type "run" with bold/italic/underline/strike/color/baseline,
|
||||
shape-level list=bullet|numbered, font.latin/font.ea, valign and margin.
|
||||
|
||||
SDK twin of textboxes-basic.sh (officecli CLI). Both produce an equivalent
|
||||
textboxes-basic.pptx. This one drives the **officecli Python SDK**
|
||||
(`pip install officecli-sdk`): one resident is started and every slide, shape,
|
||||
paragraph and run is shipped over the named pipe in a single `doc.batch(...)`
|
||||
round-trip — items apply in order, so a paragraph/run can target a shape an
|
||||
earlier item in the same list just created. Each item is the same
|
||||
`{"command","parent","type","props"}` dict you'd put in an `officecli batch` list.
|
||||
|
||||
Usage:
|
||||
pip install officecli-sdk # plus the `officecli` binary on PATH
|
||||
python3 textboxes-basic.py
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
# --- locate the SDK: prefer an installed `officecli-sdk`, else the in-repo copy
|
||||
try:
|
||||
import officecli # pip install officecli-sdk
|
||||
except ImportError:
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)),
|
||||
"..", "..", "..", "sdk", "python"))
|
||||
import officecli
|
||||
|
||||
FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "textboxes-basic.pptx")
|
||||
|
||||
|
||||
def slide(**props):
|
||||
"""One `add slide` item in batch-shape."""
|
||||
return {"command": "add", "parent": "/", "type": "slide", "props": props}
|
||||
|
||||
|
||||
def textbox(parent, **props):
|
||||
"""One `add textbox` item in batch-shape."""
|
||||
return {"command": "add", "parent": parent, "type": "textbox", "props": props}
|
||||
|
||||
|
||||
def paragraph(parent, **props):
|
||||
"""One `add paragraph` item in batch-shape."""
|
||||
return {"command": "add", "parent": parent, "type": "paragraph", "props": props}
|
||||
|
||||
|
||||
def run(parent, **props):
|
||||
"""One `add run` item in batch-shape."""
|
||||
return {"command": "add", "parent": parent, "type": "run", "props": props}
|
||||
|
||||
|
||||
def setp(path, **props):
|
||||
"""One `set` item in batch-shape."""
|
||||
return {"command": "set", "path": path, "props": props}
|
||||
|
||||
|
||||
LOREM = ("Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
|
||||
"Vivamus lacinia odio vitae vestibulum vestibulum.")
|
||||
|
||||
print(f"Building {FILE} ...")
|
||||
|
||||
with officecli.create(FILE, "--force") as doc:
|
||||
items = []
|
||||
|
||||
# ===================================================================
|
||||
# Slide 1 — Horizontal alignment (4 textboxes, one per align value)
|
||||
# ===================================================================
|
||||
items.append(slide())
|
||||
items.append(textbox("/slide[1]",
|
||||
text="Horizontal Alignment", size="28", bold="true",
|
||||
x="0.5in", y="0.3in", width="12in", height="0.6in"))
|
||||
|
||||
y = 1.3
|
||||
for a in ("left", "center", "right", "justify"):
|
||||
items.append(textbox("/slide[1]",
|
||||
x="0.5in", y=f"{y}in", width="12in", height="1.3in",
|
||||
fill="F1FAEE", text=f"[align={a}] {LOREM}", size="14",
|
||||
align=a))
|
||||
y += 1.5
|
||||
|
||||
# ===================================================================
|
||||
# Slide 2 — Multi-paragraph + bulleted / numbered lists
|
||||
# ===================================================================
|
||||
items.append(slide())
|
||||
items.append(textbox("/slide[2]",
|
||||
text="Lists and Multi-Paragraph", size="28", bold="true",
|
||||
x="0.5in", y="0.3in", width="12in", height="0.6in"))
|
||||
|
||||
# Bulleted list — start with one initial paragraph (the title), append the
|
||||
# rest, then turn on bullets.
|
||||
items.append(textbox("/slide[2]",
|
||||
x="0.5in", y="1.2in", width="6in", height="4in",
|
||||
text="Coffee preparation steps",
|
||||
bold="true", size="18", color="1D3557"))
|
||||
for t in ("Grind beans to medium-fine",
|
||||
"Heat water to 93°C",
|
||||
"Bloom 30s with 2× coffee weight",
|
||||
"Pour remaining water in spirals",
|
||||
"Total brew time: 3-4 minutes"):
|
||||
items.append(paragraph("/slide[2]/shape[1]", text=t))
|
||||
# Turn paragraphs 2-6 into bullets (level 0). Paragraph 1 is the title.
|
||||
items.append(setp("/slide[2]/shape[1]", list="bullet"))
|
||||
|
||||
# Numbered list (ordered)
|
||||
items.append(textbox("/slide[2]",
|
||||
x="7in", y="1.2in", width="6in", height="4in",
|
||||
text="Release checklist",
|
||||
bold="true", size="18", color="1D3557"))
|
||||
for t in ("Run tests", "Tag the release", "Push to registry",
|
||||
"Announce in #releases"):
|
||||
items.append(paragraph("/slide[2]/shape[2]", text=t))
|
||||
items.append(setp("/slide[2]/shape[2]", list="numbered"))
|
||||
|
||||
# Indented sub-bullet — level=1 on a paragraph nests it one step in.
|
||||
items.append(paragraph("/slide[2]/shape[2]",
|
||||
text="(verify checksum)", level="1"))
|
||||
items.append(setp("/slide[2]/shape[2]", list="numbered"))
|
||||
|
||||
# ===================================================================
|
||||
# Slide 3 — Styled runs (rich text within one paragraph)
|
||||
# ===================================================================
|
||||
items.append(slide())
|
||||
items.append(textbox("/slide[3]",
|
||||
text="Rich Text — Runs", size="28", bold="true",
|
||||
x="0.5in", y="0.3in", width="12in", height="0.6in"))
|
||||
|
||||
# Empty paragraph that we'll fill with multiple runs of different styles.
|
||||
items.append(textbox("/slide[3]",
|
||||
x="0.5in", y="1.5in", width="12in", height="1in",
|
||||
text="", size="20"))
|
||||
items.append(run("/slide[3]/shape[1]/p[1]", text="The "))
|
||||
items.append(run("/slide[3]/shape[1]/p[1]", text="quick ", bold="true", color="E63946"))
|
||||
items.append(run("/slide[3]/shape[1]/p[1]", text="brown ", italic="true", color="A0522D"))
|
||||
items.append(run("/slide[3]/shape[1]/p[1]", text="fox jumps over the "))
|
||||
items.append(run("/slide[3]/shape[1]/p[1]", text="lazy ", underline="single", color="2A9D8F"))
|
||||
items.append(run("/slide[3]/shape[1]/p[1]", text="dog."))
|
||||
|
||||
# Superscript / subscript via baseline
|
||||
items.append(textbox("/slide[3]",
|
||||
x="0.5in", y="3in", width="12in", height="0.8in",
|
||||
text="", size="24"))
|
||||
items.append(run("/slide[3]/shape[2]/p[1]", text="E = mc"))
|
||||
items.append(run("/slide[3]/shape[2]/p[1]", text="2", baseline="super"))
|
||||
items.append(run("/slide[3]/shape[2]/p[1]", text=" and H"))
|
||||
items.append(run("/slide[3]/shape[2]/p[1]", text="2", baseline="sub"))
|
||||
items.append(run("/slide[3]/shape[2]/p[1]", text="O"))
|
||||
|
||||
# Strikethrough + colored
|
||||
items.append(textbox("/slide[3]",
|
||||
x="0.5in", y="4.2in", width="12in", height="0.8in",
|
||||
text="", size="20"))
|
||||
items.append(run("/slide[3]/shape[3]/p[1]",
|
||||
text="OLD PRICE: $99 ", strike="single", color="999999"))
|
||||
items.append(run("/slide[3]/shape[3]/p[1]",
|
||||
text="NOW $49!", bold="true", color="E63946", size="24"))
|
||||
|
||||
# ===================================================================
|
||||
# Slide 4 — Per-script fonts (Latin + EastAsian) + vertical alignment
|
||||
# ===================================================================
|
||||
items.append(slide())
|
||||
items.append(textbox("/slide[4]",
|
||||
text="Multilingual Fonts + Layout", size="28", bold="true",
|
||||
x="0.5in", y="0.3in", width="12in", height="0.6in"))
|
||||
|
||||
# Mixed-script box: separate fonts for Latin and EastAsian text.
|
||||
items.append(textbox("/slide[4]",
|
||||
x="0.5in", y="1.5in", width="6in", height="2in",
|
||||
fill="F1FAEE", margin="0.2in",
|
||||
text="Hello, 世界! こんにちは、世界。",
|
||||
size="24", bold="true",
|
||||
**{"font.latin": "Georgia", "font.ea": "Yu Mincho"}))
|
||||
|
||||
items.append(textbox("/slide[4]",
|
||||
x="0.5in", y="3.7in", width="6in", height="0.5in",
|
||||
text='font.latin=Georgia, font.ea="Yu Mincho"',
|
||||
size="12", italic="true", color="666666"))
|
||||
|
||||
# Vertical alignment within a tall box
|
||||
x = 7.0
|
||||
for va in ("top", "middle", "bottom"):
|
||||
items.append(textbox("/slide[4]",
|
||||
x=f"{x}in", y="1.5in", width="2in", height="3in",
|
||||
fill="A8DADC", margin="0.15in",
|
||||
text=f"valign={va}", size="16", bold="true",
|
||||
valign=va, align="center"))
|
||||
x += 2.2
|
||||
|
||||
items.append(textbox("/slide[4]",
|
||||
x="7in", y="4.8in", width="6in", height="0.5in",
|
||||
text="valign + per-box margin + align=center",
|
||||
size="12", italic="true", color="666666"))
|
||||
|
||||
doc.batch(items)
|
||||
print(f" added {len(items)} slides/shapes/paragraphs/runs")
|
||||
|
||||
print(f"Generated: {FILE}")
|
||||
Executable
+169
@@ -0,0 +1,169 @@
|
||||
#!/bin/bash
|
||||
# Basic PowerPoint textboxes — alignment, multi-paragraph, bulleted lists,
|
||||
# styled runs, per-script fonts (Latin/EastAsian), vertical alignment, padding.
|
||||
# Demonstrates: --type textbox vs --type shape (textbox is an alias for shape),
|
||||
# --type paragraph with align/lineSpacing/indent, --type run with bold/color/baseline,
|
||||
# shape-level list=bullet|ordered, font.latin/font.ea, valign and margin/autoFit.
|
||||
|
||||
# NOTE: intentionally NO `set -e`. Like the SDK twin's doc.batch, this script
|
||||
# tolerates forward-compat 'UNSUPPORTED props' warnings (officecli exit 2) and
|
||||
# keeps building so the full document is produced.
|
||||
DIR="$(dirname "$0")"
|
||||
PPTX="$DIR/textboxes-basic.pptx"
|
||||
|
||||
rm -f "$PPTX"
|
||||
officecli create "$PPTX"
|
||||
officecli open "$PPTX"
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# Slide 1 — Horizontal alignment (4 textboxes, one per align value)
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
officecli add "$PPTX" / --type slide
|
||||
officecli add "$PPTX" '/slide[1]' --type textbox \
|
||||
--prop text="Horizontal Alignment" --prop size=28 --prop bold=true \
|
||||
--prop x=0.5in --prop y=0.3in --prop width=12in --prop height=0.6in
|
||||
|
||||
LOREM='Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus lacinia odio vitae vestibulum vestibulum.'
|
||||
|
||||
Y=1.3
|
||||
for a in left center right justify; do
|
||||
officecli add "$PPTX" '/slide[1]' --type textbox \
|
||||
--prop x=0.5in --prop y="${Y}in" --prop width=12in --prop height=1.3in \
|
||||
--prop fill=F1FAEE --prop text="[align=$a] $LOREM" --prop size=14 \
|
||||
--prop align="$a"
|
||||
Y=$(echo "$Y + 1.5" | bc -l)
|
||||
done
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# Slide 2 — Multi-paragraph + bulleted / numbered lists
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
officecli add "$PPTX" / --type slide
|
||||
officecli add "$PPTX" '/slide[2]' --type textbox \
|
||||
--prop text="Lists and Multi-Paragraph" --prop size=28 --prop bold=true \
|
||||
--prop x=0.5in --prop y=0.3in --prop width=12in --prop height=0.6in
|
||||
|
||||
# Bulleted list — start with one initial paragraph, append the rest, then turn on bullets.
|
||||
officecli add "$PPTX" '/slide[2]' --type textbox \
|
||||
--prop x=0.5in --prop y=1.2in --prop width=6in --prop height=4in \
|
||||
--prop text="Coffee preparation steps" \
|
||||
--prop bold=true --prop size=18 --prop color=1D3557
|
||||
|
||||
officecli add "$PPTX" '/slide[2]/shape[1]' --type paragraph --prop text="Grind beans to medium-fine"
|
||||
officecli add "$PPTX" '/slide[2]/shape[1]' --type paragraph --prop text="Heat water to 93°C"
|
||||
officecli add "$PPTX" '/slide[2]/shape[1]' --type paragraph --prop text="Bloom 30s with 2× coffee weight"
|
||||
officecli add "$PPTX" '/slide[2]/shape[1]' --type paragraph --prop text="Pour remaining water in spirals"
|
||||
officecli add "$PPTX" '/slide[2]/shape[1]' --type paragraph --prop text="Total brew time: 3-4 minutes"
|
||||
|
||||
# Turn paragraphs 2-6 into bullets (level 0). Paragraph 1 is the title — leave unbulleted.
|
||||
officecli set "$PPTX" '/slide[2]/shape[1]' --prop list=bullet
|
||||
|
||||
# Numbered list (ordered)
|
||||
officecli add "$PPTX" '/slide[2]' --type textbox \
|
||||
--prop x=7in --prop y=1.2in --prop width=6in --prop height=4in \
|
||||
--prop text="Release checklist" \
|
||||
--prop bold=true --prop size=18 --prop color=1D3557
|
||||
|
||||
officecli add "$PPTX" '/slide[2]/shape[2]' --type paragraph --prop text="Run tests"
|
||||
officecli add "$PPTX" '/slide[2]/shape[2]' --type paragraph --prop text="Tag the release"
|
||||
officecli add "$PPTX" '/slide[2]/shape[2]' --type paragraph --prop text="Push to registry"
|
||||
officecli add "$PPTX" '/slide[2]/shape[2]' --type paragraph --prop text="Announce in #releases"
|
||||
|
||||
officecli set "$PPTX" '/slide[2]/shape[2]' --prop list=numbered
|
||||
|
||||
# Indented sub-bullet — level=1 on a paragraph nests it one step in.
|
||||
officecli add "$PPTX" '/slide[2]/shape[2]' --type paragraph \
|
||||
--prop text="(verify checksum)" --prop level=1
|
||||
officecli set "$PPTX" '/slide[2]/shape[2]' --prop list=numbered
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# Slide 3 — Styled runs (rich text within one paragraph)
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
officecli add "$PPTX" / --type slide
|
||||
officecli add "$PPTX" '/slide[3]' --type textbox \
|
||||
--prop text="Rich Text — Runs" --prop size=28 --prop bold=true \
|
||||
--prop x=0.5in --prop y=0.3in --prop width=12in --prop height=0.6in
|
||||
|
||||
# Empty paragraph that we'll fill with multiple runs of different styles.
|
||||
officecli add "$PPTX" '/slide[3]' --type textbox \
|
||||
--prop x=0.5in --prop y=1.5in --prop width=12in --prop height=1in \
|
||||
--prop text="" --prop size=20
|
||||
|
||||
officecli add "$PPTX" '/slide[3]/shape[1]/p[1]' --type run --prop text="The "
|
||||
officecli add "$PPTX" '/slide[3]/shape[1]/p[1]' --type run \
|
||||
--prop text="quick " --prop bold=true --prop color=E63946
|
||||
officecli add "$PPTX" '/slide[3]/shape[1]/p[1]' --type run \
|
||||
--prop text="brown " --prop italic=true --prop color=A0522D
|
||||
officecli add "$PPTX" '/slide[3]/shape[1]/p[1]' --type run --prop text="fox jumps over the "
|
||||
officecli add "$PPTX" '/slide[3]/shape[1]/p[1]' --type run \
|
||||
--prop text="lazy " --prop underline=single --prop color=2A9D8F
|
||||
officecli add "$PPTX" '/slide[3]/shape[1]/p[1]' --type run --prop text="dog."
|
||||
|
||||
# Superscript / subscript via baseline
|
||||
officecli add "$PPTX" '/slide[3]' --type textbox \
|
||||
--prop x=0.5in --prop y=3in --prop width=12in --prop height=0.8in \
|
||||
--prop text="" --prop size=24
|
||||
|
||||
officecli add "$PPTX" '/slide[3]/shape[2]/p[1]' --type run --prop text="E = mc"
|
||||
officecli add "$PPTX" '/slide[3]/shape[2]/p[1]' --type run --prop text="2" --prop baseline=super
|
||||
officecli add "$PPTX" '/slide[3]/shape[2]/p[1]' --type run --prop text=" and H"
|
||||
officecli add "$PPTX" '/slide[3]/shape[2]/p[1]' --type run --prop text="2" --prop baseline=sub
|
||||
officecli add "$PPTX" '/slide[3]/shape[2]/p[1]' --type run --prop text="O"
|
||||
|
||||
# Strikethrough + small caps + colored
|
||||
officecli add "$PPTX" '/slide[3]' --type textbox \
|
||||
--prop x=0.5in --prop y=4.2in --prop width=12in --prop height=0.8in \
|
||||
--prop text="" --prop size=20
|
||||
|
||||
officecli add "$PPTX" '/slide[3]/shape[3]/p[1]' --type run \
|
||||
--prop text="OLD PRICE: \$99 " --prop strike=single --prop color=999999
|
||||
officecli add "$PPTX" '/slide[3]/shape[3]/p[1]' --type run \
|
||||
--prop text="NOW \$49!" --prop bold=true --prop color=E63946 --prop size=24
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# Slide 4 — Per-script fonts (Latin + East Asian) + vertical alignment + padding
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
officecli add "$PPTX" / --type slide
|
||||
officecli add "$PPTX" '/slide[4]' --type textbox \
|
||||
--prop text="Multilingual Fonts + Layout" --prop size=28 --prop bold=true \
|
||||
--prop x=0.5in --prop y=0.3in --prop width=12in --prop height=0.6in
|
||||
|
||||
# Mixed-script box: separate fonts for Latin and EastAsian text.
|
||||
officecli add "$PPTX" '/slide[4]' --type textbox \
|
||||
--prop x=0.5in --prop y=1.5in --prop width=6in --prop height=2in \
|
||||
--prop fill=F1FAEE --prop margin=0.2in \
|
||||
--prop text="Hello, 世界! こんにちは、世界。" \
|
||||
--prop size=24 --prop bold=true \
|
||||
--prop font.latin="Georgia" --prop font.ea="Yu Mincho"
|
||||
|
||||
officecli add "$PPTX" '/slide[4]' --type textbox \
|
||||
--prop x=0.5in --prop y=3.7in --prop width=6in --prop height=0.5in \
|
||||
--prop text='font.latin=Georgia, font.ea="Yu Mincho"' \
|
||||
--prop size=12 --prop italic=true --prop color=666666
|
||||
|
||||
# Vertical alignment within a tall box
|
||||
for va in top middle bottom; do
|
||||
case $va in
|
||||
top) X=7 ;;
|
||||
middle) X=9.5 ;;
|
||||
bottom) X=12 ;; # off-slide — squeeze
|
||||
esac
|
||||
done
|
||||
|
||||
X=7
|
||||
for va in top middle bottom; do
|
||||
officecli add "$PPTX" '/slide[4]' --type textbox \
|
||||
--prop x="${X}in" --prop y=1.5in --prop width=2in --prop height=3in \
|
||||
--prop fill=A8DADC --prop margin=0.15in \
|
||||
--prop text="valign=$va" --prop size=16 --prop bold=true \
|
||||
--prop valign="$va" --prop align=center
|
||||
X=$(echo "$X + 2.2" | bc -l)
|
||||
done
|
||||
|
||||
officecli add "$PPTX" '/slide[4]' --type textbox \
|
||||
--prop x=7in --prop y=4.8in --prop width=6in --prop height=0.5in \
|
||||
--prop text='valign + per-box margin + align=center' \
|
||||
--prop size=12 --prop italic=true --prop color=666666
|
||||
|
||||
officecli close "$PPTX"
|
||||
officecli validate "$PPTX"
|
||||
echo "Created: $PPTX"
|
||||
Reference in New Issue
Block a user