Word Clouds
OKLCH-palettized word clouds generated from your GitHub starred-repo topics and languages.
Modules
scripts/word_clouds/generate.py— orchestration, file I/O, CLI-facing settings, and output dispatchscripts/word_clouds/metaheuristic.py— animated SVG renderer that sequences 25 solver layouts into one asset
Two config models
WordCloudSettingsModel in config.py is the top-level YAML config (part of ProjectConfig). WordCloudSettings in word_clouds.py is the internal generator config with extra="forbid". Extra keys silently pass in the first, raise ValidationError in the second.
What it generates
SVG word clouds where:
- Topics cloud — keywords from repositories you've starred, sorted by topic frequency
- Languages cloud — programming languages across your starred repos
The README and CI pipeline default to animated SVGs where each frame is laid out by a different metaheuristic solver. Static renderers remain available for manual generation.
Optimization model
All metaheuristic frames solve the same placement problem. The objective is "lower is better" and combines:
- Hard feasibility penalties for overlap and out-of-bounds words
- Packing density inside the occupied hull
- Visual balance around the canvas center
- Whitespace uniformity between neighboring words
- Reading-flow penalties for hard-to-scan rotations
- Landscape-aspect bias so layouts stay broad instead of collapsing into portrait stacks
- Size-gradient preference so larger words stay closer to the visual center
The readability policy is active during solver sampling, not just final scoring. Large words can use a different rotation palette than smaller words, which lets you keep headline terms mostly horizontal while still allowing more variation in the tail.
Input data
The word cloud reads a markdown file produced by the starred CLI tool:
.github/assets/topics.md ← topic-grouped starred repos
.github/assets/languages.md ← language-grouped starred reposThese are updated nightly by the update-starred-lists workflow job.
CLI
# Topics word cloud
uv run python -m scripts.cli generate word-cloud \
--config-path ./config.yaml \
--from-topics-md \
--output-path .github/assets/img/wordcloud_typographic_by_topics.svg
# Languages word cloud
uv run python -m scripts.cli generate word-cloud \
--config-path ./config.yaml \
--from-languages-md \
--output-path .github/assets/img/wordcloud_typographic_by_languages.svgConfiguration
Under word_cloud_settings in config.yaml:
word_cloud_settings:
output_dir: .github/assets/img
output_filename: word_cloud.png
max_words: 1000
prompt: "My Tech Skills: Python, JavaScript, Cloud, AI, DevOps, SQL, React"
stopwords: [] # Additional stopwords list
layout_readability:
standard_rotations: [0, 0, 0, -8, 8, 90]
large_word_rotations: [0, 0, 0, -8, 8]
large_word_threshold_ratio: 0.72
reading_flow_weight: 2.0
target_aspect_ratio: 1.8
landscape_bias_weight: 1.4Key knobs:
max_wordslimits the generated vocabulary before rendering for both classic and SVG backendsstopwordsfilters explicit prompt terms and markdown-derived frequencies before layoutstandard_rotationscontrols the general rotation palettelarge_word_rotationsapplies only to the largest words in the layoutlarge_word_threshold_ratiodecides which words count as "large"reading_flow_weightincreases or relaxes the cost of difficult rotationstarget_aspect_ratioandlandscape_bias_weightsteer the solver toward wider layoutspromptis tokenized from comma/newline separated tags or free text when you generate directly from text
Output files
| File | Description |
|---|---|
wordcloud_typographic_by_topics.svg | Static topics cloud preserving every parsed topic in a readable typographic layout |
wordcloud_typographic_by_languages.svg | Static languages cloud preserving every parsed language in a readable typographic layout |
Rendering backends
The scripts/word_clouds/ subpackage provides several SVG renderers. The CI pipeline and README use the typographic renderer:
| Renderer | Strategy |
|---|---|
WordleRenderer | Classic Wordle-style random placement |
ClusteredRenderer | Grouped by semantic clusters |
TypographicRenderer | Typography-focused layout |
ShapedRenderer | Mask-based shape filling |
MetaheuristicAnimRenderer | 25 solver frames ordered into one CSS-animated SVG |