diff --git a/CLAUDE.md b/CLAUDE.md index a5b3d42..addd311 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,9 +4,9 @@ This project builds presentation decks for Marp, supporting multiple courses. ## Courses -- **223015b** - Dateiformate, Schnittstellen, Speichermedien (HdM, 6 Kapitel) -- **223015c** - Internettechnologien (HdM, 3 Kapitel) -- **dhbw** - Technik I – Grundlagen IT (DHBW, 4 Kapitel) +- **223015b** - Dateiformate, Schnittstellen, Speichermedien (HdM, 6 Kapitel + Klausur) +- **223015c** - Internettechnologien (HdM, 3 Kapitel + Klausur) +- **dhbw** - Technik I – Grundlagen IT (DHBW, 8 Kapitel) ## Agent Restrictions @@ -36,21 +36,31 @@ build/ # Generated output (gitignored) ## Build Commands +Unified per-course pattern: `make -`. Group targets without +suffix run for all courses. + ```bash -make hdm-dev # HdM live server all (port 1312) -make hdm-dev-b # HdM 223015b only (port 1313) -make hdm-dev-c # HdM 223015c only (port 1314) -make dhbw-dev # DHBW live server (port 1315) -make hdm-build # Build all HdM courses -make dhbw-build # Build DHBW course -make hdm-html # HTML only (HdM) -make hdm-pdf # PDF only (HdM) -make hdm-klausur # Extract klausur slides → slides/*/klausurfolien.md -make hdm-deploy # Deploy HdM (ASK FIRST!) -make dhbw-deploy # Deploy DHBW (ASK FIRST!) -make deploy # Deploy all (ASK FIRST!) +# Per-course (replace with course id: 223015b, 223015c, dhbw) +make dev- # Live server (HMR) on per-course port +make build- # Build HTML + PDF +make html- # HTML only +make pdf- # PDF only +make klausur- # Extract klausur slides (HdM only) +make deploy- # Build + deploy single course (ASK FIRST!) + +# All courses +make dev # Combined dev server (port 1312, all courses) +make build # Build everything +make html / pdf # HTML / PDF only +make klausur # Extract klausur (HdM courses only) +make deploy # Deploy everything (ASK FIRST!) ``` +Per-course ports: `223015b` → 1313, `223015c` → 1314, `dhbw` → 1315. + +**Adding a new course:** add id to `COURSES` in Makefile + define `_NAME`, +`_KAPITEL`, `_DEPLOY`, `_PORT`, `_KLAUSUR`. No new targets needed. + ## Nix Flake Commands ```bash diff --git a/Makefile b/Makefile index 175cd44..ef23cfc 100644 --- a/Makefile +++ b/Makefile @@ -1,212 +1,163 @@ -# Uni Slides - Unified Makefile -# DHBW + HdM courses +# Uni Slides – Unified Makefile +# Multi-course Marp build system (HdM + DHBW) -.PHONY: help dev hdm-dev hdm-dev-b hdm-dev-c dhbw-dev \ - build hdm-build hdm-build-b hdm-build-c dhbw-build \ - html hdm-html hdm-html-b hdm-html-c \ - pdf hdm-pdf hdm-pdf-b hdm-pdf-c \ - klausur hdm-klausur hdm-klausur-b hdm-klausur-c \ - qr qr-slides optimize-images clean install deploy deploy-index +.PHONY: help dev build html pdf klausur deploy deploy-index build-index \ + clean install qr qr-slides optimize-images -# Course configuration -COURSE_HDM = 223015b 223015c -COURSE_DHBW = dhbw +# ----------------------------------------------------------------------------- +# Course registry +# ----------------------------------------------------------------------------- +COURSES = 223015b 223015c dhbw SLIDES_DIR = slides - -# HdM course settings -223015b_NAME = Dateiformate, Schnittstellen, Speichermedien -223015b_KAPITEL = 00-intro 01-grundlagen-text-audio 02-bild-audio-video 03-speichermedien-schnittstellen 04-distribution-apis-zukunft 05-vertiefung-offene-fragen klausurfolien klausurfragen - -223015c_NAME = Internettechnologien -223015c_KAPITEL = 01-geschichte-grundlagen-html 02-netzwerke-protokolle-css 03-interaktivitaet-javascript klausurfolien klausurfragen - -# DHBW course settings -dhbw_NAME = Technik I – Grundlagen IT -dhbw_KAPITEL = 01_web_eng 02_css_extended 03_nodejs_basics 04_nodejs_advanced 05_testing 06_typescript 07_docker 08_best_practices - -# Deploy paths -HDM_DEPLOY_PATH = /home/tengo/html/hdm -DHBW_DEPLOY_PATH = /home/tengo/html - DEPLOY_HOST = tengo@tuttle.uberspace.de -# Default target +# Per-course settings: NAME, KAPITEL, DEPLOY, PORT, KLAUSUR (1 or empty) +223015b_NAME = Dateiformate, Schnittstellen, Speichermedien +223015b_KAPITEL = 00-intro 01-grundlagen-text-audio 02-bild-audio-video 03-speichermedien-schnittstellen 04-distribution-apis-zukunft 05-vertiefung-offene-fragen klausurfolien klausurfragen +223015b_DEPLOY = /home/tengo/html/hdm/223015b +223015b_PORT = 1313 +223015b_KLAUSUR = 1 + +223015c_NAME = Internettechnologien +223015c_KAPITEL = 01-geschichte-grundlagen-html 02-netzwerke-protokolle-css 03-interaktivitaet-javascript klausurfolien klausurfragen +223015c_DEPLOY = /home/tengo/html/hdm/223015c +223015c_PORT = 1314 +223015c_KLAUSUR = 1 + +dhbw_NAME = Technik I – Grundlagen IT +dhbw_KAPITEL = 01_web_eng 02_css_extended 03_nodejs_basics 04_nodejs_advanced 05_testing 06_typescript 07_docker 08_best_practices +dhbw_DEPLOY = /home/tengo/html/dhbw +dhbw_PORT = 1315 +dhbw_KLAUSUR = + +# Courses with klausur extraction enabled +KLAUSUR_COURSES = $(foreach c,$(COURSES),$(if $($(c)_KLAUSUR),$(c),)) +ROOT_DEPLOY = /home/tengo/html/hdm + +# ----------------------------------------------------------------------------- +# Help +# ----------------------------------------------------------------------------- help: - @echo "Uni Slides - DHBW + HdM Build System" + @echo "Uni Slides – Unified Build System" @echo "" - @echo "HdM Courses:" - @echo " 223015b - Dateiformate, Schnittstellen, Speichermedien" - @echo " 223015c - Internettechnologien" + @echo "Courses:" + @for c in $(COURSES); do echo " $$c"; done @echo "" - @echo "DHBW Courses:" - @echo " dhbw - Technik I – Grundlagen IT" + @echo "Per-course (replace with course id):" + @echo " make dev- Live server (HMR)" + @echo " make build- Build HTML + PDF" + @echo " make html- Build HTML only" + @echo " make pdf- Build PDF only" + @echo " make klausur- Extract klausur slides" + @echo " make deploy- Build + deploy" @echo "" - @echo "Development:" - @echo " make hdm-dev - Live server all HdM courses (port 1312, HMR)" - @echo " make hdm-dev-b - 223015b only (port 1313, HMR)" - @echo " make hdm-dev-c - 223015c only (port 1314, HMR)" - @echo " make dhbw-dev - DHBW live server (port 1315, HMR)" - @echo "" - @echo "Build (HdM):" - @echo " make hdm-build - Build all HdM courses" - @echo " make hdm-build-b - Build 223015b only" - @echo " make hdm-build-c - Build 223015c only" - @echo " make hdm-html - HTML only all HdM" - @echo " make hdm-pdf - PDF only all HdM" - @echo "" - @echo "Build (DHBW):" - @echo " make dhbw-build - Build DHBW course" - @echo "" - @echo "Klausur (HdM):" - @echo " make hdm-klausur - Extract klausurfolien all HdM" - @echo " make hdm-klausur-b - 223015b only" - @echo " make hdm-klausur-c - 223015c only" + @echo "All courses:" + @echo " make dev Combined dev server (port 1312, all courses)" + @echo " make build Build everything" + @echo " make html / pdf HTML / PDF only" + @echo " make klausur Extract klausur (HdM courses)" + @echo " make deploy Deploy everything" @echo "" @echo "Tools:" - @echo " make qr URL=... - Generate QR code" - @echo " make qr-slides COURSE=223015b - QR for course URL" - @echo " make optimize-images COURSE=223015b - Resize images" - @echo "" - @echo "Deploy:" - @echo " make deploy - Deploy all courses" - @echo " make hdm-deploy - Deploy all HdM courses" - @echo " make dhbw-deploy - Deploy DHBW course" - @echo "" - @echo "Other:" - @echo " make clean - Remove generated files" + @echo " make qr URL=... QR code" + @echo " make qr-slides COURSE= QR for course URL" + @echo " make optimize-images COURSE= Resize images" + @echo " make clean Remove generated files" + @echo " make install npm install" -# Ensure build directories exist +# ----------------------------------------------------------------------------- +# Build infrastructure +# ----------------------------------------------------------------------------- build/.exists: - @mkdir -p build/223015b build/223015c build/dhbw + @mkdir -p $(addprefix build/,$(COURSES)) @touch $@ -# Development servers (HdM) -hdm-dev: +# ----------------------------------------------------------------------------- +# Pattern rules: dev-, build-, html-, pdf-, klausur-, deploy- +# Per-course config read via $($*_VAR) +# ----------------------------------------------------------------------------- +dev-%: + @./scripts/dev-server.sh $* $($*_PORT) + +build-%: build/.exists + @echo "Building $*..." + @mkdir -p build/$* + @cp -r $(SLIDES_DIR)/$*/assets build/$*/ 2>/dev/null || true + @cp -r $(SLIDES_DIR)/$*/materials build/$*/ 2>/dev/null || true + @for f in $($*_KAPITEL); do \ + if [ -f "$(SLIDES_DIR)/$*/$$f.md" ]; then \ + echo " $$f"; \ + npx @marp-team/marp-cli $(SLIDES_DIR)/$*/$$f.md -o build/$*/$$f.html; \ + npx @marp-team/marp-cli $(SLIDES_DIR)/$*/$$f.md --pdf --allow-local-files -o build/$*/$$f.pdf; \ + fi \ + done + @./scripts/generate-index.sh $* build/$* + +html-%: build/.exists + @echo "Building HTML for $*..." + @mkdir -p build/$* + @cp -r $(SLIDES_DIR)/$*/assets build/$*/ 2>/dev/null || true + @cp -r $(SLIDES_DIR)/$*/materials build/$*/ 2>/dev/null || true + @for f in $($*_KAPITEL); do \ + if [ -f "$(SLIDES_DIR)/$*/$$f.md" ]; then \ + echo " $$f.html"; \ + npx @marp-team/marp-cli $(SLIDES_DIR)/$*/$$f.md -o build/$*/$$f.html; \ + fi \ + done + @./scripts/generate-index.sh $* build/$* + +pdf-%: build/.exists + @echo "Building PDFs for $*..." + @mkdir -p build/$* + @for f in $($*_KAPITEL); do \ + if [ -f "$(SLIDES_DIR)/$*/$$f.md" ]; then \ + echo " $$f.pdf"; \ + npx @marp-team/marp-cli $(SLIDES_DIR)/$*/$$f.md --pdf --allow-local-files -o build/$*/$$f.pdf; \ + fi \ + done + +klausur-%: + @./scripts/extract-klausur.sh $* + +deploy-%: build-% + @echo "Deploying $*..." + scp build/$*/*.html $(DEPLOY_HOST):$($*_DEPLOY)/ + scp build/$*/*.pdf $(DEPLOY_HOST):$($*_DEPLOY)/ 2>/dev/null || true + scp build/$*/*.svg $(DEPLOY_HOST):$($*_DEPLOY)/ 2>/dev/null || true + scp -r build/$*/assets/ $(DEPLOY_HOST):$($*_DEPLOY)/ 2>/dev/null || true + scp -r build/$*/materials/ $(DEPLOY_HOST):$($*_DEPLOY)/ 2>/dev/null || true + @echo "$* deployed." + +# ----------------------------------------------------------------------------- +# Group targets (all courses) +# ----------------------------------------------------------------------------- +dev: @./scripts/dev-server.sh -hdm-dev-b: - @./scripts/dev-server.sh 223015b 1313 +build: $(addprefix build-,$(COURSES)) +html: $(addprefix html-,$(COURSES)) +pdf: $(addprefix pdf-,$(COURSES)) +klausur: $(addprefix klausur-,$(KLAUSUR_COURSES)) -hdm-dev-c: - @./scripts/dev-server.sh 223015c 1314 +build-index: build/.exists + @echo "Building root index..." + @mkdir -p build + @./scripts/generate-root-index.sh -dev-kill: - @-fuser -k 1312/tcp 2>/dev/null || true - @-fuser -k 1313/tcp 2>/dev/null || true - @-fuser -k 1314/tcp 2>/dev/null || true +deploy-index: build-index + @echo "Deploying root index..." + scp build/index.html $(DEPLOY_HOST):$(ROOT_DEPLOY)/ 2>/dev/null || true + @echo "Root index deployed." -# DHBW dev (using HdM dev-server for now) -dhbw-dev: - @./scripts/dev-server.sh dhbw 1315 +deploy: build-index $(addprefix deploy-,$(COURSES)) deploy-index + @echo "All courses deployed." -# HdM build functions -define hdm_build_course - @echo "Building $(1)..." - @mkdir -p build/$(1) - @cp -r $(SLIDES_DIR)/$(1)/assets build/$(1)/ 2>/dev/null || true - @cp -r $(SLIDES_DIR)/$(1)/materials build/$(1)/ 2>/dev/null || true - @for f in $($(1)_KAPITEL); do \ - if [ -f "$(SLIDES_DIR)/$(1)/$$f.md" ]; then \ - echo " Building $$f..."; \ - npx @marp-team/marp-cli $(SLIDES_DIR)/$(1)/$$f.md -o build/$(1)/$$f.html; \ - npx @marp-team/marp-cli $(SLIDES_DIR)/$(1)/$$f.md --pdf --allow-local-files -o build/$(1)/$$f.pdf; \ - fi \ - done - @./scripts/generate-index.sh $(1) build/$(1) -endef - -hdm-build-b: build/.exists - $(call hdm_build_course,223015b) - -hdm-build-c: build/.exists - $(call hdm_build_course,223015c) - -hdm-build: hdm-build-b hdm-build-c - @echo "All HdM courses built!" - -# DHBW build function -define dhbw_build_course - @echo "Building $(1)..." - @mkdir -p build/$(1) - @cp -r $(SLIDES_DIR)/$(1)/assets build/$(1)/ 2>/dev/null || true - @for f in $($(1)_KAPITEL); do \ - if [ -f "$(SLIDES_DIR)/$(1)/$$f.md" ]; then \ - echo " Building $$f..."; \ - npx @marp-team/marp-cli $(SLIDES_DIR)/$(1)/$$f.md -o build/$(1)/$$f.html; \ - npx @marp-team/marp-cli $(SLIDES_DIR)/$(1)/$$f.md --pdf --allow-local-files -o build/$(1)/$$f.pdf; \ - fi \ - done - @./scripts/generate-index.sh $(1) build/$(1) -endef - -dhbw-build: build/.exists - $(call dhbw_build_course,dhbw) - -# HdM HTML only -define hdm_html_course - @echo "Building HTML for $(1)..." - @mkdir -p build/$(1) - @cp -r $(SLIDES_DIR)/$(1)/assets build/$(1)/ 2>/dev/null || true - @cp -r $(SLIDES_DIR)/$(1)/materials build/$(1)/ 2>/dev/null || true - @for f in $($(1)_KAPITEL); do \ - if [ -f "$(SLIDES_DIR)/$(1)/$$f.md" ]; then \ - echo " $$f.html"; \ - npx @marp-team/marp-cli $(SLIDES_DIR)/$(1)/$$f.md -o build/$(1)/$$f.html; \ - fi \ - done - @./scripts/generate-index.sh $(1) build/$(1) -endef - -hdm-html-b: build/.exists - $(call hdm_html_course,223015b) - -hdm-html-c: build/.exists - $(call hdm_html_course,223015c) - -hdm-html: hdm-html-b hdm-html-c - -# HdM PDF only -define hdm_pdf_course - @echo "Building PDFs for $(1)..." - @mkdir -p build/$(1) - @for f in $($(1)_KAPITEL); do \ - if [ -f "$(SLIDES_DIR)/$(1)/$$f.md" ]; then \ - echo " $$f.pdf"; \ - npx @marp-team/marp-cli $(SLIDES_DIR)/$(1)/$$f.md --pdf --allow-local-files -o build/$(1)/$$f.pdf; \ - fi \ - done -endef - -hdm-pdf-b: build/.exists - $(call hdm_pdf_course,223015b) - -hdm-pdf-c: build/.exists - $(call hdm_pdf_course,223015c) - -hdm-pdf: hdm-pdf-b hdm-pdf-c - -# Legacy aliases (no prefix) -build: hdm-build -html: hdm-html -pdf: hdm-pdf - -# Klausur extraction (HdM) -hdm-klausur-b: - @./scripts/extract-klausur.sh 223015b - -hdm-klausur-c: - @./scripts/extract-klausur.sh 223015c - -hdm-klausur: hdm-klausur-b hdm-klausur-c - @echo "Klausurfolien slides extracted for all HdM courses!" - -klausur: hdm-klausur - -# QR Code generation +# ----------------------------------------------------------------------------- +# Tools +# ----------------------------------------------------------------------------- qr: ifndef URL - @echo "Usage: make qr URL=https://example.com" - @echo " make qr URL=https://example.com OUTPUT=my-qr.png" + @echo "Usage: make qr URL=https://example.com [OUTPUT=qr.png]" else @nix-shell -p qrencode --run 'qrencode -o $(or $(OUTPUT),qr-code.png) -s 10 "$(URL)"' @echo "Generated: $(or $(OUTPUT),qr-code.png)" @@ -214,79 +165,28 @@ endif qr-slides: ifndef COURSE - @echo "Usage: make qr-slides COURSE=223015b" + @echo "Usage: make qr-slides COURSE=" else @nix-shell -p qrencode --run 'qrencode -o build/$(COURSE)/qr-$(COURSE).png -s 10 "https://librete.ch/hdm/$(COURSE)/"' @echo "Generated: build/$(COURSE)/qr-$(COURSE).png" endif -# Optimize images optimize-images: ifndef COURSE - @echo "Usage: make optimize-images COURSE=223015b" + @echo "Usage: make optimize-images COURSE=" else @echo "Optimizing images for $(COURSE)..." @mkdir -p $(SLIDES_DIR)/$(COURSE)/assets-original @nix-shell -p imagemagick --run 'for img in $(SLIDES_DIR)/$(COURSE)/assets/*.png $(SLIDES_DIR)/$(COURSE)/assets/*.jpg 2>/dev/null; do \ [ -f "$$img" ] && cp "$$img" $(SLIDES_DIR)/$(COURSE)/assets-original/ && \ - magick "$$img" -resize "1920x>" -quality 85 "$$img" && echo " Optimized: $$(basename $$img)"; \ + magick "$$img" -resize "1920x>" -quality 85 "$$img" && echo " $$(basename $$img)"; \ done || true' - @echo "Done! Originals in assets-original/" + @echo "Done. Originals in assets-original/" endif -# Root index -build-index: build/.exists - @echo "Building root index..." - @mkdir -p build - @./scripts/generate-root-index.sh - -# Deploy (HdM) -define hdm_deploy_course - @echo "Deploying $(1)..." - scp build/$(1)/*.html $(DEPLOY_HOST):$(HDM_DEPLOY_PATH)/$(1)/ - scp build/$(1)/*.pdf $(DEPLOY_HOST):$(HDM_DEPLOY_PATH)/$(1)/ 2>/dev/null || true - scp build/$(1)/*.svg $(DEPLOY_HOST):$(HDM_DEPLOY_PATH)/$(1)/ 2>/dev/null || true - scp -r build/$(1)/assets/ $(DEPLOY_HOST):$(HDM_DEPLOY_PATH)/$(1)/ 2>/dev/null || true - scp -r build/$(1)/materials/ $(DEPLOY_HOST):$(HDM_DEPLOY_PATH)/$(1)/ 2>/dev/null || true - @echo "$(1) deployed!" -endef - -hdm-deploy-b: hdm-build-b - $(call hdm_deploy_course,223015b) - -hdm-deploy-c: hdm-build-c - $(call hdm_deploy_course,223015c) - -hdm-deploy: hdm-build hdm-deploy-b hdm-deploy-c - @echo "All HdM courses deployed!" - -# Deploy (DHBW) -define dhbw_deploy_course - @echo "Deploying $(1)..." - scp build/$(1)/*.html $(DEPLOY_HOST):$(DHBW_DEPLOY_PATH)/$(1)/ - scp build/$(1)/*.pdf $(DEPLOY_HOST):$(DHBW_DEPLOY_PATH)/$(1)/ 2>/dev/null || true - scp build/$(1)/*.svg $(DEPLOY_HOST):$(DHBW_DEPLOY_PATH)/$(1)/ 2>/dev/null || true - scp -r build/$(1)/assets/ $(DEPLOY_HOST):$(DHBW_DEPLOY_PATH)/$(1)/ 2>/dev/null || true - @echo "$(1) deployed!" -endef - -dhbw-deploy: dhbw-build - $(call dhbw_deploy_course,dhbw) - -deploy-index: build-index - @echo "Deploying root index..." - scp build/index.html $(DEPLOY_HOST):$(HDM_DEPLOY_PATH)/ 2>/dev/null || true - @echo "Root index deployed!" - -deploy: build-index hdm-deploy dhbw-deploy deploy-index - @echo "All courses deployed!" - -# Clean clean: - @echo "Cleaning generated files..." + @echo "Cleaning..." rm -rf build/ .dev-index/ *.pdf *.html qr-code.png -# Install dependencies install: - @echo "Installing dependencies..." - npm install + @npm install