mirror of
https://github.com/HananoshikaYomaru/openfreebooks.git
synced 2026-11-13 21:15:54 +00:00
Update build scripts and README: Enhance build command to include static HTML checks and curriculum validation, streamline development process with new dev script, and clarify local development instructions. Update curriculum wiring in catalog to support dynamic subject loading and improve Mermaid map integration.
This commit is contained in:
parent
3f3ea4a36c
commit
562c225884
7 changed files with 340 additions and 71 deletions
|
|
@ -2,7 +2,7 @@
|
|||
name: ofb
|
||||
description: >-
|
||||
Develop Open Free Books (OFB): Zola static site, catalog/curriculum JSON,
|
||||
HTML chapters, Solid.js, JSON Canvas maps, Sass. Use when editing openfreebooks,
|
||||
HTML chapters, Solid.js, Mermaid catalog maps, Sass. Use when editing openfreebooks,
|
||||
adding subjects/chapters/curriculum, catalog, math content, or deploying to
|
||||
Cloudflare.
|
||||
---
|
||||
|
|
@ -20,8 +20,8 @@ data/catalog.json → subject list + global curriculum filter chips
|
|||
data/{subject}-curriculum.json → strands, chapters, curriculums[], graph.edges
|
||||
content/{subject}/… → Zola sections (chapter pages at /{subject}/{slug}/)
|
||||
themes/…/partials/{subject}/ → chapter HTML bodies (not Markdown today)
|
||||
frontend/ → catalog-app, canvas viewer, site chrome
|
||||
/catalog/ → browse UI (list + JSON Canvas map)
|
||||
frontend/ → catalog-app, Mermaid map view, site chrome
|
||||
/catalog/ → browse UI (list + Mermaid map)
|
||||
```
|
||||
|
||||
**Catalog is the subject index.** `/math/` redirects to `/catalog/?subject=math`. Do not revive a separate book index unless asked.
|
||||
|
|
@ -47,7 +47,7 @@ bun run build # production: JS + Zola + pagefind → public/
|
|||
| Theme static | **Only** commit `themes/openfreebooks/static/js/bundle.js` (+ fonts if any). **Never** commit `public/` or stale HTML under theme `static/` |
|
||||
| Tera | Never name a loaded JSON variable `math` (reserved). Use `math_catalog`, etc. |
|
||||
| Chapter URLs | `/{subjectId}/{chapter-slug}/` (e.g. `/math/quadratic-equations/`) |
|
||||
| Canvas | [JSON Canvas 1.0](https://jsoncanvas.org/spec/1.0/); viewer: `json-canvas-viewer` (full build, lazy-loaded on catalog) |
|
||||
| Map | Mermaid DAG view (`?view=tree`) driven by `graph.edges` |
|
||||
| Graph | `graph.edges` must be **acyclic**; builder throws on cycles |
|
||||
|
||||
## Common tasks → where to edit
|
||||
|
|
@ -55,7 +55,7 @@ bun run build # production: JS + Zola + pagefind → public/
|
|||
| Task | Files |
|
||||
|------|--------|
|
||||
| New global curriculum chip (e.g. GCSE) | `data/catalog.json` → `curriculums[]`; `_catalog.scss` badge; `frontend/src/lib/catalog-badge.ts`; rebuild |
|
||||
| New subject (sidebar) | `data/catalog.json` → `subjects[]`; `data/{id}-curriculum.json`; **wire catalog template** (today: manual `if subject.id` in `catalog.html` — prefer fixing per [CONTRIBUTING.md](../../../CONTRIBUTING.md)) |
|
||||
| New subject (sidebar) | `data/catalog.json` → `subjects[]`; `data/{id}-curriculum.json` (catalog template auto-loads by `id`) |
|
||||
| New chapter (planned) | `{subject}-curriculum.json` strand entry; optional `graph.edges` |
|
||||
| New chapter (live) | Above + `content/{subject}/{slug}/_index.md` + HTML partial + `chapter.html` wiring + `main.tsx` widget mount if interactive |
|
||||
| Homepage subject card | `themes/.../templates/index.html` (not yet data-driven) |
|
||||
|
|
@ -78,16 +78,16 @@ bun run build # production: JS + Zola + pagefind → public/
|
|||
|
||||
Detailed checklists: [curriculum-data.md](curriculum-data.md). Human-facing guide: [CONTRIBUTING.md](../../../CONTRIBUTING.md).
|
||||
|
||||
## Catalog / canvas
|
||||
## Catalog / map
|
||||
|
||||
| Piece | Path |
|
||||
|-------|------|
|
||||
| Shell UI (subject, filters, list/map toggle) | `frontend/src/components/catalog-app.tsx` |
|
||||
| Shared chapter card (list + map markup) | `frontend/src/components/catalog-chapter-card.tsx` |
|
||||
| Map viewer (json-canvas-viewer) | `frontend/src/components/catalog-canvas-view.tsx` (lazy chunk) |
|
||||
| Canvas layout (strands as columns, DAG levels, node positions) | `frontend/src/lib/catalog-to-canvas.ts` |
|
||||
| Card height measure + post-render fit | `frontend/src/lib/catalog-chapter-card-layout.ts` |
|
||||
| Viewer theme (light/dark hex colors) | `frontend/src/lib/catalog-canvas-theme.ts` |
|
||||
| Map viewer (Mermaid) | `frontend/src/components/catalog-mermaid-view.tsx` (lazy chunk) |
|
||||
| Mermaid source builder | `frontend/src/lib/catalog-to-mermaid.ts` |
|
||||
| Mermaid theme (light/dark hex colors) | `frontend/src/lib/catalog-mermaid-theme.ts` |
|
||||
| Theme-mode helpers used by map | `frontend/src/lib/catalog-canvas-theme.ts` |
|
||||
| Curriculum badge CSS class map | `frontend/src/lib/catalog-badge.ts` |
|
||||
| Types | `data/catalog.types.ts` |
|
||||
| Styles | `themes/openfreebooks/sass/_catalog.scss` |
|
||||
|
|
@ -97,11 +97,11 @@ Detailed checklists: [curriculum-data.md](curriculum-data.md). Human-facing guid
|
|||
|
||||
**List view:** full-card link for live chapters; number + title row on wide screens.
|
||||
|
||||
**Map view:** custom `nodeComponents.text` renders the same card DOM as list (`catalog-chapter-card--map`). Only the **title** is a link (with `→` and animated underline on hover/focus). Planned chapters are non-clickable. Do not make the whole card an `<a>`.
|
||||
**Map view:** `CatalogMermaidView` renders a Mermaid DAG from `graph.edges`. Only live chapter titles become links; planned chapters are non-clickable.
|
||||
|
||||
**Map layout:** one column per strand; Y from DAG level + per-level max card height. Node width `300px` (`CHAPTER_NODE_WIDTH`). Heights: off-screen `scrollHeight` per card, then after viewer paints, `measureRenderedMapChapterCards()` + `relayoutCanvasChapterHeights()` once if any node was too short. Waits for `document.fonts.ready` before first layout.
|
||||
**Map layout:** generated in `catalog-to-mermaid.ts` with strand subgraphs + edges from curriculum DAG data.
|
||||
|
||||
**Canvas viewer quirks:** use `container.get(internal.InteractionHandler).onClick` (not `viewer.onClick`); edge colors must be 8-digit hex (no `rgba` on node/edge color fields); wheel on map uses capture-phase `stopPropagation` unless Ctrl/Cmd so the page can scroll.
|
||||
**Mermaid quirks:** use `theme: "base"` + hex `themeVariables`; Mermaid applies inline fills, so cluster fills are controlled in Mermaid config, not plain Sass overrides.
|
||||
|
||||
Prerequisites: **only** `graph.edges` (required, global DAG, cross-strand OK). Longest-path levels. No implicit strand-list chains. List order ≠ map order.
|
||||
|
||||
|
|
@ -136,10 +136,10 @@ bun run build
|
|||
|
||||
## Planned / not implemented (do not assume)
|
||||
|
||||
- Defuddle “copy as Markdown” on chapters
|
||||
- Markdown-based chapters (spec says HTML; README may be outdated)
|
||||
- Defuddle “copy as Markdown” on non-chapter pages
|
||||
- Data-driven homepage cards
|
||||
- Single-file subject registration (catalog template still special-cases `math`)
|
||||
- Single source for subject metadata (`catalog.json` + `*-curriculum.json`)
|
||||
- Subject scaffold command (`scaffold:subject`)
|
||||
|
||||
See README **Contributor experience** task list for tracked fixes.
|
||||
|
||||
|
|
|
|||
|
|
@ -89,16 +89,16 @@ Example: `data/math-curriculum.json`.
|
|||
|
||||
### Wiring into catalog
|
||||
|
||||
`themes/openfreebooks/templates/catalog.html` must expose strands + graph in `#catalog-data`. **Today only `math` is wired** — adding a subject requires a Tera block like:
|
||||
`themes/openfreebooks/templates/catalog.html` exposes strands + graph in `#catalog-data` by loading `data/{subject.id}-curriculum.json` for each catalog subject.
|
||||
|
||||
```tera
|
||||
{% set subject_catalog = load_data(path="data/science-curriculum.json", format="json") %}
|
||||
{% for subject in catalog.subjects %}
|
||||
{% set subject_curriculum = load_data(path="data/" ~ subject.id ~ "-curriculum.json", format="json") %}
|
||||
...
|
||||
"strands": {% if subject.id == "science" %}{{ subject_catalog.strands | json_encode() | safe }}{% else %}[]{% endif %}
|
||||
"strands": {{ subject_curriculum.strands | default(value=[]) | json_encode() | safe }}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
**Goal (tracked in README):** auto-load `data/{id}-curriculum.json` by subject id.
|
||||
|
||||
## Status: planned vs live
|
||||
|
||||
| status | Catalog list | Map node | Content required |
|
||||
|
|
@ -106,7 +106,7 @@ Example: `data/math-curriculum.json`.
|
|||
| `planned` | Shown, “Coming soon” badge | Card shown; title not linked | Only JSON entry |
|
||||
| `live` | Full card links to chapter | Title links to chapter (`→` + underline); rest of card not clickable | `content/` + HTML partial + template wiring |
|
||||
|
||||
Map nodes are `type: "text"` in JSON Canvas; the viewer renders custom HTML via `catalog-chapter-card.tsx` (`renderCatalogChapterCardElement`), not markdown.
|
||||
Map view is Mermaid-based (`CatalogMermaidView` + `catalog-to-mermaid.ts`) and uses `graph.edges` as the source-of-truth DAG.
|
||||
|
||||
## Adding a curriculum label
|
||||
|
||||
|
|
@ -117,18 +117,15 @@ Map nodes are `type: "text"` in JSON Canvas; the viewer renders custom HTML via
|
|||
|
||||
## Map card heights (agents)
|
||||
|
||||
Do not use fixed node heights or font-metrics libraries for layout. The pipeline is:
|
||||
Do not hand-place map node positions. The pipeline is:
|
||||
|
||||
1. `measureAllMapChapterCardHeights()` — render each card off-screen; read `scrollHeight`.
|
||||
2. `subjectToCanvas()` — assign node `height` and column Y from DAG levels.
|
||||
3. After `json-canvas-viewer` paints, `measureRenderedMapChapterCards()` + `relayoutCanvasChapterHeights()` — bump any node still too short and reflow Y / strand groups.
|
||||
1. `subjectToMermaid()` builds Mermaid source from strands + `graph.edges`.
|
||||
2. `CatalogMermaidView` renders with Mermaid (`theme: "base"` + hex theme variables).
|
||||
3. `enhanceStrandClusterHeaders()` post-processes strand header chrome in SVG.
|
||||
|
||||
Card markup must stay in sync between `catalog-chapter-card.tsx` (Solid + `renderCatalogChapterCardElement`) and `_catalog.scss` (especially `.catalog-chapter-card--map`).
|
||||
|
||||
## Validation (manual until scripted)
|
||||
## Validation
|
||||
|
||||
- JSON parses (`jq . data/math-curriculum.json`).
|
||||
- Every `live` slug has `content/{subject}/{slug}/_index.md`.
|
||||
- Every `curriculums[]` value is listed in `catalog.json`.
|
||||
- Graph edges reference existing slugs; no cycles (open catalog map view).
|
||||
- `bun run validate:curriculum` (scripted checks for slugs, curricula labels, live content paths, and DAG acyclicity).
|
||||
- `bun run build` succeeds.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue