- Python 100%
|
|
||
|---|---|---|
| data | ||
| docs | ||
| includes | ||
| .gitignore | ||
| .python-version | ||
| CLAUDE.md | ||
| fit_to_md.py | ||
| LICENSE | ||
| MERMAID_RENDERING.md | ||
| prefecture_map.py | ||
| pyproject.toml | ||
| README.md | ||
| retro_build.py | ||
| RETRO_BUILD_SETUP.md | ||
| RETRO_README.md | ||
| roadtrip_to_md.py | ||
| zensical.toml | ||
benoit.jp.net
Personal website at benoit.jp.net, built with Zensical (by the Material for MkDocs creators). Documents self-hosted services, technical how-to guides, hiking logs, road trip GPS logs, and personal content.
Development
# Build the site
uv run zensical build
# Serve locally with live reload (http://localhost:8000)
uv run zensical serve
# Serve and open browser automatically
uv run zensical serve --open
fit_to_md.py
100% vibe coded by Claude Code. 0% human.
Converts a Garmin .fit hiking activity file into a Markdown page for the
Hiking section of the site.
uv run python fit_to_md.py <activity.fit> [--notes "..."] [--peaks "..."] [--tz OFFSET]
Arguments
| Argument | Default | Description |
|---|---|---|
fit_file |
— | Path to the Garmin .fit file |
--notes |
(empty) | Free-text notes about the hike |
--peaks |
(auto) | Comma-separated peak names, bypasses Overpass API lookup |
--tz |
+09:00 |
Timezone offset for display (JST by default) |
Output
| File | Description |
|---|---|
docs/Hiking/YYYY-MM-DD.md |
Markdown page with stats table |
docs/Hiking/YYYY-MM-DD/map.png |
GPS trace rendered on OpenStreetMap tiles |
docs/Hiking/YYYY-MM-DD/charts.png |
Elevation (colored by HR), heart rate, speed, cadence charts |
docs/Hiking/index.md |
Auto-updated index listing all hikes |
docs/Hiking/prefectures.png |
Prefecture coverage map, regenerated on every run |
If two activities share the same date, the existing page is renamed to
YYYY-MM-DD-HHMM.md and the new one is written as YYYY-MM-DD-HHMM.md
(where HHMM is the local start time), preserving both.
After running, add the new page to the nav array in zensical.toml and
fill in the prefectures frontmatter field with the prefectures hiked:
{"🥾 Peak Name, YYYY-MM-DD" = "Hiking/YYYY-MM-DD.md"}
prefectures: [Tokyo, Kanagawa]
Dependencies
Managed via uv, declared in pyproject.toml:
fitparse— Garmin .fit file parsermatplotlib— Charts (elevation, heart rate, speed, cadence)staticmap— Static map render using OSM tilespyyaml— YAML frontmatter parsing for index generationrequests— Overpass API queries for peak name lookup
prefecture_map.py
100% vibe coded by Claude Code. 0% human.
Shared helper used by both fit_to_md.py and roadtrip_to_md.py to generate
a colored PNG map of Japan's 47 prefectures, highlighting the ones visited.
Not intended to be called directly.
Prefecture names are written in plain English in each page's prefectures:
frontmatter list (e.g. [Tokyo, Osaka, Hokkaido]). The full mapping from
clean names to GeoJSON identifiers is defined in PREFECTURE_NAMES inside the
module. The boundary data lives in data/japan_prefectures.geojson (from the
dataofjapan/land project, MIT licensed).
roadtrip_to_md.py
100% vibe coded by Claude Code. 0% human.
Converts multi-day GPX road trip files into a Markdown page for the Road Trips section of the site.
uv run python roadtrip_to_md.py --name "Tohoku 2024" day1.gpx [day2.gpx ...]
Arguments
| Argument | Default | Description |
|---|---|---|
gpx_files |
— | GPX files, one per day, in chronological order |
--name |
(required) | Trip name, e.g. Tohoku 2024 |
--tz |
+09:00 |
Timezone offset for display (JST by default) |
--notes |
(empty) | Free-text notes to append to the page |
--md-only |
off | Skip map/chart regeneration, update Markdown only |
Output
| File | Description |
|---|---|
docs/Road-Trips/YYYY-MM-DD.md |
Markdown page with stats table and Day by Day breakdown |
docs/Road-Trips/YYYY-MM-DD/map.png |
Multi-day GPS trace on ESRI World Street Map tiles |
docs/Road-Trips/YYYY-MM-DD/charts.png |
Elevation and speed charts per day |
docs/Road-Trips/index.md |
Auto-updated index listing all trips with summaries |
docs/Road-Trips/prefectures.png |
Prefecture coverage map, regenerated on every run |
After running, add the new page to the nav array in zensical.toml, then
manually fill in the prefectures, trip_summary, and Route fields:
{"🚗 Trip Name, YYYY-MM-DD" = "Road-Trips/YYYY-MM-DD.md"}
prefectures: [Shiga, Fukui, Ishikawa, Toyama]
trip_summary: "One-sentence description of the overall circuit."
Dependencies
Managed via uv, declared in pyproject.toml:
matplotlib— Charts (elevation, speed)staticmap— Static map render using ESRI tilespyyaml— YAML frontmatter parsing for index generationnumpy— Speed smoothing and percentile calculations