This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
The Perl Advent Calendar is a static site generator that publishes 24-25 Perl module articles annually from December 1-25. The site is deployed to GitHub Pages at https://perladvent.org.
The build system follows this flow:
POD articles (YEAR/articles/) → WWW::AdventCalendar processes →
HTML pages generated → Static files copied → out/ directory → GitHub Pages
- WWW::AdventCalendar - Main engine converting POD to HTML (git submodule in
inc/WWW-AdventCalendar) - Pod::Elemental::Transformer::SynHi - Syntax highlighting for code blocks
- Text::VimColor + vim-perl - Vim-based syntax highlighting
- PPI::HTML - Perl code parsing and HTML generation
- YEAR/articles/ - Published articles in
YYYY-MM-DD.podformat - YEAR/incoming/ - Work-in-progress articles before date assignment
- YEAR/share/static/ - Images and assets specific to that year
- YEAR/advent.ini - Year-specific configuration (colors, metadata)
- script/ - Build and maintenance scripts
- inc/ - Git submodules for forked dependencies
- out/ - Generated static HTML (not committed)
perl script/new_article
# Creates YEAR/incoming/slug.pod with template# Test specific article
perl t/article_pod.t 2025/incoming/your-article.pod
# Test all articles
prove -lr t/# Find article interactively and assign to December day
find 2025/incoming | fzf | xargs -I {} perl script/assign-date.pl --article {} --day 5 --year 2025
# This moves article to 2025/articles/2025-12-05.pod and creates publish branch/PR
# IMPORTANT: Images must be moved manually from incoming/ to share/static/# Build entire site
./script/build-site.sh
# Build single year (faster for testing)
./script/build-site.sh --single-year 2025
# Simulate specific date (useful for testing calendar behavior)
./script/build-site.sh --today 2025-12-15
# Build and serve locally
./script/build-site.sh --single-year 2025
cpm install -g App::HTTPThis
http_this --autoindex out/
# Visit http://127.0.0.1:7007/2025/# Renders all incoming articles with sequential December dates
perl script/render-incoming.pl
http_this --autoindex out/2025# Add previous year to archives database
./year2yaml 2024
# Prepare for new year
./script/prepare-new-year.shArticles are written in POD (Plain Old Documentation) with these required headers:
Author: Your Name <email@example.com>
Title: Article Title
Topic: Module::Name
Raw HTML blocks:
=for html
<img src="image-name.png" alt="description" style="float: right; margin: 0 0 1em 1em; width: 300px;">
Note: Both =for html and =for :html are valid POD syntax and work correctly in this codebase.
Syntax-highlighted code blocks:
=begin perl
my $code = 'with syntax highlighting';
=end perl
Bullet lists:
=for :list
* Item one
* Item two
Links:
L<Module::Name> # Auto-links to CPAN
L<text|https://url.com> # External link
- Place images in
YEAR/share/static/directory - During build, files are copied to
out/YEAR/ - Reference in articles with relative path:
src="image-name.png"
- Wrong directory: Images must be in
YEAR/share/static/notYEAR/incoming/ - Not copied during assign-date: The script reminds you, but images must be moved manually
- Missing indentation: HTML content in
=for htmlblocks should be indented
Example:
=for html
<img src="image.png" alt="description">
- Articles publish as
YYYY-12-DD.htmlwhere DD is 01-25 - The published HTML filename comes from the POD filename
- If file is
2025-12-01.pod, it publishes as2025-12-01.html - Note: The calendar may display it on Dec 3 if that's when it's scheduled in the build
- All articles must have valid POD syntax
- Required headers: Author, Title, Topic
- Tests run automatically on all PRs via GitHub Actions
- Authors: Fork → create article in incoming/ → PR to main
- Editors: Review → merge to main → assign-date.pl → publish branch → PR
- Automation: GitHub Actions deploys to Pages in December/January
script/build-site.sh performs these steps:
- Generate archive pages from
archives.yamlusingmkarchives - For each year 2011-2025:
- Copy static assets to
out/YEAR/ - Run
advcal -c advent.ini -o ../out/YEARto generate HTML
- Copy static assets to
- Copy root assets (images, CSS, HTML)
- Convert Markdown docs to HTML
- advent.ini: Per-year config (title, colors, directories, editor info)
- archives.yaml: Historical database of all articles (populated via
year2yaml) - .perl-version: Required Perl version (5.36.0)
- cpanfile: Perl dependencies
- test.yml: Runs POD validation tests on all PRs
- build.yml: Builds site and deploys to GitHub Pages (December-January only)
- Check filename matches
YYYY-MM-DD.podformat - Verify it's in
articles/notincoming/ - Check advent.ini
end_dateincludes that date - Test with
--todayflag to simulate publication date
- Verify image is in
YEAR/share/static/ - Check HTML content in
=for htmlblocks is properly indented - Rebuild and check
out/YEAR/contains the image - Verify HTML isn't escaped in generated file
- Check POD syntax:
perl t/article_pod.t path/to/article.pod - Verify required headers present
- Check for unescaped special characters in POD
- Review GitHub Actions logs for specific errors
From EDITING.md:
- Light touch editing: Preserve author's voice while fixing grammar/spelling
- Christmas themes welcome but optional: Festive elements encouraged but not required
- Technical accuracy required: Verify all code examples work
- Graphics encouraged: Images, GIFs, SVGs add visual interest
- Use GitHub PR suggestions for typo fixes
- Post-merge edits acceptable for minor fixes
- September 30: Article proposal deadline
- October 1: Acceptance notifications
- November 1: First draft due
- November 15: Final edits due
- December 1 (12:00 AM EST): Articles go live