A clean, readable academic website built with Pelican using a custom theme inspired by Tufte CSS.
- Off-white/dark backgrounds with comfortable text contrast (dark/light mode toggle)
- Academic structure: Research, Teaching, and Consulting as landing pages with subpages
- Topic-based blog: Thoughts and HowTos categories
- Sidenotes and marginnotes in the Tufte style
- Responsive design that gracefully adapts to mobile screens
- EB Garamond typography for classical elegance
- GitHub Pages deployment via GitHub Actions
- Jekyll-style Tufte tags for easy content creation
- Python 3.8+
- pip
# Clone the repository
git clone https://github.com/yourusername/your-repo-name.git
cd your-repo-name
# Install dependencies
pip install pelican markdown
# Generate the site
pelican content
# Start the development server
pelican --listenVisit http://localhost:8000 to preview your site.
For static pages (like research publications, course lists):
Add Markdown files to content/pages/:
Title: My Page
Slug: my-page
Content here...For blog posts (research notes, teaching reflections, thoughts):
Add Markdown files to content/:
Title: My New Post
Date: 2024-01-15
Category: Thoughts
Summary: A brief description.
Your content here...Available blog categories:
Thoughts- Essays and reflectionsHowTos- Practical applications and case studies
Note: Research, Teaching, and Consulting are now static pages, not blog categories. To add blog posts about these topics, create posts that link from the respective landing pages.
Each category automatically gets its own page listing all articles in that topic.
For static pages (like About), add files to content/pages/:
Title: About
Slug: about
Page content here...This theme includes a plugin that provides Jekyll-style tags for Tufte elements, making it much easier to write content.
Sidenotes (numbered, appear in margin):
Some text{% sidenote "sn-unique-id" "This appears in the margin with a number." %} continues here.
Marginnotes (unnumbered, appear in margin with ⊕ toggle):
Some text{% marginnote "mn-unique-id" "This appears in the margin without a number." %} continues here.
Newthought (small caps opening phrase):
{% newthought "The opening phrase" %} of a new section in small caps.
Epigraph (styled quotation block):
{% epigraph "The quote text here." "Author Name" "Source Title" %}
Main column image:
{% maincolumn "assets/img/photo.jpg" "Caption for the image" %}
Full-width image (spans main content + margin):
{% fullwidth "images/wide-photo.jpg" "Caption for the full-width image" %}
Margin figure (image in margin):
{% marginfigure "mf-unique-id" "assets/img/small.jpg" "Caption in margin" %}
Note: Each sidenote, marginnote, and marginfigure needs a unique ID (like sn-1, mn-example, mf-photo) for the mobile toggle to work correctly.
MathJax is enabled for mathematical notation:
Inline math: $E=mc^2$ or \(E=mc^2\)
Display math:
$$
x = \frac{-b \pm \sqrt{b^2-4ac}}{2a}
$$
To show literal dollar signs without rendering math:
- Use backticks for inline code:
`$100`renders as$100 - Use backslash escape:
\$100renders as $100 - Math won't process inside code blocks or inline code
The site is organized for academic use:
Navigation: Research | Teaching | Consulting | Thoughts | HowTos | About | Colophon
Static Pages:
research.md— Landing page with working papers and links to domainsresearch-astrophysics.md— Astrophysics publicationsresearch-data-science.md— Data science publicationsresearch-accounting.md— Accounting publicationsteaching.md— Landing page with current coursesteaching-courses.md— All courses taughtteaching-materials.md— Course materials and resourcesconsulting.md— Consulting services and approachabout.md— Biographical informationcolophon.md— Site credits and tech stack
Blog Posts: Regular articles with categories (Thoughts, HowTos)
The site includes an automatic dark/light mode toggle. Click the 🌙/☀️ button in the navigation. The preference is saved in your browser's localStorage.
To customize the color schemes, edit themes/tufte/static/css/tufte.css:
:root, [data-theme="light"] {
--bg-color: #fffff8;
--text-color: #333333;
/* ... more variables */
}
[data-theme="dark"] {
--bg-color: #1a1a1a;
--text-color: #e0e0e0;
/* ... more variables */
}- Push this repository to GitHub
- Go to Settings → Pages
- Under "Build and deployment", select GitHub Actions
- Update
SITEURLinpublishconf.pywith your GitHub Pages URL:SITEURL = 'https://yourusername.github.io/your-repo-name'
- Push changes—the site will build and deploy automatically
# Generate production build
pelican content -s publishconf.py
# The output/ directory contains your static site
# Deploy it to any static hosting serviceEdit pelicanconf.py:
SITENAME = 'Your Site Title'
AUTHOR = 'Your Name'
SITESUBTITLE = 'Optional tagline'To change blog category names, edit pelicanconf.py:
TOPICS = [
('Thoughts', 'thoughts'),
('HowTos', 'use-cases'),
('Consulting', 'consulting'),
]Edit CSS variables in themes/tufte/static/css/tufte.css (see Dark Mode section above).
├── content/
│ ├── pages/ # Static pages (about, contact)
│ ├── extra/ # Files copied as-is (.nojekyll)
│ └── *.md # Blog posts
├── themes/
│ └── tufte/
│ ├── static/css/ # Tufte CSS
│ └── templates/ # Jinja2 templates
├── output/ # Generated site (gitignored)
├── pelicanconf.py # Development config
├── publishconf.py # Production config
└── .github/workflows/ # GitHub Actions
Theme and configuration are provided under the MIT License. Content is yours.