pikslide 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pikslide-0.1.0/LICENSE +14 -0
- pikslide-0.1.0/NOTICE +17 -0
- pikslide-0.1.0/PKG-INFO +256 -0
- pikslide-0.1.0/README.md +228 -0
- pikslide-0.1.0/pyproject.toml +54 -0
- pikslide-0.1.0/pyproject.toml.orig +45 -0
- pikslide-0.1.0/src/pikslide/__init__.py +311 -0
- pikslide-0.1.0/src/pikslide/docs/grammar.md +521 -0
- pikslide-0.1.0/src/pikslide/docs/spec.md +667 -0
- pikslide-0.1.0/src/pikslide/fonts.py +249 -0
- pikslide-0.1.0/src/pikslide/help.py +1119 -0
- pikslide-0.1.0/src/pikslide/pik/__init__.py +16 -0
- pikslide-0.1.0/src/pikslide/pik/ast.py +498 -0
- pikslide-0.1.0/src/pikslide/pik/dump.py +53 -0
- pikslide-0.1.0/src/pikslide/pik/layout.py +1855 -0
- pikslide-0.1.0/src/pikslide/pik/macros.py +343 -0
- pikslide-0.1.0/src/pikslide/pik/parser.py +888 -0
- pikslide-0.1.0/src/pikslide/pik/preset_text_rects.py +1854 -0
- pikslide-0.1.0/src/pikslide/pik/text_area.py +135 -0
- pikslide-0.1.0/src/pikslide/pik/tokens.py +648 -0
- pikslide-0.1.0/src/pikslide/pptx_writer.py +1085 -0
- pikslide-0.1.0/src/pikslide/prelude.pik +262 -0
- pikslide-0.1.0/src/pikslide/ps/pptx_to_pdf.ps1 +57 -0
- pikslide-0.1.0/src/pikslide/ps/pptx_to_png.ps1 +78 -0
- pikslide-0.1.0/src/pikslide/render.py +124 -0
pikslide-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
BSD Zero Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Miki Yutani
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
purpose with or without fee is hereby granted.
|
|
7
|
+
|
|
8
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
9
|
+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
10
|
+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
11
|
+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
12
|
+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
13
|
+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
14
|
+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
pikslide-0.1.0/NOTICE
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
This project (pikslide) is licensed under the Zero-Clause BSD license; see
|
|
2
|
+
LICENSE.
|
|
3
|
+
|
|
4
|
+
The .pik tokenizer, grammar, macro expansion, layout formulas, default
|
|
5
|
+
variable table, and color name table in src/pikslide/pik/ are substantially
|
|
6
|
+
ported (in several places, directly transcribed) from pikchr:
|
|
7
|
+
|
|
8
|
+
pikchr - https://pikchr.org/
|
|
9
|
+
Copyright (C) 2020-09-01 by D. Richard Hipp <drh@sqlite.org>
|
|
10
|
+
|
|
11
|
+
pikchr's own source (pikchr.y) states it is released under the following
|
|
12
|
+
terms:
|
|
13
|
+
|
|
14
|
+
Zero-Clause BSD license:
|
|
15
|
+
|
|
16
|
+
Permission to use, copy, modify, and/or distribute this software for
|
|
17
|
+
any purpose with or without fee is hereby granted.
|
pikslide-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pikslide
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A text language for drawing diagrams as native, editable PowerPoint objects
|
|
5
|
+
Keywords: diagram,powerpoint,pptx,pic,pikchr,slides
|
|
6
|
+
Author: Miki Yutani
|
|
7
|
+
Author-email: Miki Yutani <mkyutani@gmail.com>
|
|
8
|
+
License-Expression: 0BSD
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
License-File: NOTICE
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
|
+
Classifier: Topic :: Multimedia :: Graphics :: Presentation
|
|
21
|
+
Requires-Dist: pillow>=12.3.0
|
|
22
|
+
Requires-Dist: python-pptx>=1.0.2
|
|
23
|
+
Requires-Python: >=3.12
|
|
24
|
+
Project-URL: Repository, https://github.com/mkyutani/pikslide
|
|
25
|
+
Project-URL: Issues, https://github.com/mkyutani/pikslide/issues
|
|
26
|
+
Project-URL: Documentation, https://github.com/mkyutani/pikslide/blob/main/src/pikslide/docs/spec.md
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# pikslide
|
|
30
|
+
|
|
31
|
+
A text language for drawing **diagrams that live inside Office slides**.
|
|
32
|
+
|
|
33
|
+
You don't write coordinates: you place objects one after another in a
|
|
34
|
+
direction, and refer to earlier objects by name. A diagram becomes
|
|
35
|
+
**native, editable PowerPoint objects** — shapes a person can select,
|
|
36
|
+
restyle and move afterwards.
|
|
37
|
+
|
|
38
|
+
The language is specified in [docs/spec.md](https://github.com/mkyutani/pikslide/blob/main/src/pikslide/docs/spec.md) and defined, in
|
|
39
|
+
BNF, in [docs/grammar.md](https://github.com/mkyutani/pikslide/blob/main/src/pikslide/docs/grammar.md). (pikslide's own design traces
|
|
40
|
+
back through two earlier languages; see Acknowledgments, below.)
|
|
41
|
+
|
|
42
|
+
## Status
|
|
43
|
+
|
|
44
|
+
v1 (docs/spec.md §1) is implemented: a parser, a layout stage, and
|
|
45
|
+
PowerPoint output; colors as a type of their own, with theme colors
|
|
46
|
+
(`theme "accent1"`, `lighter`/`darker`) rendered as real `schemeClr`,
|
|
47
|
+
never resolved to RGB; fonts the same way — text set in the theme's own
|
|
48
|
+
font by default, not a hard-coded family, with `major` selecting the
|
|
49
|
+
heading font and `typeface` overriding both with one literal family;
|
|
50
|
+
three fixed text sizes (`small`/`medium`/`large`); a prelude of built-in
|
|
51
|
+
names (CSS color names, built-in defaults, the theme-color names); preset
|
|
52
|
+
shapes (`shape roundRect`, any of the ~180 OOXML presets, matched
|
|
53
|
+
case-insensitively); images (PNG/JPEG/GIF, and SVG — embedded together
|
|
54
|
+
with a PNG fallback for older viewers, sized explicitly or by aspect
|
|
55
|
+
ratio, path resolved and contained under the source file's own
|
|
56
|
+
directory); `include "house.pik"` for shared definitions (contained the
|
|
57
|
+
same way, with cycle detection); object identity — a label becomes the
|
|
58
|
+
shape's real PowerPoint name (an unlabeled object gets a default `box
|
|
59
|
+
1`-style name), and `behind X` places an object immediately below `X`
|
|
60
|
+
in z-order — so the Selection Pane reads like the source (`[ ... ]`
|
|
61
|
+
blocks are a source-level grouping construct only, flattened rather than
|
|
62
|
+
turned into a PowerPoint group when written out); starting a new
|
|
63
|
+
standalone deck from another file's theme instead of the built-in Office
|
|
64
|
+
one (`--template`); a template's settings file (`<name>.theme.pik`, or
|
|
65
|
+
`--settings FILE`), for its slide layout, font, accent colors and text
|
|
66
|
+
sizes; and diagnostics — `file:line:column`, the source line and a caret
|
|
67
|
+
for a syntax error (naming the right file even inside a nested
|
|
68
|
+
`include`), "did you mean" suggestions for an unknown
|
|
69
|
+
color/preset/image name, `--strict`, `--check`, and `--format json`.
|
|
70
|
+
|
|
71
|
+
Deliberately out of v1 (docs/spec.md §7): inserting into an existing
|
|
72
|
+
deck's slide, ` ```pikslide ` blocks in Markdown, connectors, SVG *output*,
|
|
73
|
+
auto-layout, tables/charts/SmartArt, animation, multi-slide authoring,
|
|
74
|
+
true Bézier curves, shape adjustment handles, arithmetic on colors.
|
|
75
|
+
|
|
76
|
+
## How it works
|
|
77
|
+
|
|
78
|
+
1. **Parse** — source is tokenized and parsed into an AST
|
|
79
|
+
(`pikslide.pik.ast.Document`).
|
|
80
|
+
2. **Layout** — the AST is resolved into concrete 2-D geometry (box positions,
|
|
81
|
+
arrow paths, text placement).
|
|
82
|
+
3. **Render** — the resolved geometry is written out as PowerPoint objects.
|
|
83
|
+
|
|
84
|
+
## Requirements
|
|
85
|
+
|
|
86
|
+
- Python 3.12+
|
|
87
|
+
|
|
88
|
+
## Install
|
|
89
|
+
|
|
90
|
+
From PyPI, as a standalone `pikslide` command:
|
|
91
|
+
|
|
92
|
+
```sh
|
|
93
|
+
uv tool install pikslide
|
|
94
|
+
# or
|
|
95
|
+
pipx install pikslide
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
`pikslide --version` prints the version installed. To remove it later:
|
|
99
|
+
`uv tool uninstall pikslide` (or `pipx uninstall pikslide`).
|
|
100
|
+
|
|
101
|
+
### From source
|
|
102
|
+
|
|
103
|
+
To work on pikslide itself, clone the repository and use
|
|
104
|
+
[uv](https://docs.astral.sh/uv/). The examples below call an installed
|
|
105
|
+
`pikslide`; in a clone, `uv run pikslide ...` runs it with no install step.
|
|
106
|
+
To install the clone as a standalone command instead (placed in
|
|
107
|
+
`~/.local/bin`), from the project root:
|
|
108
|
+
|
|
109
|
+
```sh
|
|
110
|
+
uv tool install .
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
If `~/.local/bin` isn't on your `PATH` yet, run `uv tool update-shell`.
|
|
114
|
+
|
|
115
|
+
## Usage
|
|
116
|
+
|
|
117
|
+
Dump the parsed tree for a `.pik` file (useful for inspecting how a script was
|
|
118
|
+
understood, or for debugging):
|
|
119
|
+
|
|
120
|
+
```sh
|
|
121
|
+
pikslide diagram.pik
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Render a `.pik` file straight to PowerPoint:
|
|
125
|
+
|
|
126
|
+
```sh
|
|
127
|
+
pikslide diagram.pik diagram.pptx
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
The result is a new one-slide deck sized to the diagram; an existing
|
|
131
|
+
OUTPUT is overwritten.
|
|
132
|
+
|
|
133
|
+
To draw on a real template's slide, in its theme and fonts, instead of
|
|
134
|
+
the built-in Office ones:
|
|
135
|
+
|
|
136
|
+
```sh
|
|
137
|
+
pikslide diagram.pik diagram.pptx --template corporate.potx
|
|
138
|
+
pikslide diagram.pik diagram.pptx --template corporate.potx --layout "Two Content"
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
(OUTPUT may be omitted when `--template` is given: it then defaults to
|
|
142
|
+
INPUT's own path with its extension changed to `.pptx`.) The slide is the
|
|
143
|
+
template's own size, and the diagram goes at the top left of its content
|
|
144
|
+
area, clear of the title and footer. Its layout is the template's Title
|
|
145
|
+
and Content layout (the first with one placeholder besides its title,
|
|
146
|
+
date, footer and slide number), unless `--layout` or the template's
|
|
147
|
+
settings file names another, by its name or, where two layouts share a
|
|
148
|
+
name, its id. `pikslide --help template` has the details: the content
|
|
149
|
+
area, the settings file, and the defaults a template sets.
|
|
150
|
+
|
|
151
|
+
`--check` parses and lays out a source without writing anything, and
|
|
152
|
+
`--format json` emits diagnostics as one JSON object instead of plain
|
|
153
|
+
text — see `pikslide --help` for every flag.
|
|
154
|
+
|
|
155
|
+
`pikslide --help TOPIC` is the language reference: a keyword (`--help box`
|
|
156
|
+
gives its synopsis, attributes and defaults), a list (`colors`, `shapes`,
|
|
157
|
+
`keywords`, …), a color or a preset shape (`--help accent1`, `--help
|
|
158
|
+
callout1`: what it looks like), or a manual (`grammar`, `spec`).
|
|
159
|
+
`pikslide --help` lists the topics.
|
|
160
|
+
|
|
161
|
+
With no arguments, `pikslide` prints its usage and points to
|
|
162
|
+
`pikslide --help intro`, the language in one page.
|
|
163
|
+
|
|
164
|
+
`--png` / `--pdf` also render the deck just written to a PNG or a PDF —
|
|
165
|
+
beside OUTPUT with the extension changed, or at an explicit path:
|
|
166
|
+
|
|
167
|
+
```sh
|
|
168
|
+
pikslide diagram.pik diagram.pptx --png --pdf
|
|
169
|
+
pikslide diagram.pik diagram.pptx --png images/diagram.png
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
(Give OUTPUT before `--png`/`--pdf`, since their PATH is optional.) This
|
|
173
|
+
uses PowerPoint itself, through COM automation (via `powershell.exe`),
|
|
174
|
+
when it's reachable — Windows, or WSL with a Windows PowerPoint install —
|
|
175
|
+
since that's the actual renderer pikslide's output is meant for; otherwise
|
|
176
|
+
it falls back to LibreOffice (`soffice`) and says so in a note: a
|
|
177
|
+
different rendering engine, good for a quick look but not for verifying
|
|
178
|
+
exact layout or text fit against real PowerPoint. `--renderer powerpoint`
|
|
179
|
+
or `--renderer libreoffice` uses only that one.
|
|
180
|
+
With no `--template`, pikslide sizes its slide exactly to the diagram, so
|
|
181
|
+
the PNG is an image of just the diagram, no separate cropping needed; with
|
|
182
|
+
one, it is the whole slide, as it will look in the deck. The PowerShell scripts
|
|
183
|
+
behind this (`src/pikslide/ps/*.ps1`) also run on their own from Windows
|
|
184
|
+
PowerShell.
|
|
185
|
+
|
|
186
|
+
### Example
|
|
187
|
+
|
|
188
|
+
`docs/examples/pipeline.pik`:
|
|
189
|
+
|
|
190
|
+
```pikslide
|
|
191
|
+
arrow "Markdown" "Source" right 200%
|
|
192
|
+
box "pikslide" "Formatter" rad 10px fit
|
|
193
|
+
arrow "PPTX" "Output" right 200%
|
|
194
|
+
arrow <- down 70% from last box.s
|
|
195
|
+
file "pikslide" "Language" fit
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
```sh
|
|
199
|
+
pikslide docs/examples/pipeline.pik docs/examples/pipeline.pptx --png
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+

|
|
203
|
+
|
|
204
|
+
[docs/examples/](https://github.com/mkyutani/pikslide/tree/main/docs/examples) has more, each with the PPTX and PNG it
|
|
205
|
+
renders to.
|
|
206
|
+
[docs/examples/japan-capitals.md](https://github.com/mkyutani/pikslide/blob/main/docs/examples/japan-capitals.md) is one
|
|
207
|
+
that Claude Code drew, with the prompt it was given.
|
|
208
|
+
|
|
209
|
+
## Limits of the current layout stage
|
|
210
|
+
|
|
211
|
+
The layout stage is a deliberately pragmatic subset of a full CAD-style
|
|
212
|
+
layout engine, covering common diagrams well rather than every case:
|
|
213
|
+
default object sizes, sequential chaining,
|
|
214
|
+
`at`/`with`/`from`/`to`/`then`/`go`/`same`/`chop`, and box/ellipse/diamond
|
|
215
|
+
edge geometry are all there, but a few things are simplified:
|
|
216
|
+
|
|
217
|
+
- spline/arc curves are drawn as straight polylines,
|
|
218
|
+
- `fit` text sizing measures with the deck's own fonts when rendering to
|
|
219
|
+
PowerPoint (docs/spec.md §3.3), but falls back to a flat per-character
|
|
220
|
+
estimate otherwise,
|
|
221
|
+
- chopping against diamond/cylinder/file shapes uses a rectangle-like
|
|
222
|
+
approximation rather than each shape's true outline.
|
|
223
|
+
|
|
224
|
+
See the module docstrings in `src/pikslide/pik/layout.py` for details.
|
|
225
|
+
|
|
226
|
+
## Development
|
|
227
|
+
|
|
228
|
+
```sh
|
|
229
|
+
uv run pytest
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Test fixtures under `tests/fixtures/examples/` are a corpus of official
|
|
233
|
+
example diagrams inherited via the port described in Acknowledgments,
|
|
234
|
+
kept as a regression net for behavior that hasn't deliberately changed.
|
|
235
|
+
|
|
236
|
+
## Acknowledgments
|
|
237
|
+
|
|
238
|
+
pikslide traces its lineage through two earlier languages. Brian
|
|
239
|
+
Kernighan's `pic` (1984) introduced sequential, relative placement of
|
|
240
|
+
named objects — draw one thing, then the next one relative to it — rather
|
|
241
|
+
than absolute coordinates. D. Richard Hipp's [pikchr](https://pikchr.org/)
|
|
242
|
+
carried that idea into a full, modern language, emitting SVG. pikslide's
|
|
243
|
+
tokenizer, grammar, macro expansion, and layout engine began as a direct
|
|
244
|
+
port of pikchr's own, and the port goes well beyond syntax — default
|
|
245
|
+
object sizes, placement and chaining math, and edge geometry are all
|
|
246
|
+
inherited from it, not rebuilt from scratch. pikslide's own design departs
|
|
247
|
+
from there where a diagram that lives inside a PowerPoint slide, rather
|
|
248
|
+
than becoming an SVG picture, calls for a different answer.
|
|
249
|
+
|
|
250
|
+
pikchr's [source](https://pikchr.org/home/doc/tip/pikchr.y) states it is
|
|
251
|
+
released under the Zero-Clause BSD license. See [NOTICE](https://github.com/mkyutani/pikslide/blob/main/NOTICE) for
|
|
252
|
+
details.
|
|
253
|
+
|
|
254
|
+
## License
|
|
255
|
+
|
|
256
|
+
[0BSD](https://github.com/mkyutani/pikslide/blob/main/LICENSE)
|
pikslide-0.1.0/README.md
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# pikslide
|
|
2
|
+
|
|
3
|
+
A text language for drawing **diagrams that live inside Office slides**.
|
|
4
|
+
|
|
5
|
+
You don't write coordinates: you place objects one after another in a
|
|
6
|
+
direction, and refer to earlier objects by name. A diagram becomes
|
|
7
|
+
**native, editable PowerPoint objects** — shapes a person can select,
|
|
8
|
+
restyle and move afterwards.
|
|
9
|
+
|
|
10
|
+
The language is specified in [docs/spec.md](https://github.com/mkyutani/pikslide/blob/main/src/pikslide/docs/spec.md) and defined, in
|
|
11
|
+
BNF, in [docs/grammar.md](https://github.com/mkyutani/pikslide/blob/main/src/pikslide/docs/grammar.md). (pikslide's own design traces
|
|
12
|
+
back through two earlier languages; see Acknowledgments, below.)
|
|
13
|
+
|
|
14
|
+
## Status
|
|
15
|
+
|
|
16
|
+
v1 (docs/spec.md §1) is implemented: a parser, a layout stage, and
|
|
17
|
+
PowerPoint output; colors as a type of their own, with theme colors
|
|
18
|
+
(`theme "accent1"`, `lighter`/`darker`) rendered as real `schemeClr`,
|
|
19
|
+
never resolved to RGB; fonts the same way — text set in the theme's own
|
|
20
|
+
font by default, not a hard-coded family, with `major` selecting the
|
|
21
|
+
heading font and `typeface` overriding both with one literal family;
|
|
22
|
+
three fixed text sizes (`small`/`medium`/`large`); a prelude of built-in
|
|
23
|
+
names (CSS color names, built-in defaults, the theme-color names); preset
|
|
24
|
+
shapes (`shape roundRect`, any of the ~180 OOXML presets, matched
|
|
25
|
+
case-insensitively); images (PNG/JPEG/GIF, and SVG — embedded together
|
|
26
|
+
with a PNG fallback for older viewers, sized explicitly or by aspect
|
|
27
|
+
ratio, path resolved and contained under the source file's own
|
|
28
|
+
directory); `include "house.pik"` for shared definitions (contained the
|
|
29
|
+
same way, with cycle detection); object identity — a label becomes the
|
|
30
|
+
shape's real PowerPoint name (an unlabeled object gets a default `box
|
|
31
|
+
1`-style name), and `behind X` places an object immediately below `X`
|
|
32
|
+
in z-order — so the Selection Pane reads like the source (`[ ... ]`
|
|
33
|
+
blocks are a source-level grouping construct only, flattened rather than
|
|
34
|
+
turned into a PowerPoint group when written out); starting a new
|
|
35
|
+
standalone deck from another file's theme instead of the built-in Office
|
|
36
|
+
one (`--template`); a template's settings file (`<name>.theme.pik`, or
|
|
37
|
+
`--settings FILE`), for its slide layout, font, accent colors and text
|
|
38
|
+
sizes; and diagnostics — `file:line:column`, the source line and a caret
|
|
39
|
+
for a syntax error (naming the right file even inside a nested
|
|
40
|
+
`include`), "did you mean" suggestions for an unknown
|
|
41
|
+
color/preset/image name, `--strict`, `--check`, and `--format json`.
|
|
42
|
+
|
|
43
|
+
Deliberately out of v1 (docs/spec.md §7): inserting into an existing
|
|
44
|
+
deck's slide, ` ```pikslide ` blocks in Markdown, connectors, SVG *output*,
|
|
45
|
+
auto-layout, tables/charts/SmartArt, animation, multi-slide authoring,
|
|
46
|
+
true Bézier curves, shape adjustment handles, arithmetic on colors.
|
|
47
|
+
|
|
48
|
+
## How it works
|
|
49
|
+
|
|
50
|
+
1. **Parse** — source is tokenized and parsed into an AST
|
|
51
|
+
(`pikslide.pik.ast.Document`).
|
|
52
|
+
2. **Layout** — the AST is resolved into concrete 2-D geometry (box positions,
|
|
53
|
+
arrow paths, text placement).
|
|
54
|
+
3. **Render** — the resolved geometry is written out as PowerPoint objects.
|
|
55
|
+
|
|
56
|
+
## Requirements
|
|
57
|
+
|
|
58
|
+
- Python 3.12+
|
|
59
|
+
|
|
60
|
+
## Install
|
|
61
|
+
|
|
62
|
+
From PyPI, as a standalone `pikslide` command:
|
|
63
|
+
|
|
64
|
+
```sh
|
|
65
|
+
uv tool install pikslide
|
|
66
|
+
# or
|
|
67
|
+
pipx install pikslide
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
`pikslide --version` prints the version installed. To remove it later:
|
|
71
|
+
`uv tool uninstall pikslide` (or `pipx uninstall pikslide`).
|
|
72
|
+
|
|
73
|
+
### From source
|
|
74
|
+
|
|
75
|
+
To work on pikslide itself, clone the repository and use
|
|
76
|
+
[uv](https://docs.astral.sh/uv/). The examples below call an installed
|
|
77
|
+
`pikslide`; in a clone, `uv run pikslide ...` runs it with no install step.
|
|
78
|
+
To install the clone as a standalone command instead (placed in
|
|
79
|
+
`~/.local/bin`), from the project root:
|
|
80
|
+
|
|
81
|
+
```sh
|
|
82
|
+
uv tool install .
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
If `~/.local/bin` isn't on your `PATH` yet, run `uv tool update-shell`.
|
|
86
|
+
|
|
87
|
+
## Usage
|
|
88
|
+
|
|
89
|
+
Dump the parsed tree for a `.pik` file (useful for inspecting how a script was
|
|
90
|
+
understood, or for debugging):
|
|
91
|
+
|
|
92
|
+
```sh
|
|
93
|
+
pikslide diagram.pik
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Render a `.pik` file straight to PowerPoint:
|
|
97
|
+
|
|
98
|
+
```sh
|
|
99
|
+
pikslide diagram.pik diagram.pptx
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
The result is a new one-slide deck sized to the diagram; an existing
|
|
103
|
+
OUTPUT is overwritten.
|
|
104
|
+
|
|
105
|
+
To draw on a real template's slide, in its theme and fonts, instead of
|
|
106
|
+
the built-in Office ones:
|
|
107
|
+
|
|
108
|
+
```sh
|
|
109
|
+
pikslide diagram.pik diagram.pptx --template corporate.potx
|
|
110
|
+
pikslide diagram.pik diagram.pptx --template corporate.potx --layout "Two Content"
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
(OUTPUT may be omitted when `--template` is given: it then defaults to
|
|
114
|
+
INPUT's own path with its extension changed to `.pptx`.) The slide is the
|
|
115
|
+
template's own size, and the diagram goes at the top left of its content
|
|
116
|
+
area, clear of the title and footer. Its layout is the template's Title
|
|
117
|
+
and Content layout (the first with one placeholder besides its title,
|
|
118
|
+
date, footer and slide number), unless `--layout` or the template's
|
|
119
|
+
settings file names another, by its name or, where two layouts share a
|
|
120
|
+
name, its id. `pikslide --help template` has the details: the content
|
|
121
|
+
area, the settings file, and the defaults a template sets.
|
|
122
|
+
|
|
123
|
+
`--check` parses and lays out a source without writing anything, and
|
|
124
|
+
`--format json` emits diagnostics as one JSON object instead of plain
|
|
125
|
+
text — see `pikslide --help` for every flag.
|
|
126
|
+
|
|
127
|
+
`pikslide --help TOPIC` is the language reference: a keyword (`--help box`
|
|
128
|
+
gives its synopsis, attributes and defaults), a list (`colors`, `shapes`,
|
|
129
|
+
`keywords`, …), a color or a preset shape (`--help accent1`, `--help
|
|
130
|
+
callout1`: what it looks like), or a manual (`grammar`, `spec`).
|
|
131
|
+
`pikslide --help` lists the topics.
|
|
132
|
+
|
|
133
|
+
With no arguments, `pikslide` prints its usage and points to
|
|
134
|
+
`pikslide --help intro`, the language in one page.
|
|
135
|
+
|
|
136
|
+
`--png` / `--pdf` also render the deck just written to a PNG or a PDF —
|
|
137
|
+
beside OUTPUT with the extension changed, or at an explicit path:
|
|
138
|
+
|
|
139
|
+
```sh
|
|
140
|
+
pikslide diagram.pik diagram.pptx --png --pdf
|
|
141
|
+
pikslide diagram.pik diagram.pptx --png images/diagram.png
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
(Give OUTPUT before `--png`/`--pdf`, since their PATH is optional.) This
|
|
145
|
+
uses PowerPoint itself, through COM automation (via `powershell.exe`),
|
|
146
|
+
when it's reachable — Windows, or WSL with a Windows PowerPoint install —
|
|
147
|
+
since that's the actual renderer pikslide's output is meant for; otherwise
|
|
148
|
+
it falls back to LibreOffice (`soffice`) and says so in a note: a
|
|
149
|
+
different rendering engine, good for a quick look but not for verifying
|
|
150
|
+
exact layout or text fit against real PowerPoint. `--renderer powerpoint`
|
|
151
|
+
or `--renderer libreoffice` uses only that one.
|
|
152
|
+
With no `--template`, pikslide sizes its slide exactly to the diagram, so
|
|
153
|
+
the PNG is an image of just the diagram, no separate cropping needed; with
|
|
154
|
+
one, it is the whole slide, as it will look in the deck. The PowerShell scripts
|
|
155
|
+
behind this (`src/pikslide/ps/*.ps1`) also run on their own from Windows
|
|
156
|
+
PowerShell.
|
|
157
|
+
|
|
158
|
+
### Example
|
|
159
|
+
|
|
160
|
+
`docs/examples/pipeline.pik`:
|
|
161
|
+
|
|
162
|
+
```pikslide
|
|
163
|
+
arrow "Markdown" "Source" right 200%
|
|
164
|
+
box "pikslide" "Formatter" rad 10px fit
|
|
165
|
+
arrow "PPTX" "Output" right 200%
|
|
166
|
+
arrow <- down 70% from last box.s
|
|
167
|
+
file "pikslide" "Language" fit
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
```sh
|
|
171
|
+
pikslide docs/examples/pipeline.pik docs/examples/pipeline.pptx --png
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+

|
|
175
|
+
|
|
176
|
+
[docs/examples/](https://github.com/mkyutani/pikslide/tree/main/docs/examples) has more, each with the PPTX and PNG it
|
|
177
|
+
renders to.
|
|
178
|
+
[docs/examples/japan-capitals.md](https://github.com/mkyutani/pikslide/blob/main/docs/examples/japan-capitals.md) is one
|
|
179
|
+
that Claude Code drew, with the prompt it was given.
|
|
180
|
+
|
|
181
|
+
## Limits of the current layout stage
|
|
182
|
+
|
|
183
|
+
The layout stage is a deliberately pragmatic subset of a full CAD-style
|
|
184
|
+
layout engine, covering common diagrams well rather than every case:
|
|
185
|
+
default object sizes, sequential chaining,
|
|
186
|
+
`at`/`with`/`from`/`to`/`then`/`go`/`same`/`chop`, and box/ellipse/diamond
|
|
187
|
+
edge geometry are all there, but a few things are simplified:
|
|
188
|
+
|
|
189
|
+
- spline/arc curves are drawn as straight polylines,
|
|
190
|
+
- `fit` text sizing measures with the deck's own fonts when rendering to
|
|
191
|
+
PowerPoint (docs/spec.md §3.3), but falls back to a flat per-character
|
|
192
|
+
estimate otherwise,
|
|
193
|
+
- chopping against diamond/cylinder/file shapes uses a rectangle-like
|
|
194
|
+
approximation rather than each shape's true outline.
|
|
195
|
+
|
|
196
|
+
See the module docstrings in `src/pikslide/pik/layout.py` for details.
|
|
197
|
+
|
|
198
|
+
## Development
|
|
199
|
+
|
|
200
|
+
```sh
|
|
201
|
+
uv run pytest
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Test fixtures under `tests/fixtures/examples/` are a corpus of official
|
|
205
|
+
example diagrams inherited via the port described in Acknowledgments,
|
|
206
|
+
kept as a regression net for behavior that hasn't deliberately changed.
|
|
207
|
+
|
|
208
|
+
## Acknowledgments
|
|
209
|
+
|
|
210
|
+
pikslide traces its lineage through two earlier languages. Brian
|
|
211
|
+
Kernighan's `pic` (1984) introduced sequential, relative placement of
|
|
212
|
+
named objects — draw one thing, then the next one relative to it — rather
|
|
213
|
+
than absolute coordinates. D. Richard Hipp's [pikchr](https://pikchr.org/)
|
|
214
|
+
carried that idea into a full, modern language, emitting SVG. pikslide's
|
|
215
|
+
tokenizer, grammar, macro expansion, and layout engine began as a direct
|
|
216
|
+
port of pikchr's own, and the port goes well beyond syntax — default
|
|
217
|
+
object sizes, placement and chaining math, and edge geometry are all
|
|
218
|
+
inherited from it, not rebuilt from scratch. pikslide's own design departs
|
|
219
|
+
from there where a diagram that lives inside a PowerPoint slide, rather
|
|
220
|
+
than becoming an SVG picture, calls for a different answer.
|
|
221
|
+
|
|
222
|
+
pikchr's [source](https://pikchr.org/home/doc/tip/pikchr.y) states it is
|
|
223
|
+
released under the Zero-Clause BSD license. See [NOTICE](https://github.com/mkyutani/pikslide/blob/main/NOTICE) for
|
|
224
|
+
details.
|
|
225
|
+
|
|
226
|
+
## License
|
|
227
|
+
|
|
228
|
+
[0BSD](https://github.com/mkyutani/pikslide/blob/main/LICENSE)
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "pikslide"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "A text language for drawing diagrams as native, editable PowerPoint objects"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "0BSD"
|
|
7
|
+
license-files = [
|
|
8
|
+
"LICENSE",
|
|
9
|
+
"NOTICE",
|
|
10
|
+
]
|
|
11
|
+
requires-python = ">=3.12"
|
|
12
|
+
keywords = [
|
|
13
|
+
"diagram",
|
|
14
|
+
"powerpoint",
|
|
15
|
+
"pptx",
|
|
16
|
+
"pic",
|
|
17
|
+
"pikchr",
|
|
18
|
+
"slides",
|
|
19
|
+
]
|
|
20
|
+
classifiers = [
|
|
21
|
+
"Development Status :: 3 - Alpha",
|
|
22
|
+
"Environment :: Console",
|
|
23
|
+
"Intended Audience :: End Users/Desktop",
|
|
24
|
+
"Operating System :: OS Independent",
|
|
25
|
+
"Programming Language :: Python :: 3",
|
|
26
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
27
|
+
"Programming Language :: Python :: 3.12",
|
|
28
|
+
"Programming Language :: Python :: 3.13",
|
|
29
|
+
"Programming Language :: Python :: 3.14",
|
|
30
|
+
"Topic :: Multimedia :: Graphics :: Presentation",
|
|
31
|
+
]
|
|
32
|
+
dependencies = [
|
|
33
|
+
"pillow>=12.3.0",
|
|
34
|
+
"python-pptx>=1.0.2",
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
[[project.authors]]
|
|
38
|
+
name = "Miki Yutani"
|
|
39
|
+
email = "mkyutani@gmail.com"
|
|
40
|
+
|
|
41
|
+
[project.urls]
|
|
42
|
+
Repository = "https://github.com/mkyutani/pikslide"
|
|
43
|
+
Issues = "https://github.com/mkyutani/pikslide/issues"
|
|
44
|
+
Documentation = "https://github.com/mkyutani/pikslide/blob/main/src/pikslide/docs/spec.md"
|
|
45
|
+
|
|
46
|
+
[project.scripts]
|
|
47
|
+
pikslide = "pikslide:main"
|
|
48
|
+
|
|
49
|
+
[build-system]
|
|
50
|
+
requires = ["uv_build>=0.12.5,<0.13.0"]
|
|
51
|
+
build-backend = "uv_build"
|
|
52
|
+
|
|
53
|
+
[dependency-groups]
|
|
54
|
+
dev = ["pytest>=9.1.1"]
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "pikslide"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "A text language for drawing diagrams as native, editable PowerPoint objects"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "0BSD"
|
|
7
|
+
license-files = ["LICENSE", "NOTICE"]
|
|
8
|
+
authors = [
|
|
9
|
+
{ name = "Miki Yutani", email = "mkyutani@gmail.com" }
|
|
10
|
+
]
|
|
11
|
+
requires-python = ">=3.12"
|
|
12
|
+
keywords = ["diagram", "powerpoint", "pptx", "pic", "pikchr", "slides"]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Development Status :: 3 - Alpha",
|
|
15
|
+
"Environment :: Console",
|
|
16
|
+
"Intended Audience :: End Users/Desktop",
|
|
17
|
+
"Operating System :: OS Independent",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
20
|
+
"Programming Language :: Python :: 3.12",
|
|
21
|
+
"Programming Language :: Python :: 3.13",
|
|
22
|
+
"Programming Language :: Python :: 3.14",
|
|
23
|
+
"Topic :: Multimedia :: Graphics :: Presentation",
|
|
24
|
+
]
|
|
25
|
+
dependencies = [
|
|
26
|
+
"pillow>=12.3.0",
|
|
27
|
+
"python-pptx>=1.0.2",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
[project.urls]
|
|
31
|
+
Repository = "https://github.com/mkyutani/pikslide"
|
|
32
|
+
Issues = "https://github.com/mkyutani/pikslide/issues"
|
|
33
|
+
Documentation = "https://github.com/mkyutani/pikslide/blob/main/src/pikslide/docs/spec.md"
|
|
34
|
+
|
|
35
|
+
[project.scripts]
|
|
36
|
+
pikslide = "pikslide:main"
|
|
37
|
+
|
|
38
|
+
[build-system]
|
|
39
|
+
requires = ["uv_build>=0.12.5,<0.13.0"]
|
|
40
|
+
build-backend = "uv_build"
|
|
41
|
+
|
|
42
|
+
[dependency-groups]
|
|
43
|
+
dev = [
|
|
44
|
+
"pytest>=9.1.1",
|
|
45
|
+
]
|