slidemark 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.
Files changed (115) hide show
  1. slidemark/__init__.py +8 -0
  2. slidemark/build.py +60 -0
  3. slidemark/cli.py +755 -0
  4. slidemark/contrast.py +95 -0
  5. slidemark/critique.py +341 -0
  6. slidemark/design.py +333 -0
  7. slidemark/fit.py +459 -0
  8. slidemark/fix.py +377 -0
  9. slidemark/fonts/fonts.conf +110 -0
  10. slidemark/forms.py +184 -0
  11. slidemark/forms2.py +283 -0
  12. slidemark/forms3.py +175 -0
  13. slidemark/honour.py +627 -0
  14. slidemark/htmlnative.py +950 -0
  15. slidemark/icons/__init__.py +349 -0
  16. slidemark/icons/glyphs.py +237 -0
  17. slidemark/icons/svgfile.py +257 -0
  18. slidemark/importer/__init__.py +702 -0
  19. slidemark/importer/design.py +370 -0
  20. slidemark/importer/diet.py +792 -0
  21. slidemark/importer/emit.py +467 -0
  22. slidemark/importer/forms2.py +358 -0
  23. slidemark/importer/links.py +424 -0
  24. slidemark/importer/look.py +341 -0
  25. slidemark/importer/mathml.py +194 -0
  26. slidemark/importer/read.py +1085 -0
  27. slidemark/importer/recognise.py +801 -0
  28. slidemark/importer/recognise2.py +947 -0
  29. slidemark/importer/recognise3.py +622 -0
  30. slidemark/importer/runs.py +243 -0
  31. slidemark/importer/shadows.py +44 -0
  32. slidemark/importer/structure.py +1603 -0
  33. slidemark/importer/vocab.py +266 -0
  34. slidemark/ir.py +415 -0
  35. slidemark/jsonio.py +53 -0
  36. slidemark/layout/__init__.py +7 -0
  37. slidemark/layout/boxpin.py +133 -0
  38. slidemark/layout/cardlook.py +143 -0
  39. slidemark/layout/chartnote.py +689 -0
  40. slidemark/layout/css.py +736 -0
  41. slidemark/layout/diagram.py +1003 -0
  42. slidemark/layout/engine.py +5240 -0
  43. slidemark/layout/forms2.py +1668 -0
  44. slidemark/layout/gantt.py +397 -0
  45. slidemark/layout/grid.py +300 -0
  46. slidemark/layout/htmlslide.py +83 -0
  47. slidemark/layout/jbreak.py +217 -0
  48. slidemark/layout/kpirow.py +84 -0
  49. slidemark/layout/kpirule.py +135 -0
  50. slidemark/layout/kpiunit.py +77 -0
  51. slidemark/layout/l3fill.py +1884 -0
  52. slidemark/layout/measure.py +733 -0
  53. slidemark/layout/metrics/widths.json +1 -0
  54. slidemark/layout/pills.py +207 -0
  55. slidemark/layout/score.py +176 -0
  56. slidemark/layout/search.py +83 -0
  57. slidemark/layout/sparsefill.py +221 -0
  58. slidemark/layout/stepspin.py +116 -0
  59. slidemark/layout/tablehl.py +103 -0
  60. slidemark/layout/tables.py +352 -0
  61. slidemark/layout/vfill.py +478 -0
  62. slidemark/layout/vocab.py +1171 -0
  63. slidemark/lint.py +731 -0
  64. slidemark/parser/__init__.py +34 -0
  65. slidemark/parser/attrs.py +463 -0
  66. slidemark/parser/blocks.py +528 -0
  67. slidemark/parser/core.py +1183 -0
  68. slidemark/parser/css.py +1114 -0
  69. slidemark/parser/ctx.py +46 -0
  70. slidemark/parser/html.py +1105 -0
  71. slidemark/parser/inline.py +307 -0
  72. slidemark/parser/lenient.py +250 -0
  73. slidemark/parser/mermaid.py +346 -0
  74. slidemark/parser/tabular.py +761 -0
  75. slidemark/parser/tokens.py +399 -0
  76. slidemark/presets/default.yaml +26 -0
  77. slidemark/presets/jp-business.yaml +57 -0
  78. slidemark/presets/midnight.yaml +23 -0
  79. slidemark/preview.py +175 -0
  80. slidemark/redesign.py +685 -0
  81. slidemark/render/__init__.py +982 -0
  82. slidemark/render/anim.py +213 -0
  83. slidemark/render/axis.py +295 -0
  84. slidemark/render/charthl.py +114 -0
  85. slidemark/render/design_part.py +337 -0
  86. slidemark/render/effects.py +308 -0
  87. slidemark/render/htmlimg.py +262 -0
  88. slidemark/render/icons.py +101 -0
  89. slidemark/render/math.py +419 -0
  90. slidemark/render/media.py +199 -0
  91. slidemark/render/objects.py +1308 -0
  92. slidemark/render/svg.py +236 -0
  93. slidemark/render/text.py +300 -0
  94. slidemark/render/util.py +155 -0
  95. slidemark/render/vocabshapes.py +79 -0
  96. slidemark/render/waterfall.py +137 -0
  97. slidemark/selfreview.py +514 -0
  98. slidemark/shapes.py +147 -0
  99. slidemark/skill/SKILL.md +287 -0
  100. slidemark/skill/reference/charts-tables.md +52 -0
  101. slidemark/skill/reference/components.md +65 -0
  102. slidemark/skill/reference/design.md +55 -0
  103. slidemark/skill/reference/diagnostics.md +36 -0
  104. slidemark/skill/reference/icons.md +12 -0
  105. slidemark/skill/reference/jp-dense.md +29 -0
  106. slidemark/skill/reference/review.md +16 -0
  107. slidemark/skill/reference/syntax.md +42 -0
  108. slidemark/template.py +391 -0
  109. slidemark/theme.py +2077 -0
  110. slidemark/units.py +55 -0
  111. slidemark/xsd.py +149 -0
  112. slidemark-0.1.0.dist-info/METADATA +384 -0
  113. slidemark-0.1.0.dist-info/RECORD +115 -0
  114. slidemark-0.1.0.dist-info/WHEEL +4 -0
  115. slidemark-0.1.0.dist-info/entry_points.txt +2 -0
slidemark/__init__.py ADDED
@@ -0,0 +1,8 @@
1
+ """SlideMark: token-efficient Markdown -> native, editable PowerPoint for AI agents."""
2
+
3
+ from .build import build
4
+ from .ir import Deck, Slide
5
+ from .parser import parse
6
+
7
+ __all__ = ["Deck", "Slide", "build", "parse"]
8
+ __version__ = "0.1.0"
slidemark/build.py ADDED
@@ -0,0 +1,60 @@
1
+ """End-to-end pipeline: text -> Deck -> layout -> .pptx."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pathlib import Path
6
+
7
+ from .ir import Deck
8
+ from .layout import layout_slide
9
+ from .lint import lint_deck
10
+ from .parser import parse
11
+ from .template import deck_theme, template_size
12
+
13
+
14
+ def build(source: str | Path, out: str | Path, *, base_dir: str | Path | None = None) -> Deck:
15
+ """Build a .pptx from text or a .md/.json/.html path. Returns the Deck (with diagnostics)."""
16
+ exts = (".md", ".json", ".html")
17
+ is_path = isinstance(source, Path) or ("\n" not in source and str(source).endswith(exts))
18
+ if is_path:
19
+ path = Path(source)
20
+ base_dir = base_dir or path.parent
21
+ if path.suffix == ".json":
22
+ from .jsonio import load_deck
23
+
24
+ deck = load_deck(path)
25
+ if any(d.rule == "bad-json" for d in deck.diagnostics):
26
+ return deck
27
+ return build_deck(deck, out, base_dir)
28
+ text = path.read_text(encoding="utf-8")
29
+ else:
30
+ text = str(source)
31
+ return build_deck(parse(text), out, base_dir)
32
+
33
+
34
+ def build_deck(deck: Deck, out: str | Path, base_dir: str | Path | None = None) -> Deck:
35
+ """Layout + lint + render a parsed Deck. Lint findings already reported by layout are deduped."""
36
+ deck.attrs.setdefault("base_dir", str(base_dir or Path.cwd()))
37
+ theme, diags = deck_theme(deck, deck.attrs["base_dir"])
38
+ deck.diagnostics.extend(diags)
39
+ if size := template_size(theme):
40
+ deck.size = size # the template's slide size wins
41
+ try:
42
+ placed = [layout_slide(slide, deck, theme, i) for i, slide in enumerate(deck.slides)]
43
+ finally:
44
+ if any(s.html is not None for s in deck.slides):
45
+ from .layout.htmlslide import close_shared
46
+
47
+ close_shared() # one Playwright at a time: the renderer opens its own for pictures
48
+ seen = {(d.rule, d.slide) for d in deck.diagnostics}
49
+ deck.diagnostics.extend(d for d in lint_deck(deck, placed, theme) if (d.rule, d.slide) not in seen)
50
+ try: # the per-slide fit map of `slidemark build` (fit.py): read off the layout result, never fatal
51
+ from .fit import fit_report
52
+
53
+ deck.attrs["fit_map"], sparse = fit_report(deck, placed, theme)
54
+ deck.diagnostics.extend(sparse) # info `sparse`: a slide that stays empty after growth
55
+ except Exception:
56
+ deck.attrs.pop("fit_map", None)
57
+ from .render import render # python-pptx loads only when a file is written
58
+
59
+ render(deck, placed, theme, out)
60
+ return deck