This skill generates case study entries for intelligent textbook projects from GitHub repositories...
This skill automates the creation of case study entries for the intelligent textbooks case studies page. Given a GitHub repository URL, it extracts project information, generates or processes a thumbnail image compressed to ~70KB, and creates a properly formatted markdown entry for docs/case-studies/index.md.
Extract the following from the GitHub repository:
dmccreary/geometry-course)https://{username}.github.io/{repo-name}{BOOK_BASE}/docs/learning-graph/book-metrics.json
first, in every repo, whether you're adding a brand-new case study or
refreshing an existing one. Do not re-count by hand if this file exists.Canonical source: docs/learning-graph/book-metrics.json (produced by
the book-metrics tool, validated against book-metrics.schema.json). Its
metrics object is the single source of truth shared with the README and
LinkedIn skills, so the case-study card shows identical numbers:
# After cloning/locating the repo for analysis:
python3 -c "import json; m=json.load(open('docs/learning-graph/book-metrics.json'))['metrics']; \
print(m['concepts'], m['chapters'], m['microsims'], m['glossaryTerms'], m['faqs'], m['words'])"
Available keys include concepts, chapters, microsims, stories,
glossaryTerms, faqs, quizQuestions, references, diagrams,
equations, words, links, equivalentPages, developmentStage.
If working from a local workspace clone (~/Documents/ws/{repo-name}),
check whether it's behind origin/main before trusting this file — a
stale checkout reports stale metrics:
git rev-list --left-right --count HEAD...origin/main # "0 N" = N commits behind
If it's behind and the working tree is clean, just git pull. If there
are uncommitted local changes, don't discard them — git stash push -u,
pull, read book-metrics.json, then git stash pop to restore the local
work exactly as it was.
When updating an already-listed case study, re-read this file rather than reusing the numbers already on the card — the file exists precisely because a book's metrics change between visits, so treat the existing card's numbers as stale until confirmed otherwise.
Fallback only if book-metrics.json is absent:
find docs -type f -name "*.md" | wc -lfind docs -type f -name "*.md" -exec cat {} \; | wc -wdocs/sims/docs/glossary.md if existsUse the gh CLI or direct GitHub API to fetch repository information:
# Get repo description
gh repo view {owner}/{repo} --json description
# Clone repo temporarily for analysis
gh repo clone {owner}/{repo} /tmp/{repo} -- --depth 1
Check for existing thumbnail options in priority order:
docs/img/ for social-card.png or similarPlace the source image in docs/case-studies/img/ with a filename matching the repo name:
geometry-course.jpg, deep-learning-course.jpgCompress the thumbnail to approximately 70KB for fast page loading.
Run the thumbnail compression script:
python3 src/compress-thumbnails.py docs/case-studies/img 70
This script:
.backup files for safetyIf PNG compression cannot achieve 70KB target, convert to JPEG:
python3 src/convert-png-to-jpg.py docs/case-studies/img 70
This script:
For compressing a single new image without affecting others:
from PIL import Image, ImageOps
def compress_single_image(input_path, output_path, target_kb=70, min_width=400):
"""Compress a single image to target size."""
img = Image.open(input_path)
img = ImageOps.exif_transpose(img)
# Convert to RGB for JPEG
if img.mode in ('RGBA', 'LA', 'P'):
background = Image.new('RGB', img.size, (255, 255, 255))
if img.mode == 'P':
img = img.convert('RGBA')
if img.mode in ('RGBA', 'LA'):
background.paste(img, mask=img.split()[-1])
img = background
elif img.mode != 'RGB':
img = img.convert('RGB')
# Calculate resize factor
orig_w, orig_h = img.size
min_factor = min_width / orig_w if orig_w > min_width else 1.0
for factor in [0.5, 0.4, 0.35, 0.3, 0.25, 0.2, 0.15]:
if factor < min_factor:
continue
new_w = int(orig_w * factor)
new_h = int(orig_h * factor)
resized = img.resize((new_w, new_h), Image.Resampling.LANCZOS)
for quality in [85, 80, 75, 70, 65, 60]:
resized.save(output_path, "JPEG", quality=quality, optimize=True)
if os.path.getsize(output_path) / 1024 <= target_kb:
return True
return False
After converting PNG to JPEG, update docs/case-studies/index.md to use the new .jpg extension:
# Before

# After

Create the markdown entry using the format in references/entry-format.md.
- **[Project Title](https://username.github.io/repo-name)**

Brief 1-2 sentence description of the project, its purpose, and target audience.
XXX Concepts · XX Chapters · XX MicroSims · XXK Words · XX Glossary Terms · XX FAQs
· <span class="completion completion-5" title="Complete (5/5)"></span>
· [:octicons-mark-github-16: Repository](https://github.com/username/repo-name)
CRITICAL — blank lines between entries: The
<div class="grid cards grid-3-col" markdown>block requires a blank line between every list item. If blank lines are missing, MkDocs Material renders all cards as a single-column list instead of a 3-column grid. Always ensure there is an empty line after the· [:octicons...]repo line before the next- **[entry.
docs/learning-graph/book-metrics.json (canonical source). Format metrics separated by · on one line, then the completion span and repo link each on their own · continuation lines:157K Words)<span class="completion completion-X" title="..."></span>Insert the new entry into docs/case-studies/index.md in alphabetical order by project title. The entries are inside a <div class="grid cards grid-3-col" markdown> block.
mkdocs serve and check the case studies pagerm docs/case-studies/img/*.backup
rm -rf /tmp/{repo-name}
User request: "Add a case study for https://github.com/dmccreary/systems-thinking"
Process:
docs/case-studies/img/systems-thinking.jpg (~31KB)- **[Systems Thinking in the Age of AI](https://dmccreary.github.io/systems-thinking)**

Interactive resources for teaching systems thinking from high school to executive level. Multiple course descriptions.
200 Concepts · 15 Chapters · 13 MicroSims · 120K Words · 41 Glossary Terms
· <span class="completion completion-2" title="Early Development (2/5)"></span>
· [:octicons-mark-github-16: Repository](https://github.com/dmccreary/systems-thinking)
mkdocs serve that the page still shows 3 columnsThe following scripts are located in the project's src/ directory:
src/compress-thumbnails.py - Compresses images to target KB size with configurable minimum widthsrc/convert-png-to-jpg.py - Converts PNG files to JPEG format for better compressionreferences/entry-format.md - Template and examples for case study entries