parody 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.
- parody-0.1.0/.claude-worktrees/fleet-ember/.devcontainer/devcontainer.json +11 -0
- parody-0.1.0/.claude-worktrees/fleet-ember/.github/workflows/ci.yml +20 -0
- parody-0.1.0/.claude-worktrees/fleet-ember/.gitignore +22 -0
- parody-0.1.0/.claude-worktrees/fleet-ember/CLAUDE.local.md +12 -0
- parody-0.1.0/.claude-worktrees/fleet-ember/Dockerfile +18 -0
- parody-0.1.0/.claude-worktrees/fleet-ember/NEW_PROJECT_SEED_PLAN.md +140 -0
- parody-0.1.0/.claude-worktrees/fleet-ember/README.md +33 -0
- parody-0.1.0/.claude-worktrees/fleet-ember/media/notebooks/unknown/tiny_code_files/autofig-4-1.svg +432 -0
- parody-0.1.0/.claude-worktrees/fleet-ember/media/notebooks/unknown/tiny_code_files/autofig-4-1.svg.backup +432 -0
- parody-0.1.0/.claude-worktrees/fleet-ember/parody/__init__.py +8 -0
- parody-0.1.0/.claude-worktrees/fleet-ember/parody/cli.py +83 -0
- parody-0.1.0/.claude-worktrees/fleet-ember/parody/filters/filter.lua +982 -0
- parody-0.1.0/.claude-worktrees/fleet-ember/parody/readers/__init__.py +0 -0
- parody-0.1.0/.claude-worktrees/fleet-ember/parody/readers/figure_mover.py +345 -0
- parody-0.1.0/.claude-worktrees/fleet-ember/parody/readers/jupytext_converter_api.py +1035 -0
- parody-0.1.0/.claude-worktrees/fleet-ember/parody/readers/jupytext_converter_with_execution.py +472 -0
- parody-0.1.0/.claude-worktrees/fleet-ember/parody/schemas/artifact-v1.json +80 -0
- parody-0.1.0/.claude-worktrees/fleet-ember/parody/toolchain.py +36 -0
- parody-0.1.0/.claude-worktrees/fleet-ember/parody/utils/__init__.py +0 -0
- parody-0.1.0/.claude-worktrees/fleet-ember/parody/utils/notebook_helpers.py +219 -0
- parody-0.1.0/.claude-worktrees/fleet-ember/parody/utils/notebook_utils.py +279 -0
- parody-0.1.0/.claude-worktrees/fleet-ember/parody/writers/__init__.py +0 -0
- parody-0.1.0/.claude-worktrees/fleet-ember/parody/writers/artifact.py +649 -0
- parody-0.1.0/.claude-worktrees/fleet-ember/pyproject.toml +62 -0
- parody-0.1.0/.claude-worktrees/fleet-ember/tests/conftest.py +20 -0
- parody-0.1.0/.claude-worktrees/fleet-ember/tests/golden/engineering-artificial-intelligence.json +6697 -0
- parody-0.1.0/.claude-worktrees/fleet-ember/tests/golden/general-topics.json +104 -0
- parody-0.1.0/.claude-worktrees/fleet-ember/tests/golden/heat-transfer-lab-manual.json +306 -0
- parody-0.1.0/.claude-worktrees/fleet-ember/tests/golden/mechatronics-lab-manual.json +481 -0
- parody-0.1.0/.claude-worktrees/fleet-ember/tests/golden/sample-notebook.json +58 -0
- parody-0.1.0/.claude-worktrees/fleet-ember/tests/test_cli.py +27 -0
- parody-0.1.0/.claude-worktrees/fleet-ember/tests/test_execution.py +77 -0
- parody-0.1.0/.claude-worktrees/fleet-ember/tests/test_golden_artifacts.py +95 -0
- parody-0.1.0/.claude-worktrees/fleet-ember/uv.lock +1696 -0
- parody-0.1.0/.claude-worktrees/olive-cedar/CLAUDE.local.md +12 -0
- parody-0.1.0/.claude-worktrees/olive-cedar/README.md +1 -0
- parody-0.1.0/.devcontainer/devcontainer.json +11 -0
- parody-0.1.0/.github/workflows/ci.yml +20 -0
- parody-0.1.0/.gitignore +22 -0
- parody-0.1.0/Dockerfile +18 -0
- parody-0.1.0/NEW_PROJECT_SEED_PLAN.md +140 -0
- parody-0.1.0/PKG-INFO +53 -0
- parody-0.1.0/README.md +33 -0
- parody-0.1.0/parody/__init__.py +8 -0
- parody-0.1.0/parody/cli.py +83 -0
- parody-0.1.0/parody/filters/filter.lua +982 -0
- parody-0.1.0/parody/readers/__init__.py +0 -0
- parody-0.1.0/parody/readers/figure_mover.py +345 -0
- parody-0.1.0/parody/readers/jupytext_converter_api.py +1035 -0
- parody-0.1.0/parody/readers/jupytext_converter_with_execution.py +472 -0
- parody-0.1.0/parody/schemas/artifact-v1.json +80 -0
- parody-0.1.0/parody/toolchain.py +36 -0
- parody-0.1.0/parody/utils/__init__.py +0 -0
- parody-0.1.0/parody/utils/notebook_helpers.py +219 -0
- parody-0.1.0/parody/utils/notebook_utils.py +279 -0
- parody-0.1.0/parody/writers/__init__.py +0 -0
- parody-0.1.0/parody/writers/artifact.py +649 -0
- parody-0.1.0/pyproject.toml +62 -0
- parody-0.1.0/tests/conftest.py +20 -0
- parody-0.1.0/tests/golden/engineering-artificial-intelligence.json +6697 -0
- parody-0.1.0/tests/golden/general-topics.json +104 -0
- parody-0.1.0/tests/golden/heat-transfer-lab-manual.json +306 -0
- parody-0.1.0/tests/golden/mechatronics-lab-manual.json +481 -0
- parody-0.1.0/tests/golden/sample-notebook.json +58 -0
- parody-0.1.0/tests/test_cli.py +27 -0
- parody-0.1.0/tests/test_execution.py +77 -0
- parody-0.1.0/tests/test_golden_artifacts.py +95 -0
- parody-0.1.0/uv.lock +1696 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# CI for the parody toolchain itself. (Content repos get their own template
|
|
2
|
+
# via `parody init` in Phase 2.) Golden-parity tests need the private source
|
|
3
|
+
# corpora and auto-skip here; they run locally pre-release.
|
|
4
|
+
name: ci
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
push:
|
|
8
|
+
branches: [main]
|
|
9
|
+
pull_request:
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
test:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
- uses: astral-sh/setup-uv@v5
|
|
17
|
+
- run: uv sync
|
|
18
|
+
- run: uv run ruff check .
|
|
19
|
+
- run: uv run parody check --toolchain
|
|
20
|
+
- run: uv run pytest -q
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
dist/
|
|
6
|
+
build/
|
|
7
|
+
.venv/
|
|
8
|
+
|
|
9
|
+
# Tooling
|
|
10
|
+
.pytest_cache/
|
|
11
|
+
.ruff_cache/
|
|
12
|
+
|
|
13
|
+
# Build artifacts — never commit build outputs to content or toolchain repos
|
|
14
|
+
# (System B carries 153 MB of versioned PDFs in git; we don't repeat that)
|
|
15
|
+
*.pdf
|
|
16
|
+
.jupytext_cache.json
|
|
17
|
+
.autofig_log.jsonl
|
|
18
|
+
# figure_mover writes media/ relative to cwd (ancestor behavior; parameterize in Phase 2)
|
|
19
|
+
/media/
|
|
20
|
+
|
|
21
|
+
# OS
|
|
22
|
+
.DS_Store
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Resuming task #234
|
|
2
|
+
|
|
3
|
+
**Task:** Follow the Seed Plan
|
|
4
|
+
|
|
5
|
+
## Description
|
|
6
|
+
Follow the markdown NEW_PROJECT_SEED_PLAN.md plan developed to stand up this project and absorb the two older systems.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
_Manage your context as you work — `project_slug="parody"`, `task_id=234`:_
|
|
10
|
+
- **Briefing** — before you pause/wrap up, `write_task_briefing(…)`: a concise “where things stand / next steps” so the next session resumes cleanly.
|
|
11
|
+
- **Task** — `set_task_next_action`, `edit_task`, `set_task_block`/`clear_task_block`, `complete_task` (or the dashboard’s **Done**).
|
|
12
|
+
- **Project memory** — when you learn something durable & project-wide (a convention, decision, gotcha), `add_project_memory` / `update_project_memory` so every future session across the project inherits it.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Parody build environment — the one-command collaboration enabler.
|
|
2
|
+
# pandoc arrives via the pypandoc-binary pin (see parody/toolchain.py),
|
|
3
|
+
# so the image needs no separate pandoc install.
|
|
4
|
+
FROM python:3.12-slim
|
|
5
|
+
|
|
6
|
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
7
|
+
git ca-certificates \
|
|
8
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
9
|
+
|
|
10
|
+
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
|
|
11
|
+
|
|
12
|
+
WORKDIR /work
|
|
13
|
+
COPY pyproject.toml uv.lock* README.md ./
|
|
14
|
+
COPY parody ./parody
|
|
15
|
+
RUN uv sync --frozen --no-dev || uv sync --no-dev
|
|
16
|
+
|
|
17
|
+
ENV PATH="/work/.venv/bin:$PATH"
|
|
18
|
+
ENTRYPOINT ["parody"]
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Parody — Unified Book/Notebook Toolchain (Seed Plan)
|
|
2
|
+
|
|
3
|
+
**Status:** Approved 2026-06-10; in execution.
|
|
4
|
+
**Name:** `parody` — a play on *parity* (keeping the print and web versions in parity). Confirmed available on PyPI 2026-06-10.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 1. Mission
|
|
9
|
+
|
|
10
|
+
One authoring toolchain, distributed as an installable Python package with a CLI, that unifies two existing systems by the same author:
|
|
11
|
+
|
|
12
|
+
- **System A — homepage notebooks pipeline** (private Django monolith `homepage-django`): pandoc-markdown + executed jupytext sources → JSON → imported into Django models, served dynamically at ricopic.one with course-integrated solution gating, exam printing, and per-user annotations.
|
|
13
|
+
- **System B — meta-based book system** (rtc-book et al.): pandoc-markdown + LaTeX → print-quality PDF (MIT Press production) *and* a Jekyll website, machinery shared across books via `meta-*` git submodules synchronized by hard links.
|
|
14
|
+
|
|
15
|
+
Parody replaces System A's embedded converter scripts and System B's `meta-book`/`meta-common` (and most of `meta-site`). It does **not** replace System A's Django serving layer—that stays in homepage-django and consumes Parody's JSON artifact.
|
|
16
|
+
|
|
17
|
+
**Ancestor repos (private; reference implementations):**
|
|
18
|
+
- https://github.com/rtc-book/real-time-computing (book), https://github.com/rtc-book/common, https://github.com/rtc-book/site-source
|
|
19
|
+
- https://github.com/ricopicone/meta-book, https://github.com/ricopicone/meta-common, https://github.com/ricopicone/meta-site
|
|
20
|
+
- homepage-django (local): toolchain code listed in §6 inventory.
|
|
21
|
+
|
|
22
|
+
## 2. Principles (lessons paid for in both ancestors)
|
|
23
|
+
|
|
24
|
+
1. **Shared machinery is a versioned dependency, never synchronized files.** The meta-* hard-link scheme (`links.json`, `link-here.py`, manual `meta-*-adoption-notes.txt` merges) is the single biggest maintenance failure in System B. Parody is `pip install parody==X.Y.Z`; a book upgrades by bumping a pin.
|
|
25
|
+
2. **The artifact is the contract.** Builds emit machine-readable, schema-versioned JSON (System B already proved this: its LaTeX build emits `book-json/` that generates the website). Consumers (Django importer, static preview, future tools) depend on the schema, not on Parody internals.
|
|
26
|
+
3. **One source, many targets.** Pandoc markdown (with executed-code blocks via jupytext) is the canonical source; targets are JSON artifact, print PDF, standalone HTML preview, (later) slides.
|
|
27
|
+
4. **Content repos are plain.** One repo per book/notebook, no submodules by default. Collaborators clone one repo, run one containerized command, open a PR. Private content (solutions) lives in the private content repo, extracted into the artifact at build, access-controlled at serve time.
|
|
28
|
+
5. **CI exists.** System B has none; every contribution burdens the author's laptop. Content repos build on PR and release artifacts on tag.
|
|
29
|
+
6. **Port incrementally, gated by golden tests.** Never rewrite both pipelines at once. Parity with System A first (it has a live production consumer), System B's print machinery second.
|
|
30
|
+
|
|
31
|
+
## 3. Architecture
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
parody (this repo, pip package + CLI)
|
|
35
|
+
├── parody/readers/ markdown + YAML frontmatter; jupytext execution (cached)
|
|
36
|
+
├── parody/filters/ pandoc lua/panflute filters (ported from both ancestors)
|
|
37
|
+
├── parody/writers/
|
|
38
|
+
│ ├── artifact.py → <slug>.json (schema below; primary target)
|
|
39
|
+
│ ├── latex.py → print PDF via latexmk/lualatex profiles (Phase 3)
|
|
40
|
+
│ └── preview.py → standalone static HTML for local review (Phase 2)
|
|
41
|
+
├── parody/cli.py parody init | build | watch | preview | check
|
|
42
|
+
├── profiles/ LaTeX classes/styles (from rtc styles-tex), HTML templates
|
|
43
|
+
└── tests/golden/ golden artifacts from both ancestors
|
|
44
|
+
|
|
45
|
+
content repo (one per book/notebook, from `parody init`)
|
|
46
|
+
├── parody.yaml title, slug, authors, targets, parody version pin
|
|
47
|
+
├── chapters/<ch>/<sec>.md (+ optional <sec>.py jupytext sources)
|
|
48
|
+
├── assets/ figures etc. (manifest-listed in the artifact)
|
|
49
|
+
├── solutions visibility via the same .exercise/.exercise-solution divs as System A
|
|
50
|
+
└── .github/workflows/ build on PR; artifact + PDF on tag
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### The artifact contract (schema v1)
|
|
54
|
+
|
|
55
|
+
Superset of homepage-django's current `notebooks_data/*.json` (so the existing Django importer keeps working with minimal change):
|
|
56
|
+
|
|
57
|
+
```jsonc
|
|
58
|
+
{
|
|
59
|
+
"schema_version": 1,
|
|
60
|
+
"generator": "parody X.Y.Z",
|
|
61
|
+
"source_repo": "github.com/…", "source_commit": "…", "built_at": "…",
|
|
62
|
+
"title": "…", "slug": "…", "description": "…", "acronym": "…",
|
|
63
|
+
"author": ["Full Name", "…"],
|
|
64
|
+
"cover_image": "…", "pdf_file": "…",
|
|
65
|
+
"assets": [{"path": "assets/fig1.png", "sha256": "…"}],
|
|
66
|
+
"chapters": [{
|
|
67
|
+
"slug": "…", "title": "…",
|
|
68
|
+
"sections": [{
|
|
69
|
+
"slug": "…", "title": "…",
|
|
70
|
+
"html": "<rendered html>",
|
|
71
|
+
"anchors": [{"id": "fig:…", "type": "figure", "title": "…"}],
|
|
72
|
+
"has_solutions": true,
|
|
73
|
+
"solutions": {"exe:id": {"content": "<html>", "title": "…"}},
|
|
74
|
+
"problems": {"exe:id": "<html>"}
|
|
75
|
+
}]
|
|
76
|
+
}]
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Important quirk (verified in System A, Phase 0 of its split plan):** the `html` field is *Django-template-flavored*—System A's `filter.lua` emits `{% media 'path' %}`, `{% static 'path' %}`, and `{% cite 'key' %}` tags that homepage-django re-renders through its template engine at view time (resolving to local `/media/` or S3 URLs, and to its zotero-backed bibliography). Schema v1 keeps this verbatim for parity; Parody's standalone `preview` writer must implement its own resolution of these tags (media → relative asset paths from the manifest; cite → citeproc). Schema v2 should consider neutral asset URLs + manifest instead of embedded tags.
|
|
81
|
+
|
|
82
|
+
v2 (post-migration, not now): rtc-style stable short-hash IDs per section/anchor (System B uses 2–4-char hashes as directory names, permalinks, cross-ref keys, and print QR targets—its best idea), print page-number map (from the LaTeX build, System B's `book-0-raw.json` trick), neutral asset references replacing embedded Django tags.
|
|
83
|
+
|
|
84
|
+
## 4. Phases
|
|
85
|
+
|
|
86
|
+
### Phase 0 — Bootstrap & decisions
|
|
87
|
+
- [x] Confirm name; reserve PyPI; repo + `pyproject.toml` (Python ≥3.11), `uv`/venv, ruff, pytest. *(2026-06-10: name `parody` confirmed available; PyPI reservation pending first publish)*
|
|
88
|
+
- [x] Pin toolchain versions explicitly: pandoc (both ancestors have been bitten by pandoc API churn—System B's adoption notes literally say "might break our build system because the figure environment changed"), pandoc-crossref, jupytext, nbconvert. Provide a Dockerfile/devcontainer from day one (System B's `camerondevine/rtc_docker` proved this is the collaboration enabler). *(pandoc pinned via `pypandoc-binary==1.15` → bundled pandoc 3.6.1, the version the goldens were built with; `parody check --toolchain` verifies; pandoc-crossref deferred to Phase 3 where it first appears)*
|
|
89
|
+
- [x] Decide filter strategy (recommendation: **keep lua filters initially**—System A's `filter.lua` and System B's 2,803-line `filter.lua` are both pandoc-lua; port them as-is per environment, refactor to shared code later. A panflute rewrite is a separate, optional project; do not block migration on it). *(decided: lua kept as-is)*
|
|
90
|
+
|
|
91
|
+
### Phase 1 — Parity with System A (gates homepage migration)
|
|
92
|
+
- [x] Port verbatim from homepage-django: `convert_notebook_md_to_json.py` (614 LOC), `jupytext_converter_api.py` (1,034), `jupytext_converter_with_execution.py` (471), `filter.lua`, `notebook_helpers.py`/`notebook_utils.py`. Strip Django imports (there are none of substance—these are scripts). *(2026-06-10: only changes—package imports, `media_root` parameterized away from Django root, generator string)*
|
|
93
|
+
- [x] Golden tests: build homepage's 5 notebooks (engineering-artificial-intelligence, general-topics, heat-transfer-lab-manual, mechatronics-lab-manual, sample-notebook) and diff against their committed `notebooks_data/*.json` (normalize: key order, whitespace). Target: semantic identity. *(all 5 pass; normalization = provenance keys only—generator, built_at, source_commit, schema_version—since older goldens predate them)*
|
|
94
|
+
- [x] Add schema_version/provenance keys; `parody check` validates an artifact against the schema. *(schema at `parody/schemas/artifact-v1.json`)*
|
|
95
|
+
- [ ] Release v0.1.0 → homepage-django Phase 2 (see its `NOTEBOOKS_SPLIT_PLAN.md`) swaps its management commands to thin wrappers over this CLI.
|
|
96
|
+
|
|
97
|
+
### Phase 2 — Content-repo ergonomics
|
|
98
|
+
- [ ] `parody init` scaffold (layout above), `parody build` (JSON + preview), `parody watch` (replaces homepage's `watch_notebooks.py`/livereload), `parody preview` (static HTML so a collaborator never needs Django to see their work).
|
|
99
|
+
- [ ] CI workflow template: build on PR (the missing System B affordance), artifact + checksums on tag.
|
|
100
|
+
- [ ] Migrate homepage notebooks into content repos one at a time, smallest first (sequencing and delivery mechanics are owned by homepage's plan, not this repo).
|
|
101
|
+
|
|
102
|
+
### Phase 3 — Print target (System B's machinery, ported properly)
|
|
103
|
+
- [ ] Inventory `rtc-book/common/filter.lua` capabilities → port per-environment with golden LaTeX-snippet tests: numbered divs (`.exercise` w/ XSIM, `.example`, `.theorem`/`.lemma`/`.corollary`, `.definition`, `.infobox`, `.listing`, `.algorithm`), semantic spans (`.keyword`, `.index`, `.path`, `.keys`, `.menu`, `.plaincite`), `pandoc-crossref` integration, hashref cross-links.
|
|
104
|
+
- [ ] latexmk profiles from `meta-book` (`latexmkrc_main`, `latexmkrc_solutions`; lualatex, `-shell-escape`/minted; conditional flags `\issolution`, `\ispartial`, `\nocropmarks`); styles from `common/styles-tex` (note: MIT Press class + licensed fonts are **book-private**—they belong in the book's content repo or a private profile package, not in Parody).
|
|
105
|
+
- [ ] Bibliography: single `book.bib` per content repo; citeproc for HTML, biblatex for print (both ancestors already agree on this split).
|
|
106
|
+
- [ ] Targets: full PDF, per-section PDF (System B's `make section h=…`), solutions manual. Sample/marketing pipeline (pdftk watermark, bookmark splitting) ports only if still wanted.
|
|
107
|
+
|
|
108
|
+
### Phase 4 — Migrate a System B book
|
|
109
|
+
- [ ] Pilot with the smallest/least in-flight meta-based project; `real-time-computing` (MIT Press production constraints, hardware versioning) goes **last**.
|
|
110
|
+
- [ ] Mapping: `meta-book` → Parody latex profiles + CLI; `meta-common` → Parody filters/styles/figure templates; `common/` content → the book's content repo (versioned prose merges in; the separate `common` repo dissolves unless two books truly share prose); `meta-site` + `site-source` → **retire per book** in favor of either (a) the Parody artifact imported into homepage-django (books become first-class citizens of the notebooks UI—likely the point of this whole effort) or (b) `parody preview` static output where a standalone book site must persist (rtcbook.org).
|
|
111
|
+
- [ ] Hardware versioning (`versions.json` → inheritance flattening → conditional prose + parts lists): port **only when the migrating book needs it**, as a Parody plugin/filter, not core.
|
|
112
|
+
- [ ] Adopt short-hash stable IDs into schema v2 here, where the rtc content already carries them.
|
|
113
|
+
|
|
114
|
+
### Phase 5 — Collaboration hardening
|
|
115
|
+
- [ ] Devcontainer + one-command build documented for outside collaborators; CONTRIBUTING template in `parody init`.
|
|
116
|
+
- [ ] Private-solutions pattern documented: private content repo → artifact carries solutions → serve-time gating (homepage) or excluded preview builds (`parody build --no-solutions`) for public artifacts.
|
|
117
|
+
- [ ] Artifact signing/checksums in the release workflow (homepage's deploy verifies before import).
|
|
118
|
+
|
|
119
|
+
## 5. Decisions to make early (with recommendations)
|
|
120
|
+
|
|
121
|
+
| Decision | Recommendation |
|
|
122
|
+
|---|---|
|
|
123
|
+
| Name | **decided:** `parody` (play on parity); PyPI availability confirmed 2026-06-10 |
|
|
124
|
+
| Lua filters vs panflute rewrite | keep lua now; converge later |
|
|
125
|
+
| One Parody repo vs core+profiles split | one repo until a second book needs a private profile (MIT Press styles force a private `parody-profiles-rtc` eventually) |
|
|
126
|
+
| Where does `common`'s shared-prose idea go | dissolve into per-book repos; resurrect as a shared content repo only if two books actually share sections again |
|
|
127
|
+
| Jekyll site replacement | don't rebuild it; homepage Django serves artifacts, `parody preview` covers standalone needs |
|
|
128
|
+
| Execution backend for code cells | keep System A's cached jupytext/nbconvert approach (it works and is already API-cached) |
|
|
129
|
+
|
|
130
|
+
## 6. Inventory of source material
|
|
131
|
+
|
|
132
|
+
**From homepage-django** (`teaching/scripts/`, `teaching/utils/`, `scripts/`): converter trio + filter.lua + helpers + watchers (≈2,800 LOC Python, 1 lua filter). Golden outputs: `teaching/notebooks_data/*.json` (5 files). Source corpora to migrate: `teaching/notebooks-source/*` (54 MB, 4 real notebooks + sample).
|
|
133
|
+
|
|
134
|
+
**From rtc-book/meta**: `common/filter.lua` (2,803 lines), `common/common.mk` (pandoc invocations: `include-files.lua`, `include-code-files.lua`, `section-divs.lua`, `pandoc-crossref`, citeproc/biblatex split), `common/styles-tex/` (`NewMath_MIT.cls`, `environments.sty`—note `environments.sty` also emits the build JSON), `meta-book` (Makefile, latexmkrc profiles, `scripts/`: `build-alone.py`, `split_pdf_at_bookmarks.sh`, hash tooling `new-version*-text.py`, `find_duplicate_hashes.py`), `meta-site` (generate-pages/faux-sources/menus scripts—reference only), `common/versions.json` + `versions-inheriter.py`/`versions-lister.py` (Phase 4, plugin), Docker image recipe.
|
|
135
|
+
|
|
136
|
+
**Known gotchas inherited:** pandoc version sensitivity; LaTeX-emitted JSON is malformed by construction (System B's `json-clean.py`)—Parody's artifact must come from the pandoc/Python side, never from LaTeX, with the LaTeX build contributing only optional enrichment (page numbers) post-cleaned; duplicate-hash detection must be a build **error**, not a warning; don't commit build artifacts to content repos (System B carries 153 MB of versioned PDFs in git)—releases/object storage instead.
|
|
137
|
+
|
|
138
|
+
## 7. Definition of done
|
|
139
|
+
|
|
140
|
+
Parody v1.0 = homepage-django builds nothing locally (all notebook content arrives as pinned artifacts from content repos), at least one former meta-based book builds print PDF + artifact from a plain content repo with CI, and `meta-book`/`meta-common` are archived.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# parody
|
|
2
|
+
|
|
3
|
+
*A play on **parity**: keeping the print and web versions of a work in parity.*
|
|
4
|
+
|
|
5
|
+
One authoring toolchain for books and course notebooks: pandoc markdown
|
|
6
|
+
(with executed jupytext code cells) in, multiple targets out —
|
|
7
|
+
|
|
8
|
+
- **JSON artifact** (schema-versioned; the contract consumed by
|
|
9
|
+
[ricopic.one](https://ricopic.one)'s Django importer and other tools)
|
|
10
|
+
- **standalone HTML preview** (planned, Phase 2)
|
|
11
|
+
- **print-quality PDF** via LaTeX profiles (planned, Phase 3)
|
|
12
|
+
|
|
13
|
+
Parody unifies and replaces the toolchains of two ancestor systems: the
|
|
14
|
+
homepage-django notebooks pipeline and the rtc-book `meta-*` book machinery.
|
|
15
|
+
See [NEW_PROJECT_SEED_PLAN.md](NEW_PROJECT_SEED_PLAN.md) for the full plan.
|
|
16
|
+
|
|
17
|
+
## Install / develop
|
|
18
|
+
|
|
19
|
+
Requires Python ≥ 3.11 and [pandoc](https://pandoc.org) (pinned version in
|
|
20
|
+
`parody/toolchain.py`), or use the Dockerfile/devcontainer.
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
uv sync # create venv + install
|
|
24
|
+
uv run parody --help
|
|
25
|
+
uv run pytest # golden tests need the ancestor corpora; see tests/golden/
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## CLI
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
parody build <notebook_dir> <output.json> # build the JSON artifact
|
|
32
|
+
parody check <artifact.json> # validate artifact against schema
|
|
33
|
+
```
|