Maintenance scripts
Python utilities that bulk-edit or generate content across the textbook. They are developer tools, not part of the Jekyll build — nothing here runs during jekyll build or the GitHub Actions deploy.
[!IMPORTANT] Keep this README in sync. Whenever you add, remove, rename, or meaningfully change a script in this folder, update the table and the relevant section below in the same commit.
Conventions
- Dry run by default. Every script previews its changes and writes nothing until you pass its apply flag (
--runor--apply). Always dry-run first, apply, then inspectgit diffbefore committing. - Run from the repo root (where the
Gemfilelives), e.g.python scripts/fix_embedded_media.py. - Scripts target the Markdown lesson pages (and their
assets/) in place.
Scripts at a glance
| Script | Purpose | Apply flag |
|---|---|---|
generate_og_posters.py | Generate static OG/social-card poster images from a page’s hero <video> (MP4) via ffmpeg, and set image: front matter. | --run |
fix_embedded_media.py | Normalize <video> inline styles and wrap bare YouTube iframes responsively. | --run |
update_lesson_nav.py | Migrate old .btn lesson nav to card-style <nav class="lesson-nav"> (rewrites .md→.html). | --run |
fix_arduino_urls.py | Migrate old arduino.cc URLs to docs.arduino.cc. Untested/brittle — use with care. | --apply |
Details
generate_og_posters.py
For pages whose first/hero media is an MP4 <video>, extracts a representative still (ffmpeg’s thumbnail filter — more robust than the literal first frame) into <module>/assets/og/<lesson>.jpg and sets/replaces the page’s image: front matter. Posters are committed assets; the build just copies them, so build time is unaffected. Re-runs skip posters already newer than their source video.
Requires ffmpeg on PATH (tested with ffmpeg 6.0). See the “SEO and social cards” section of website-dev.md for the overall convention.
python scripts/generate_og_posters.py # dry run, whole site
python scripts/generate_og_posters.py --run # apply, whole site
python scripts/generate_og_posters.py --run --force # re-encode even fresh posters
python scripts/generate_og_posters.py --run arduino/serial-print.md # limit to files
fix_embedded_media.py
Scans all .md files for two issues: (1) strips redundant style="margin:0px" from <video> elements (handled by CSS in custom.css Section 8), and (2) wraps unwrapped YouTube <iframe>s in <div class="iframe-container"> and removes hardcoded width/height so they scale responsively. Non-YouTube iframes (e.g. p5.js embeds) are left untouched.
python scripts/fix_embedded_media.py # dry run
python scripts/fix_embedded_media.py --run # apply
update_lesson_nav.py
Migrates the old <span class="fs-6">…{: .btn .btn-outline }…</span> lesson nav to the card-style <nav class="lesson-nav">, converting link extensions from .md to .html. Handles prev+next, next-only, and prev-only.
Known gaps: does not match the single “Back to” button form, and its summary print can crash on Windows cp1252 consoles. Some pages may need hand-migration.
python scripts/update_lesson_nav.py # dry run
python scripts/update_lesson_nav.py --run # apply
fix_arduino_urls.py
Sweeps .md files for old arduino.cc URLs and migrates them to docs.arduino.cc (reference URLs with camelCase slug fixes, plus wiki-style URLs).
Untested and brittle per its own header — it does not fully parse Markdown links. Review diffs carefully; prefer
--verifyto HTTP-check the new URLs.
python scripts/fix_arduino_urls.py # dry run
python scripts/fix_arduino_urls.py --apply # apply
python scripts/fix_arduino_urls.py --verify # dry run + HTTP-check new URLs
python scripts/fix_arduino_urls.py --apply --verify