predictygraph 0.1.0__py3-none-any.whl
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/__init__.py +108 -0
- predictygraph/__main__.py +7 -0
- predictygraph/anim.py +91 -0
- predictygraph/cli.py +62 -0
- predictygraph/default.css +16 -0
- predictygraph/fonts/Carlito-Bold.ttf +0 -0
- predictygraph/fonts/Carlito-Regular.ttf +0 -0
- predictygraph/fonts/DejaVuSans-Bold.ttf +0 -0
- predictygraph/fonts/DejaVuSans.ttf +0 -0
- predictygraph/fonts/LiberationMono-Bold.ttf +0 -0
- predictygraph/fonts/LiberationMono-Regular.ttf +0 -0
- predictygraph/fonts/LiberationSans-Bold.ttf +0 -0
- predictygraph/fonts/LiberationSans-Regular.ttf +0 -0
- predictygraph/fonts/LiberationSerif-Bold.ttf +0 -0
- predictygraph/fonts/LiberationSerif-Regular.ttf +0 -0
- predictygraph/fonts.py +167 -0
- predictygraph/ir.py +62 -0
- predictygraph/layout.py +534 -0
- predictygraph/model.py +98 -0
- predictygraph/parser.py +310 -0
- predictygraph/render/__init__.py +17 -0
- predictygraph/render/apng.py +43 -0
- predictygraph/render/svg.py +121 -0
- predictygraph/route.py +453 -0
- predictygraph/safe.py +41 -0
- predictygraph/scene.py +349 -0
- predictygraph/style.py +204 -0
- predictygraph/text.py +80 -0
- predictygraph/theme.py +107 -0
- predictygraph/themes/catppuccin-frappe.toml +27 -0
- predictygraph/themes/catppuccin-latte.toml +27 -0
- predictygraph/themes/catppuccin-macchiato.toml +27 -0
- predictygraph/themes/catppuccin-mocha.toml +27 -0
- predictygraph/themes/default.toml +22 -0
- predictygraph/themes/dracula.toml +25 -0
- predictygraph/themes/github-light.toml +25 -0
- predictygraph/themes/gruvbox-dark.toml +24 -0
- predictygraph/themes/nord.toml +25 -0
- predictygraph/themes/solarized-dark.toml +15 -0
- predictygraph/themes/solarized-light.toml +24 -0
- predictygraph-0.1.0.dist-info/METADATA +60 -0
- predictygraph-0.1.0.dist-info/RECORD +44 -0
- predictygraph-0.1.0.dist-info/WHEEL +4 -0
- predictygraph-0.1.0.dist-info/entry_points.txt +6 -0
predictygraph/theme.py
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 The predictygraph Authors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
|
+
|
|
5
|
+
"""TOML colour themes -> CSS (variables + base rules). See docs/THEMES.md."""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
import tomllib
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
BUNDLED = Path(__file__).parent / "themes"
|
|
13
|
+
HUES = ("red", "orange", "yellow", "green", "cyan", "blue", "purple")
|
|
14
|
+
ROLE_DEFAULTS = {
|
|
15
|
+
"accent": "blue", "danger": "red", "node-fill": "surface", "node-stroke": "border",
|
|
16
|
+
"node-text": "fg", "group-fill": "bg-alt", "group-stroke": "border", "group-text": "muted",
|
|
17
|
+
"edge": "muted", "edge-text": "fg",
|
|
18
|
+
}
|
|
19
|
+
REQUIRED = ("bg", "surface", "fg", "muted", "border") + HUES
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ThemeError(ValueError):
|
|
23
|
+
pass
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _mix(a: str, b: str, t: float) -> str:
|
|
27
|
+
ca = [int(a[i:i + 2], 16) for i in (1, 3, 5)]
|
|
28
|
+
cb = [int(b[i:i + 2], 16) for i in (1, 3, 5)]
|
|
29
|
+
return "#" + "".join(f"{round(x * t + y * (1 - t)):02x}" for x, y in zip(ca, cb))
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def find_theme(name: str, base_dir: str = ".") -> Path:
|
|
33
|
+
cand = Path(base_dir) / name
|
|
34
|
+
if name.endswith(".toml") and cand.exists():
|
|
35
|
+
return cand
|
|
36
|
+
dirs = [d for d in os.environ.get("PDG_THEME_PATH", "").split(os.pathsep) if d] + [str(BUNDLED)]
|
|
37
|
+
for d in dirs:
|
|
38
|
+
p = Path(d) / f"{name}.toml"
|
|
39
|
+
if p.exists():
|
|
40
|
+
return p
|
|
41
|
+
raise ThemeError(f"unknown theme {name!r} (available: {', '.join(list_themes())})")
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def list_themes() -> list[str]:
|
|
45
|
+
return sorted(p.stem for p in BUNDLED.glob("*.toml"))
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def load_theme(name: str, base_dir: str = ".", _seen=()) -> dict:
|
|
49
|
+
path = find_theme(name, base_dir)
|
|
50
|
+
data = tomllib.loads(path.read_text(encoding="utf-8"))
|
|
51
|
+
if data.get("schema", 1) != 1:
|
|
52
|
+
raise ThemeError(f"{path}: unsupported schema {data['schema']}")
|
|
53
|
+
if "extends" in data:
|
|
54
|
+
if data["extends"] in _seen:
|
|
55
|
+
raise ThemeError(f"{path}: extends cycle")
|
|
56
|
+
parent = load_theme(data["extends"], str(path.parent), _seen + (name,))
|
|
57
|
+
for sect in ("palette", "roles", "shape"):
|
|
58
|
+
parent.setdefault(sect, {}).update(data.get(sect, {}))
|
|
59
|
+
parent["name"] = data.get("name", name)
|
|
60
|
+
parent["dark"] = data.get("dark", parent.get("dark", False))
|
|
61
|
+
data = parent
|
|
62
|
+
return data
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def theme_css(name: str, base_dir: str = ".") -> str:
|
|
66
|
+
t = load_theme(name, base_dir)
|
|
67
|
+
pal = dict(t.get("palette", {}))
|
|
68
|
+
missing = [k for k in REQUIRED if k not in pal]
|
|
69
|
+
if missing:
|
|
70
|
+
raise ThemeError(f"theme {name!r} palette missing: {', '.join(missing)}")
|
|
71
|
+
for k, v in pal.items():
|
|
72
|
+
if not (isinstance(v, str) and v.startswith("#") and len(v) == 7):
|
|
73
|
+
raise ThemeError(f"theme {name!r}: palette.{k} must be #rrggbb, got {v!r}")
|
|
74
|
+
pal.setdefault("bg-alt", _mix(pal["surface"], pal["bg"], 0.45))
|
|
75
|
+
for h in HUES:
|
|
76
|
+
pal.setdefault(f"{h}-soft", _mix(pal[h], pal["bg"], 0.22))
|
|
77
|
+
roles = {**ROLE_DEFAULTS, **t.get("roles", {})}
|
|
78
|
+
unknown = set(t.get("roles", {})) - set(ROLE_DEFAULTS)
|
|
79
|
+
if unknown:
|
|
80
|
+
raise ThemeError(f"theme {name!r}: unknown roles {sorted(unknown)}")
|
|
81
|
+
shape = t.get("shape", {})
|
|
82
|
+
|
|
83
|
+
def ref(v):
|
|
84
|
+
return f"var(--{v})" if v in pal else v
|
|
85
|
+
|
|
86
|
+
lines = [":root {"]
|
|
87
|
+
lines += [f" --{k}: {v};" for k, v in pal.items()]
|
|
88
|
+
lines += [f" --{k}: {ref(v)};" for k, v in roles.items()]
|
|
89
|
+
lines.append("}")
|
|
90
|
+
radius = shape.get("radius", 6)
|
|
91
|
+
lines.append("graph { background: var(--bg); color: var(--fg); }")
|
|
92
|
+
if "font" in shape:
|
|
93
|
+
lines.append(f'graph {{ font-family: "{shape["font"]}", sans-serif; }}')
|
|
94
|
+
lines.append(f"node {{ fill: var(--node-fill); stroke: var(--node-stroke); color: var(--node-text); "
|
|
95
|
+
f"border-radius: {radius}px; }}")
|
|
96
|
+
lines.append("group { fill: var(--group-fill); stroke: var(--group-stroke); color: var(--group-text); }")
|
|
97
|
+
lines.append("edge { stroke: var(--edge); color: var(--edge-text); }")
|
|
98
|
+
# semantic helper classes usable on any node/group/edge: .red .green .accent ...
|
|
99
|
+
for h in HUES + ("accent", "danger"):
|
|
100
|
+
base = f"var(--{h})"
|
|
101
|
+
soft = f"var(--{h}-soft)" if h in HUES else f"var(--{roles[h]}-soft)" if roles[h] in HUES else "var(--surface)"
|
|
102
|
+
lines.append(f"node.{h}, group.{h} {{ fill: {soft}; stroke: {base}; }}")
|
|
103
|
+
lines.append(f"edge.{h} {{ stroke: {base}; color: {base}; }}")
|
|
104
|
+
lines.append("node.solid { fill: var(--fg); stroke: var(--fg); color: var(--bg); }")
|
|
105
|
+
if "edge-width" in shape:
|
|
106
|
+
lines.append(f"edge {{ stroke-width: {shape['edge-width']}; }}")
|
|
107
|
+
return "\n".join(lines) + "\n"
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 The predictygraph Authors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
|
+
|
|
5
|
+
schema = 1
|
|
6
|
+
name = "catppuccin-frappe"
|
|
7
|
+
dark = true
|
|
8
|
+
|
|
9
|
+
[palette]
|
|
10
|
+
bg = "#303446"
|
|
11
|
+
surface = "#414559"
|
|
12
|
+
fg = "#c6d0f5"
|
|
13
|
+
muted = "#a5adce"
|
|
14
|
+
border = "#626880"
|
|
15
|
+
red = "#e78284"
|
|
16
|
+
orange = "#ef9f76"
|
|
17
|
+
yellow = "#e5c890"
|
|
18
|
+
green = "#a6d189"
|
|
19
|
+
cyan = "#81c8be"
|
|
20
|
+
blue = "#8caaee"
|
|
21
|
+
purple = "#ca9ee6"
|
|
22
|
+
|
|
23
|
+
[roles]
|
|
24
|
+
accent = "purple"
|
|
25
|
+
|
|
26
|
+
[shape]
|
|
27
|
+
radius = 10
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 The predictygraph Authors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
|
+
|
|
5
|
+
schema = 1
|
|
6
|
+
name = "catppuccin-latte"
|
|
7
|
+
dark = false
|
|
8
|
+
|
|
9
|
+
[palette]
|
|
10
|
+
bg = "#eff1f5"
|
|
11
|
+
surface = "#e6e9ef"
|
|
12
|
+
fg = "#4c4f69"
|
|
13
|
+
muted = "#6c6f85"
|
|
14
|
+
border = "#9ca0b0"
|
|
15
|
+
red = "#d20f39"
|
|
16
|
+
orange = "#fe640b"
|
|
17
|
+
yellow = "#df8e1d"
|
|
18
|
+
green = "#40a02b"
|
|
19
|
+
cyan = "#179299"
|
|
20
|
+
blue = "#1e66f5"
|
|
21
|
+
purple = "#8839ef"
|
|
22
|
+
|
|
23
|
+
[roles]
|
|
24
|
+
accent = "purple"
|
|
25
|
+
|
|
26
|
+
[shape]
|
|
27
|
+
radius = 10
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 The predictygraph Authors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
|
+
|
|
5
|
+
schema = 1
|
|
6
|
+
name = "catppuccin-macchiato"
|
|
7
|
+
dark = true
|
|
8
|
+
|
|
9
|
+
[palette]
|
|
10
|
+
bg = "#24273a"
|
|
11
|
+
surface = "#363a4f"
|
|
12
|
+
fg = "#cad3f5"
|
|
13
|
+
muted = "#a5adcb"
|
|
14
|
+
border = "#5b6078"
|
|
15
|
+
red = "#ed8796"
|
|
16
|
+
orange = "#f5a97f"
|
|
17
|
+
yellow = "#eed49f"
|
|
18
|
+
green = "#a6da95"
|
|
19
|
+
cyan = "#8bd5ca"
|
|
20
|
+
blue = "#8aadf4"
|
|
21
|
+
purple = "#c6a0f6"
|
|
22
|
+
|
|
23
|
+
[roles]
|
|
24
|
+
accent = "purple"
|
|
25
|
+
|
|
26
|
+
[shape]
|
|
27
|
+
radius = 10
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 The predictygraph Authors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
|
+
|
|
5
|
+
schema = 1
|
|
6
|
+
name = "catppuccin-mocha"
|
|
7
|
+
dark = true
|
|
8
|
+
|
|
9
|
+
[palette]
|
|
10
|
+
bg = "#1e1e2e"
|
|
11
|
+
surface = "#313244"
|
|
12
|
+
fg = "#cdd6f4"
|
|
13
|
+
muted = "#a6adc8"
|
|
14
|
+
border = "#585b70"
|
|
15
|
+
red = "#f38ba8"
|
|
16
|
+
orange = "#fab387"
|
|
17
|
+
yellow = "#f9e2af"
|
|
18
|
+
green = "#a6e3a1"
|
|
19
|
+
cyan = "#94e2d5"
|
|
20
|
+
blue = "#89b4fa"
|
|
21
|
+
purple = "#cba6f7"
|
|
22
|
+
|
|
23
|
+
[roles]
|
|
24
|
+
accent = "purple"
|
|
25
|
+
|
|
26
|
+
[shape]
|
|
27
|
+
radius = 10
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 The predictygraph Authors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
|
+
|
|
5
|
+
schema = 1
|
|
6
|
+
name = "default"
|
|
7
|
+
dark = false
|
|
8
|
+
|
|
9
|
+
[palette]
|
|
10
|
+
bg = "#ffffff"
|
|
11
|
+
surface = "#ffffff"
|
|
12
|
+
fg = "#111827"
|
|
13
|
+
muted = "#4b5563"
|
|
14
|
+
border = "#374151"
|
|
15
|
+
bg-alt = "#f3f4f6"
|
|
16
|
+
red = "#dc2626"
|
|
17
|
+
orange = "#ea580c"
|
|
18
|
+
yellow = "#ca8a04"
|
|
19
|
+
green = "#16a34a"
|
|
20
|
+
cyan = "#0891b2"
|
|
21
|
+
blue = "#2563eb"
|
|
22
|
+
purple = "#7c3aed"
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 The predictygraph Authors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
|
+
|
|
5
|
+
schema = 1
|
|
6
|
+
name = "dracula"
|
|
7
|
+
dark = true
|
|
8
|
+
|
|
9
|
+
[palette]
|
|
10
|
+
bg = "#282a36"
|
|
11
|
+
surface = "#44475a"
|
|
12
|
+
fg = "#f8f8f2"
|
|
13
|
+
muted = "#bfc3d9"
|
|
14
|
+
border = "#bd93f9"
|
|
15
|
+
red = "#ff5555"
|
|
16
|
+
orange = "#ffb86c"
|
|
17
|
+
yellow = "#f1fa8c"
|
|
18
|
+
green = "#50fa7b"
|
|
19
|
+
cyan = "#8be9fd"
|
|
20
|
+
blue = "#6272a4"
|
|
21
|
+
purple = "#bd93f9"
|
|
22
|
+
|
|
23
|
+
[roles]
|
|
24
|
+
accent = "purple"
|
|
25
|
+
edge = "purple"
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 The predictygraph Authors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
|
+
|
|
5
|
+
schema = 1
|
|
6
|
+
name = "github-light"
|
|
7
|
+
dark = false
|
|
8
|
+
|
|
9
|
+
[palette]
|
|
10
|
+
bg = "#ffffff"
|
|
11
|
+
surface = "#f6f8fa"
|
|
12
|
+
fg = "#1f2328"
|
|
13
|
+
muted = "#656d76"
|
|
14
|
+
border = "#d0d7de"
|
|
15
|
+
red = "#cf222e"
|
|
16
|
+
orange = "#bc4c00"
|
|
17
|
+
yellow = "#9a6700"
|
|
18
|
+
green = "#1a7f37"
|
|
19
|
+
cyan = "#1b7c83"
|
|
20
|
+
blue = "#0969da"
|
|
21
|
+
purple = "#8250df"
|
|
22
|
+
|
|
23
|
+
[roles]
|
|
24
|
+
node-stroke = "muted"
|
|
25
|
+
group-fill = "bg"
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 The predictygraph Authors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
|
+
|
|
5
|
+
schema = 1
|
|
6
|
+
name = "gruvbox-dark"
|
|
7
|
+
dark = true
|
|
8
|
+
|
|
9
|
+
[palette]
|
|
10
|
+
bg = "#282828"
|
|
11
|
+
surface = "#3c3836"
|
|
12
|
+
fg = "#ebdbb2"
|
|
13
|
+
muted = "#a89984"
|
|
14
|
+
border = "#665c54"
|
|
15
|
+
red = "#fb4934"
|
|
16
|
+
orange = "#fe8019"
|
|
17
|
+
yellow = "#fabd2f"
|
|
18
|
+
green = "#b8bb26"
|
|
19
|
+
cyan = "#8ec07c"
|
|
20
|
+
blue = "#83a598"
|
|
21
|
+
purple = "#d3869b"
|
|
22
|
+
|
|
23
|
+
[roles]
|
|
24
|
+
accent = "yellow"
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 The predictygraph Authors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
|
+
|
|
5
|
+
schema = 1
|
|
6
|
+
name = "nord"
|
|
7
|
+
dark = true
|
|
8
|
+
|
|
9
|
+
[palette]
|
|
10
|
+
bg = "#2e3440"
|
|
11
|
+
surface = "#3b4252"
|
|
12
|
+
fg = "#eceff4"
|
|
13
|
+
muted = "#d8dee9"
|
|
14
|
+
border = "#81a1c1"
|
|
15
|
+
red = "#bf616a"
|
|
16
|
+
orange = "#d08770"
|
|
17
|
+
yellow = "#ebcb8b"
|
|
18
|
+
green = "#a3be8c"
|
|
19
|
+
cyan = "#88c0d0"
|
|
20
|
+
blue = "#81a1c1"
|
|
21
|
+
purple = "#b48ead"
|
|
22
|
+
|
|
23
|
+
[roles]
|
|
24
|
+
accent = "cyan"
|
|
25
|
+
edge = "cyan"
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 The predictygraph Authors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
|
+
|
|
5
|
+
schema = 1
|
|
6
|
+
name = "solarized-dark"
|
|
7
|
+
extends = "solarized-light"
|
|
8
|
+
dark = true
|
|
9
|
+
|
|
10
|
+
[palette]
|
|
11
|
+
bg = "#002b36"
|
|
12
|
+
surface = "#073642"
|
|
13
|
+
fg = "#eee8d5"
|
|
14
|
+
muted = "#93a1a1"
|
|
15
|
+
border = "#586e75"
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 The predictygraph Authors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
|
+
|
|
5
|
+
schema = 1
|
|
6
|
+
name = "solarized-light"
|
|
7
|
+
dark = false
|
|
8
|
+
|
|
9
|
+
[palette]
|
|
10
|
+
bg = "#fdf6e3"
|
|
11
|
+
surface = "#eee8d5"
|
|
12
|
+
fg = "#073642"
|
|
13
|
+
muted = "#657b83"
|
|
14
|
+
border = "#93a1a1"
|
|
15
|
+
red = "#dc322f"
|
|
16
|
+
orange = "#cb4b16"
|
|
17
|
+
yellow = "#b58900"
|
|
18
|
+
green = "#859900"
|
|
19
|
+
cyan = "#2aa198"
|
|
20
|
+
blue = "#268bd2"
|
|
21
|
+
purple = "#6c71c4"
|
|
22
|
+
|
|
23
|
+
[roles]
|
|
24
|
+
group-fill = "bg"
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: predictygraph
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Predictable graphs: a readable, CSS-styled diagram DSL with per-group layouts, rendered to SVG/APNG
|
|
5
|
+
Author-Email: Reza Jelveh <git@jelveh.me>
|
|
6
|
+
License: GPL-3.0-or-later
|
|
7
|
+
Requires-Python: >=3.11
|
|
8
|
+
Requires-Dist: tinycss2>=1.5.1
|
|
9
|
+
Requires-Dist: typer>=0.26.8
|
|
10
|
+
Requires-Dist: pillow>=11.0.0
|
|
11
|
+
Provides-Extra: apng
|
|
12
|
+
Requires-Dist: cairosvg>=2.7; extra == "apng"
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
|
|
15
|
+
<!--
|
|
16
|
+
SPDX-FileCopyrightText: 2026 The predictygraph Authors
|
|
17
|
+
|
|
18
|
+
SPDX-License-Identifier: GPL-3.0-or-later
|
|
19
|
+
-->
|
|
20
|
+
|
|
21
|
+
# predictygraph
|
|
22
|
+
|
|
23
|
+
**Predictable graphs.** A readable diagram DSL with per-group layouts ("balancing styles"),
|
|
24
|
+
plain-CSS styling, and static or animated SVG/APNG output (no browser).
|
|
25
|
+
Spec: [docs/SPEC.md](docs/SPEC.md). Docs: [predictygraph.github.io](https://predictygraph.github.io/).
|
|
26
|
+
Editor support: [tree-sitter-pdg](https://github.com/predictygraph/tree-sitter-pdg).
|
|
27
|
+
Rendered examples and the gallery: [predictygraph.github.io](https://predictygraph.github.io/). This repo keeps
|
|
28
|
+
only `.pdg` sources; images live in the docs repo (git-lfs).
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
uv run pdg examples/hami_flow.pdg # -> examples/hami_flow.svg (not committed)
|
|
32
|
+
uv run pdg diagram.pdg --css theme.css -o out.svg
|
|
33
|
+
uv run pdg diagram.pdg -o out.png # animated PNG (APNG)
|
|
34
|
+
uv run pdg diagram.pdg --check # validate only
|
|
35
|
+
uv run pdg diagram.pdg --target web # size labels to fit any browser font
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
`pdg` is the short alias of the `predictygraph` command.
|
|
39
|
+
|
|
40
|
+
## Credits
|
|
41
|
+
|
|
42
|
+
This project stands on the shoulders of two giants.
|
|
43
|
+
|
|
44
|
+
**[Graphviz](https://graphviz.org/) (dot)** taught a generation that diagrams can be
|
|
45
|
+
text. Its layered layout algorithm is still the reference for graph drawing, and
|
|
46
|
+
we are grateful for decades of work on it. But dot optimises for the whole graph
|
|
47
|
+
at once: you describe nodes and edges, and the engine decides where they go.
|
|
48
|
+
Nudging one cluster without disturbing the rest means fighting `rank`, `weight`
|
|
49
|
+
and invisible edges. Styling lives in attributes rather than CSS, and the output
|
|
50
|
+
often looks like a paper figure rather than a slide.
|
|
51
|
+
|
|
52
|
+
**[Mermaid](https://mermaid.js.org/)** made text diagrams mainstream by putting
|
|
53
|
+
them in Markdown, READMEs and docs sites. Its syntax is friendly and we borrowed
|
|
54
|
+
from its spirit. But it renders through a browser and JavaScript, leaves little
|
|
55
|
+
control over layout, and the same source can render differently across versions
|
|
56
|
+
and hosts.
|
|
57
|
+
|
|
58
|
+
predictygraph keeps what we love from both (diagrams as readable text) and adds what we
|
|
59
|
+
missed: per-group layouts, plain-CSS styling, and deterministic static SVG with no
|
|
60
|
+
browser in the loop.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
predictygraph-0.1.0.dist-info/METADATA,sha256=CoDqApa_uMOvZDcWrJ3tIrcUtT80fgNGzhRengYnJTU,2689
|
|
2
|
+
predictygraph-0.1.0.dist-info/WHEEL,sha256=IuIk3wbaEnFH1cx75iM2R1CmliRI3dFLXTbRakgvgFQ,90
|
|
3
|
+
predictygraph-0.1.0.dist-info/entry_points.txt,sha256=yde4kgZ0WRlm5G5l-bjg2OgDIrtUCIYfkPbLgVoJq6g,100
|
|
4
|
+
predictygraph/__init__.py,sha256=f7zBi_TUZDt4V-ELDQyHk31fzhi2OQEH4YvHuN-xZzY,4395
|
|
5
|
+
predictygraph/__main__.py,sha256=0F2Unhc4kKA6uxBytbfvF03Fn2hNKDr9r6HyDi2s8Ig,132
|
|
6
|
+
predictygraph/anim.py,sha256=gsjFrTwykcvZW9ICdWaYuu0HlOU4WWTRso0t2l2C6f4,3162
|
|
7
|
+
predictygraph/cli.py,sha256=7l5U1IRedyCmwEWWM-5ZDIQA25BcuFZ_3HKwGAn69jA,3088
|
|
8
|
+
predictygraph/default.css,sha256=vbBfmABACFHe3ZQVhJ7IJbpLpmv7aip2dFwytxWOs-Q,751
|
|
9
|
+
predictygraph/fonts.py,sha256=3CdQFgjvzpyL6YdAhudB_tBBFq-mPBpYZOvZ8XqDd5o,7647
|
|
10
|
+
predictygraph/fonts/Carlito-Bold.ttf,sha256=uyNP56DvE4vqsqoFk02kl7LkOUd1pWUs48iW2TAFwsQ,58012
|
|
11
|
+
predictygraph/fonts/Carlito-Regular.ttf,sha256=MN2s88fyeXioDICb_MkWZp3ouIvMU9cJmgIwuncqKjU,46056
|
|
12
|
+
predictygraph/fonts/DejaVuSans-Bold.ttf,sha256=8z1aujFUcQllZd4gESIK0AVFTuxTHOaCEE0RsrkTkeY,31864
|
|
13
|
+
predictygraph/fonts/DejaVuSans.ttf,sha256=APTQyByjSZV9-sYuoCnXe276iFZmny3CcW90zrVBWKY,38268
|
|
14
|
+
predictygraph/fonts/LiberationMono-Bold.ttf,sha256=y25HdnJTYHyPnxFOAnHprHigxxtqJAq2_9QbWC9emkA,10300
|
|
15
|
+
predictygraph/fonts/LiberationMono-Regular.ttf,sha256=-lAx0L1_BJPW1Nl_AALhaD_kD4sf_5URKKRGuaDK3gY,9680
|
|
16
|
+
predictygraph/fonts/LiberationSans-Bold.ttf,sha256=cDQz0tZxoafJM-oQBgZ4jYRQSb4Sphc8qPl0XHBsaMQ,19408
|
|
17
|
+
predictygraph/fonts/LiberationSans-Regular.ttf,sha256=MDnbaCx53AHWIMqvPiBpy-TUL6PH6YvOcMa5NpKHKv8,19736
|
|
18
|
+
predictygraph/fonts/LiberationSerif-Bold.ttf,sha256=WE7FT4YNjPETuGFlvyslCL6cYd-1rdh4UNQqzWnNfws,10740
|
|
19
|
+
predictygraph/fonts/LiberationSerif-Regular.ttf,sha256=3BuekcztcwjkSZ20inLWZuBLp3xpDLRgkE7j5uUqH4Y,10060
|
|
20
|
+
predictygraph/ir.py,sha256=xY4K-qa5F06JMpkROPO-8E2qmyKv9VpfF-fGXObWGJ4,2110
|
|
21
|
+
predictygraph/layout.py,sha256=mue-hjQ5QeNb4o4vn3GuLfAXgAvPMdU06hjooljA56E,22106
|
|
22
|
+
predictygraph/model.py,sha256=jz_GDCqu8C-KqjvYiu2bkH-f8NgUhOCmYuyNya1tD1s,2684
|
|
23
|
+
predictygraph/parser.py,sha256=r26WZp0oTS1mm3o8-EAx8qII0GEpGtAL9MSvQs0i0TA,11586
|
|
24
|
+
predictygraph/render/__init__.py,sha256=ALzR1UUJcUW1KvjzidRsmg7GQckUlXr3zbceNprzGBQ,496
|
|
25
|
+
predictygraph/render/apng.py,sha256=JYeThbH7xjYW_zmZHl4HDcCqUxgp4xCGT3Iw6RkH8Eo,1639
|
|
26
|
+
predictygraph/render/svg.py,sha256=nURaWmmgl-j7Lw_Eas0sSES4PSw3Es7Z_8N69J-nJt0,4877
|
|
27
|
+
predictygraph/route.py,sha256=RsJL3B9-x8iYTTm06k_yUel1HtcTvslKXSVzmxgF4X8,20559
|
|
28
|
+
predictygraph/safe.py,sha256=yogRtscoKxYDi6C7TX13HJ6CFXfFn7B_i7oFW-WREb8,1331
|
|
29
|
+
predictygraph/scene.py,sha256=6-6j335ziIwYgwNVUNbYJlnYlKqbXhOekcf7r_dKvY8,18422
|
|
30
|
+
predictygraph/style.py,sha256=2vecRNRYKum8cx0eZ89ldPDU6HAR-S9F4F-jtepz-7U,7731
|
|
31
|
+
predictygraph/text.py,sha256=x3Tm7FbQXjhPuREofQkh-zG3Q_1Sd9oUkvOrbVC6AIQ,2723
|
|
32
|
+
predictygraph/theme.py,sha256=sY1VR7wtsQbLi06eqPzOpF3g6Ril447aM9cu84Vfqes,4543
|
|
33
|
+
predictygraph/themes/catppuccin-frappe.toml,sha256=1IfcQWEu6zHnKMViicqhPtpbNKpRvVsCM5j3DdMCKHI,425
|
|
34
|
+
predictygraph/themes/catppuccin-latte.toml,sha256=4aWAdU7fvs0j0SzVG0s3I8xl63XLgo7CGTqq4ziFYA0,425
|
|
35
|
+
predictygraph/themes/catppuccin-macchiato.toml,sha256=7PjwFAATdAhhj-x2O04Pjxnw-Q6olEwMMozQi1b5zcg,428
|
|
36
|
+
predictygraph/themes/catppuccin-mocha.toml,sha256=VwGfiF2aKXe9TbqJUASEslLW3Wqf-_e6wOvsZ4-oKfI,424
|
|
37
|
+
predictygraph/themes/default.toml,sha256=0SJw8oGTJVw9N_Hj5w40vvBHz6-g9fF-TbkFWA_f_ss,387
|
|
38
|
+
predictygraph/themes/dracula.toml,sha256=WR9EkNw4LGSBlIk1s47JylRUhFyHPiI_h3rPbxUqYmQ,410
|
|
39
|
+
predictygraph/themes/github-light.toml,sha256=qlG2LPuuYPfkpbV9wEHmAV2Iinlhii8NRJ-IP8hXMrk,422
|
|
40
|
+
predictygraph/themes/gruvbox-dark.toml,sha256=_qTu1OcT54kg4HWCPSm78W60Vo11WU21WrvjD1r3sFY,399
|
|
41
|
+
predictygraph/themes/nord.toml,sha256=OiSYUlGUcdK3oniAY4AhBLgFTsIQS8VJ183Q1ChV124,403
|
|
42
|
+
predictygraph/themes/solarized-dark.toml,sha256=0aYVb90TDBhUd8MWrI_3hqQ9-PcRNbokWFLjWVwZhM8,277
|
|
43
|
+
predictygraph/themes/solarized-light.toml,sha256=8H6EBjALiUEGNll5zrH_5o0iT0PwbJ1amrAlfmEu088,403
|
|
44
|
+
predictygraph-0.1.0.dist-info/RECORD,,
|