- CLAUDE.md: Add cover letter RST format guide - Makefile: Use cover-letter.style for PDF generation - lib/generate_llms_txt.py: Add contact, payment, software, ML expertise & commission sections - New cover letters: Phantom Backend (Money Movement), Solflare Backend Developer - cover-letter.style: rst2pdf styling for clean PDF output
196 lines
9.9 KiB
Makefile
196 lines
9.9 KiB
Makefile
.PHONY: html help clean regenerate serve devserver publish pygments jsonresume jsonresume-themes jsonresume-pdf rst2md llms jsonfeed jsonblog plaintext formats
|
|
|
|
BASEDIR=$(CURDIR)
|
|
INPUTDIR=$(BASEDIR)/content
|
|
OUTPUTDIR=$(BASEDIR)/output
|
|
CONFFILE=$(BASEDIR)/pelicanconf.py
|
|
PUBLISHCONF=$(BASEDIR)/publishconf.py
|
|
|
|
help:
|
|
@echo 'Makefile for a pelican Web site '
|
|
@echo ' '
|
|
@echo 'Usage: '
|
|
@echo ' make venv setup virtual environment '
|
|
@echo ' make resume (re)generate the resume PDF '
|
|
@echo ' make jsonresume copy JSONResume to output '
|
|
@echo ' make jsonresume-themes install 30 jsonresume themes '
|
|
@echo ' make jsonresume-pdf generate PDFs for favorite themes '
|
|
@echo ' make cover-letters (re)generate cover letter PDFs '
|
|
@echo ' make html (re)generate the web site '
|
|
@echo ' make clean remove the generated files '
|
|
@echo ' make regenerate regenerate files upon modification '
|
|
@echo ' make publish generate using production settings '
|
|
@echo ' make serve serve site at http://localhost:8000'
|
|
@echo ' make devserver serve and regenerate together '
|
|
@echo ' make pygments generate pygments stylesheets '
|
|
@echo ' make rst2md convert RST to MD in output '
|
|
@echo ' make llms generate llms.txt for AI agents '
|
|
@echo ' make jsonfeed generate JSON Feed (/feeds/all.json)'
|
|
@echo ' make jsonblog generate JSON Blog (/blog.json) '
|
|
@echo ' make plaintext generate plain text (index.txt) '
|
|
@echo ' make formats generate all agent-friendly formats'
|
|
@echo ' '
|
|
|
|
THEME_REPO_URL ?= git@github.com:russellballestrini/pelican-svbhack.git
|
|
|
|
venv:
|
|
python3 -m venv venv
|
|
venv/bin/pip install -r requirements.txt
|
|
mkdir -p pelican-themes
|
|
cd pelican-themes && git clone $(THEME_REPO_URL)
|
|
venv/bin/pelican-themes -i pelican-themes/pelican-svbhack/
|
|
|
|
resume: jsonresume
|
|
venv/bin/rst2pdf content/pages/russell.ballestrini.resume.rst --stylesheets content/pages/russell.ballestrini.resume.style -o output/uploads/russell.ballestrini.resume.pdf
|
|
@echo "Creating softlinks for various job titles..."
|
|
@cd output/uploads && ln -sf russell.ballestrini.resume.pdf founder.russell.ballestrini.resume.pdf
|
|
@cd output/uploads && ln -sf russell.ballestrini.resume.pdf founding.engineer.russell.ballestrini.resume.pdf
|
|
@cd output/uploads && ln -sf russell.ballestrini.resume.pdf software.developer.russell.ballestrini.resume.pdf
|
|
@cd output/uploads && ln -sf russell.ballestrini.resume.pdf software.engineer.russell.ballestrini.resume.pdf
|
|
@cd output/uploads && ln -sf russell.ballestrini.resume.pdf senior.software.engineer.russell.ballestrini.resume.pdf
|
|
@cd output/uploads && ln -sf russell.ballestrini.resume.pdf staff.software.engineer.russell.ballestrini.resume.pdf
|
|
@cd output/uploads && ln -sf russell.ballestrini.resume.pdf principal.software.engineer.russell.ballestrini.resume.pdf
|
|
@cd output/uploads && ln -sf russell.ballestrini.resume.pdf full.stack.engineer.russell.ballestrini.resume.pdf
|
|
@cd output/uploads && ln -sf russell.ballestrini.resume.pdf site.reliability.engineer.russell.ballestrini.resume.pdf
|
|
@cd output/uploads && ln -sf russell.ballestrini.resume.pdf sre.russell.ballestrini.resume.pdf
|
|
@cd output/uploads && ln -sf russell.ballestrini.resume.pdf devops.engineer.russell.ballestrini.resume.pdf
|
|
@cd output/uploads && ln -sf russell.ballestrini.resume.pdf backend.engineer.russell.ballestrini.resume.pdf
|
|
@cd output/uploads && ln -sf russell.ballestrini.resume.pdf platform.engineer.russell.ballestrini.resume.pdf
|
|
@cd output/uploads && ln -sf russell.ballestrini.resume.pdf infrastructure.engineer.russell.ballestrini.resume.pdf
|
|
@echo "Resume softlinks created!"
|
|
|
|
jsonresume:
|
|
@mkdir -p output/uploads
|
|
cp content/pages/russell.ballestrini.resume.json output/uploads/russell.ballestrini.resume.json
|
|
cp content/pages/unturf.resume.json output/uploads/unturf.resume.json
|
|
@echo "JSONResume files copied to output/uploads/"
|
|
|
|
# JSONResume themes - 30 tested working themes
|
|
JSONRESUME_THEMES = classy cora dark-classy-responsive elegant eloquent even kards kendall \
|
|
light-classy-responsive lucide modern modern-extended modern-plain msresume nameme one \
|
|
onepage-plus printclassy projects rnord rocketspacer sceptile simplyelegant stackoverflow \
|
|
stackoverflow-ru straightforward tan-responsive techlead timeline-fixed waterfall
|
|
|
|
RESUME_FILE ?= content/pages/russell.ballestrini.resume.json
|
|
|
|
jsonresume-themes:
|
|
@echo "Installing 30 jsonresume themes..."
|
|
npm install $(addprefix jsonresume-theme-,$(JSONRESUME_THEMES)) puppeteer --legacy-peer-deps
|
|
@echo "Done! Run: make jsonresume-pdf"
|
|
|
|
# Export JSONResume as HTML in all themes
|
|
jsonresume-all-html:
|
|
@mkdir -p output/uploads/jsonresume-themes
|
|
@echo "Generating HTML for all themes..."
|
|
@for theme in $(JSONRESUME_THEMES); do \
|
|
echo " Generating $$theme..."; \
|
|
node -e "try { \
|
|
const t = require('jsonresume-theme-$$theme'); \
|
|
const r = require('./$(RESUME_FILE)'); \
|
|
require('fs').writeFileSync('output/uploads/jsonresume-themes/russell.ballestrini.$$theme.html', t.render(r)); \
|
|
console.log(' OK'); \
|
|
} catch(e) { console.log(' Failed:', e.message.split('\n')[0]); }" 2>/dev/null || echo " Failed: $$theme"; \
|
|
done
|
|
@echo "HTML files saved to output/uploads/jsonresume-themes/"
|
|
@echo "Open in browser & print to PDF"
|
|
|
|
# Favorite JSONResume themes for PDF export
|
|
JSONRESUME_PDF_THEMES = kendall modern-plain one onepage-plus
|
|
|
|
# Generate PDFs for favorite themes using puppeteer
|
|
jsonresume-pdf: jsonresume-all-html
|
|
@mkdir -p output/uploads
|
|
@echo "Generating PDFs for favorite themes..."
|
|
@node -e " \
|
|
const puppeteer = require('puppeteer'); \
|
|
const themes = '$(JSONRESUME_PDF_THEMES)'.split(' '); \
|
|
(async () => { \
|
|
const browser = await puppeteer.launch({headless: 'new'}); \
|
|
for (const theme of themes) { \
|
|
const page = await browser.newPage(); \
|
|
await page.goto('file://$(CURDIR)/output/uploads/jsonresume-themes/russell.ballestrini.' + theme + '.html', {waitUntil: 'networkidle0'}); \
|
|
await page.pdf({path: '$(CURDIR)/output/uploads/russell.ballestrini.' + theme + '.pdf', format: 'A4'}); \
|
|
console.log(' Created: russell.ballestrini.' + theme + '.pdf'); \
|
|
await page.close(); \
|
|
} \
|
|
await browser.close(); \
|
|
})(); \
|
|
"
|
|
@echo "PDFs saved to output/uploads/"
|
|
|
|
cover-letter:
|
|
@if [ -z "$(FILE)" ]; then \
|
|
echo "Usage: make cover-letter FILE=filename-without-extension"; \
|
|
echo "Example: make cover-letter FILE=2025-11-29-runpod-principal-software-engineer-storage-systems-russell-ballestrini"; \
|
|
exit 1; \
|
|
fi
|
|
@mkdir -p output/uploads/cover-letters
|
|
@echo "Generating PDF for $(FILE)..."
|
|
@venv/bin/rst2pdf content/pages/cover-letters/$(FILE).rst --stylesheets content/pages/cover-letters/cover-letter.style -o output/uploads/cover-letters/$(FILE).pdf
|
|
@echo "PDF generated: output/uploads/cover-letters/$(FILE).pdf"
|
|
|
|
cover-letters:
|
|
@mkdir -p output/uploads/cover-letters
|
|
@for letter in content/pages/cover-letters/*.rst; do \
|
|
basename=$$(basename $$letter .rst); \
|
|
echo "Generating PDF for $$basename..."; \
|
|
venv/bin/rst2pdf $$letter --stylesheets content/pages/cover-letters/cover-letter.style -o output/uploads/cover-letters/$$basename.pdf; \
|
|
done
|
|
@echo "All cover letters generated in output/uploads/cover-letters/"
|
|
|
|
html: pygments
|
|
venv/bin/pelican content -o output -s pelicanconf.py
|
|
|
|
clean:
|
|
[ ! -d output ] || rm -rf output
|
|
|
|
regenerate:
|
|
venv/bin/pelican -r content -o output -s pelicanconf.py
|
|
|
|
serve:
|
|
venv/bin/pelican -l content -o output -s pelicanconf.py
|
|
|
|
devserver:
|
|
venv/bin/pelican -lr content -o output -s pelicanconf.py
|
|
|
|
publish:
|
|
venv/bin/pelican content -o output -s publishconf.py
|
|
|
|
pygments:
|
|
@echo "Generating pygments stylesheets..."
|
|
venv/bin/python -c "from pygments.formatters import HtmlFormatter; print(HtmlFormatter(style='monokai').get_style_defs('.highlight'))" > pelican-themes/pelican-svbhack/static/css/pygments-dark.css
|
|
venv/bin/python -c "from pygments.formatters import HtmlFormatter; print(HtmlFormatter(style='default').get_style_defs('.highlight'))" > pelican-themes/pelican-svbhack/static/css/pygments-light.css
|
|
@echo "Patching to remove hardcoded backgrounds..."
|
|
sed -i 's/.highlight { background: #272822; color: #f8f8f2 }/.highlight { color: #f8f8f2 }/' pelican-themes/pelican-svbhack/static/css/pygments-dark.css
|
|
sed -i 's/.highlight { background: #f8f8f8; }/.highlight { }/' pelican-themes/pelican-svbhack/static/css/pygments-light.css
|
|
@echo "Done! Pygments stylesheets generated and patched."
|
|
|
|
rst2md:
|
|
@echo "Converting RST to Markdown in output directory..."
|
|
venv/bin/python lib/rst2md.py $(OUTPUTDIR)
|
|
@echo "Done! Markdown files generated alongside RST sources."
|
|
|
|
llms:
|
|
@echo "Generating llms.txt for AI agents..."
|
|
venv/bin/python lib/generate_llms_txt.py $(OUTPUTDIR) $(SITEURL)
|
|
@echo "Done! llms.txt generated in output directory."
|
|
|
|
jsonfeed:
|
|
@echo "Generating JSON Feed..."
|
|
venv/bin/python lib/generate_jsonfeed.py $(OUTPUTDIR) $(SITEURL)
|
|
@echo "Done! JSON Feed generated at /feeds/all.json"
|
|
|
|
jsonblog:
|
|
@echo "Generating JSON Blog..."
|
|
venv/bin/python lib/generate_jsonblog.py $(OUTPUTDIR) $(SITEURL)
|
|
@echo "Done! JSON Blog generated at /blog.json"
|
|
|
|
plaintext:
|
|
@echo "Generating plain text versions..."
|
|
venv/bin/python lib/generate_plaintext.py $(OUTPUTDIR)
|
|
@echo "Done! Plain text files generated (index.txt)."
|
|
|
|
formats: rst2md plaintext jsonfeed jsonblog llms
|
|
@echo "All agent-friendly formats generated!"
|
|
|
|
SITEURL ?= https://russell.ballestrini.net
|