predictygraph 0.2.3__tar.gz → 0.2.4__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.
- {predictygraph-0.2.3 → predictygraph-0.2.4}/PKG-INFO +32 -8
- {predictygraph-0.2.3 → predictygraph-0.2.4}/README.md +31 -7
- {predictygraph-0.2.3 → predictygraph-0.2.4}/pyproject.toml +1 -1
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/layout.py +17 -8
- {predictygraph-0.2.3 → predictygraph-0.2.4}/tests/test_stack.py +14 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/__init__.py +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/__main__.py +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/anim.py +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/cli.py +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/default.css +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/fonts/Carlito-Bold.ttf +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/fonts/Carlito-Regular.ttf +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/fonts/DejaVuSans-Bold.ttf +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/fonts/DejaVuSans.ttf +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/fonts/LiberationMono-Bold.ttf +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/fonts/LiberationMono-Regular.ttf +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/fonts/LiberationSans-Bold.ttf +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/fonts/LiberationSans-Regular.ttf +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/fonts/LiberationSerif-Bold.ttf +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/fonts/LiberationSerif-Regular.ttf +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/fonts.py +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/ir.py +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/model.py +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/parser.py +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/render/__init__.py +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/render/apng.py +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/render/svg.py +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/route.py +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/safe.py +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/scene.py +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/style.py +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/styleutil.py +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/text.py +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/theme.py +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/themes/catppuccin-frappe.toml +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/themes/catppuccin-latte.toml +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/themes/catppuccin-macchiato.toml +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/themes/catppuccin-mocha.toml +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/themes/default.toml +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/themes/dracula.toml +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/themes/github-light.toml +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/themes/gruvbox-dark.toml +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/themes/hami.toml +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/themes/nord.toml +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/themes/solarized-dark.toml +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/themes/solarized-light.toml +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/tests/test_annotations.py +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/tests/test_diagonal.py +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/tests/test_fixes.py +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/tests/test_hardening.py +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/tests/test_predictygraph.py +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/tests/test_routing.py +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/tests/test_scene.py +0 -0
- {predictygraph-0.2.3 → predictygraph-0.2.4}/tests/test_targets.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: predictygraph
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4
|
|
4
4
|
Summary: Predictable graphs: a readable, CSS-styled diagram DSL with per-group layouts, rendered to SVG/APNG
|
|
5
5
|
Author-Email: Reza Jelveh <git@jelveh.me>
|
|
6
6
|
License: GPL-3.0-or-later
|
|
@@ -27,16 +27,40 @@ Editor support: [tree-sitter-pdg](https://github.com/predictygraph/tree-sitter-p
|
|
|
27
27
|
Rendered examples and the gallery: [predictygraph.github.io](https://predictygraph.github.io/). This repo keeps
|
|
28
28
|
only `.pdg` sources; images live in the docs repo (git-lfs).
|
|
29
29
|
|
|
30
|
+
## Install
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
uv tool install "predictygraph[apng]" # or: pipx install "predictygraph[apng]"
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
`[apng]` adds PNG output. `pdg` is the short alias of the `predictygraph` command.
|
|
37
|
+
|
|
38
|
+
## Use
|
|
39
|
+
|
|
30
40
|
```bash
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
41
|
+
pdg examples/annotations.pdg # -> examples/annotations.svg (not committed)
|
|
42
|
+
pdg diagram.pdg --css theme.css -o out.svg
|
|
43
|
+
pdg diagram.pdg -o out.png # PNG (animated if the diagram moves)
|
|
44
|
+
pdg diagram.pdg --check # validate only
|
|
45
|
+
pdg diagram.pdg -o d.png --width 1000 --colors 64 # small PNG for chat
|
|
46
|
+
pdg diagram.pdg --target web # size labels to fit any browser font
|
|
37
47
|
```
|
|
38
48
|
|
|
39
|
-
|
|
49
|
+
From a checkout, prefix these with `uv run`. Start with
|
|
50
|
+
[examples/annotations.pdg](examples/annotations.pdg): one small diagram that uses every
|
|
51
|
+
annotation feature, with a comment for each.
|
|
52
|
+
|
|
53
|
+
## Agent skill
|
|
54
|
+
|
|
55
|
+
[skills/predictygraph](skills/predictygraph) teaches an AI agent to write, render and
|
|
56
|
+
check `.pdg` diagrams.
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
# Hermes Agent
|
|
60
|
+
hermes skills install https://raw.githubusercontent.com/predictygraph/predictygraph/master/skills/predictygraph/SKILL.md
|
|
61
|
+
# Claude Code and other agents that read SKILL.md folders: copy the folder
|
|
62
|
+
cp -r skills/predictygraph ~/.claude/skills/
|
|
63
|
+
```
|
|
40
64
|
|
|
41
65
|
## Credits
|
|
42
66
|
|
|
@@ -13,16 +13,40 @@ Editor support: [tree-sitter-pdg](https://github.com/predictygraph/tree-sitter-p
|
|
|
13
13
|
Rendered examples and the gallery: [predictygraph.github.io](https://predictygraph.github.io/). This repo keeps
|
|
14
14
|
only `.pdg` sources; images live in the docs repo (git-lfs).
|
|
15
15
|
|
|
16
|
+
## Install
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
uv tool install "predictygraph[apng]" # or: pipx install "predictygraph[apng]"
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
`[apng]` adds PNG output. `pdg` is the short alias of the `predictygraph` command.
|
|
23
|
+
|
|
24
|
+
## Use
|
|
25
|
+
|
|
16
26
|
```bash
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
27
|
+
pdg examples/annotations.pdg # -> examples/annotations.svg (not committed)
|
|
28
|
+
pdg diagram.pdg --css theme.css -o out.svg
|
|
29
|
+
pdg diagram.pdg -o out.png # PNG (animated if the diagram moves)
|
|
30
|
+
pdg diagram.pdg --check # validate only
|
|
31
|
+
pdg diagram.pdg -o d.png --width 1000 --colors 64 # small PNG for chat
|
|
32
|
+
pdg diagram.pdg --target web # size labels to fit any browser font
|
|
23
33
|
```
|
|
24
34
|
|
|
25
|
-
|
|
35
|
+
From a checkout, prefix these with `uv run`. Start with
|
|
36
|
+
[examples/annotations.pdg](examples/annotations.pdg): one small diagram that uses every
|
|
37
|
+
annotation feature, with a comment for each.
|
|
38
|
+
|
|
39
|
+
## Agent skill
|
|
40
|
+
|
|
41
|
+
[skills/predictygraph](skills/predictygraph) teaches an AI agent to write, render and
|
|
42
|
+
check `.pdg` diagrams.
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# Hermes Agent
|
|
46
|
+
hermes skills install https://raw.githubusercontent.com/predictygraph/predictygraph/master/skills/predictygraph/SKILL.md
|
|
47
|
+
# Claude Code and other agents that read SKILL.md folders: copy the folder
|
|
48
|
+
cp -r skills/predictygraph ~/.claude/skills/
|
|
49
|
+
```
|
|
26
50
|
|
|
27
51
|
## Credits
|
|
28
52
|
|
|
@@ -160,6 +160,9 @@ class LineLayout(Layout):
|
|
|
160
160
|
if j != i + 1:
|
|
161
161
|
continue
|
|
162
162
|
w, _, _ = text_block(e.label, e.label_style or e.style, 11, bold=False)
|
|
163
|
+
if e.attrs.get("step"): # the step badge sits just left of the label
|
|
164
|
+
bw, bh, _ = text_block(e.attrs["step"][:3], e.step_style or e.style, 11, bold=True)
|
|
165
|
+
w += max(bw, bh) + 12
|
|
163
166
|
need[i] = max(need.get(i, 0.0), w + 34)
|
|
164
167
|
return need
|
|
165
168
|
|
|
@@ -570,20 +573,26 @@ def shift(item: Item, dx: float) -> None:
|
|
|
570
573
|
|
|
571
574
|
def align_x(doc: Document) -> None:
|
|
572
575
|
"""`align-x=ID`: centre an item horizontally on another item, e.g. line up a box with
|
|
573
|
-
the one it calls in the panel below.
|
|
574
|
-
|
|
576
|
+
the one it calls in the panel below. Siblings on the side it moves towards travel with
|
|
577
|
+
it, so every gap (and the edge labels in it) keeps its width; the whole block stays
|
|
578
|
+
inside the parent's content box, so no group is resized and nothing overlaps."""
|
|
575
579
|
for item in list(doc.walk()):
|
|
576
580
|
ref = doc.items.get(item.attrs.get("align-x", ""))
|
|
577
581
|
p = item.parent
|
|
578
582
|
if ref is None or ref is item or p is None:
|
|
579
583
|
continue
|
|
580
584
|
pr = box4(p.style.get("padding"), 14)[1]
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
585
|
+
lo_edge, hi_edge = p.ax + p.ox, p.ax + p.w - pr
|
|
586
|
+
dx = ref.cx - item.cx
|
|
587
|
+
if dx > 0: # item and everything right of it move right, up to the right edge
|
|
588
|
+
block = [s for s in p.children if s is item or s.ax >= item.ax + item.w - 1e-6]
|
|
589
|
+
dx = min(dx, hi_edge - max(s.ax + s.w for s in block))
|
|
590
|
+
else: # item and everything left of it move left, down to the left edge
|
|
591
|
+
block = [s for s in p.children if s is item or s.ax + s.w <= item.ax + 1e-6]
|
|
592
|
+
dx = max(dx, lo_edge - min(s.ax for s in block))
|
|
593
|
+
if abs(dx) > 0.01:
|
|
594
|
+
for s in block:
|
|
595
|
+
shift(s, dx)
|
|
587
596
|
|
|
588
597
|
|
|
589
598
|
def layout(doc: Document) -> None:
|
|
@@ -82,3 +82,17 @@ def test_accent_bar_stays_inside_rounded_corners():
|
|
|
82
82
|
assert min(ys) > 0 and max(ys) < 40 # starts below the top edge: it follows the arc
|
|
83
83
|
right = accent_segs(0, 0, 100, 40, 4, 10, "right")
|
|
84
84
|
assert min(s[-2] for s in right if s[0] != "Z") >= 96
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def test_align_x_keeps_gaps_by_moving_neighbours():
|
|
88
|
+
src = ('graph layout=column align=stretch\n'
|
|
89
|
+
'group top layout=row gap=300 {\n p "p"\n q "q"\n}\n'
|
|
90
|
+
'group bottom layout=row gap=30 {\n a "aaaa" align-x=q\n b "bbbb"\n}\n'
|
|
91
|
+
'a -> b "a fairly long label"\n')
|
|
92
|
+
plain = parse(src.replace(" align-x=q", ""))
|
|
93
|
+
build_scene(plain)
|
|
94
|
+
doc = parse(src)
|
|
95
|
+
build_scene(doc)
|
|
96
|
+
gap = lambda d: d.items["b"].ax - (d.items["a"].ax + d.items["a"].w)
|
|
97
|
+
assert abs(gap(doc) - gap(plain)) < 0.01 # b moved with a: the label still fits
|
|
98
|
+
assert doc.items["a"].ax > plain.items["a"].ax
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/fonts/LiberationMono-Regular.ttf
RENAMED
|
File without changes
|
|
File without changes
|
{predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/fonts/LiberationSans-Regular.ttf
RENAMED
|
File without changes
|
{predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/fonts/LiberationSerif-Bold.ttf
RENAMED
|
File without changes
|
{predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/fonts/LiberationSerif-Regular.ttf
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{predictygraph-0.2.3 → predictygraph-0.2.4}/src/predictygraph/themes/catppuccin-macchiato.toml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|