Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions .github/workflows/build-html.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
name: Build HTML Lab Manual

on:
push:
branches: [master]
paths:
- 'lab_manual.tex'
- 'tufte.cfg'
- 'toc.js'
- 'lab-manual.css'
- '.github/workflows/build-html.yml'
pull_request:
branches: [master]
paths:
- 'lab_manual.tex'
- 'tufte.cfg'
- 'toc.js'
- 'lab-manual.css'
workflow_dispatch: # Allow manual triggering

permissions:
contents: read
pages: write
id-token: write

# Only allow one deployment at a time
concurrency:
group: "pages"
cancel-in-progress: false

jobs:
build-html:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install TeX Live
run: |
sudo apt-get update
sudo apt-get install -y texlive-latex-extra texlive-fonts-extra texlive-plain-generic tex4ht

- name: Run make4ht conversion
run: |
mkdir -p html_output
make4ht -u -c tufte.cfg -d html_output lab_manual.tex "mathml,mathjax" || true
# List what was generated
ls -la html_output/ || echo "html_output directory contents check"

- name: Download Tufte CSS assets
run: |
# Download tufte.css
curl -sL -o html_output/tufte.css https://raw.githubusercontent.com/edwardtufte/tufte-css/gh-pages/tufte.css

# Download ET Book fonts
mkdir -p html_output/et-book
for font in et-book-roman-line-figures et-book-roman-old-style-figures et-book-semi-bold-old-style-figures et-book-bold-line-figures; do
curl -sL -o "html_output/et-book/${font}.ttf" "https://github.com/edwardtufte/tufte-css/raw/gh-pages/et-book/${font}.ttf" 2>/dev/null || true
curl -sL -o "html_output/et-book/${font}.woff" "https://github.com/edwardtufte/tufte-css/raw/gh-pages/et-book/${font}.woff" 2>/dev/null || true
done

# Copy lab logo
cp -r lab_logo html_output/

# Copy custom files (toc.js for table of contents)
cp toc.js html_output/

# Rename main HTML file to index.html if needed
if [ -f html_output/lab_manual.html ] && [ ! -f html_output/index.html ]; then
cp html_output/lab_manual.html html_output/index.html
fi

- name: List output files
run: ls -la html_output/

- name: Upload HTML artifact
uses: actions/upload-artifact@v4
with:
name: html-lab-manual
path: html_output/
retention-days: 30

# Deploy to GitHub Pages only on push to master
deploy:
if: github.ref == 'refs/heads/master' && github.event_name == 'push'
needs: build-html
runs-on: ubuntu-latest

environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}

steps:
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: html-lab-manual
path: html_output

- name: Setup Pages
uses: actions/configure-pages@v4

- name: Upload to GitHub Pages
uses: actions/upload-pages-artifact@v3
with:
path: html_output

- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
13 changes: 13 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,16 @@ lab_manual.ilg
lab_manual.fdb_latexmk
lab_manual.ind
lab_manual.blg

# TeX4ht build artifacts
*.4ct
*.4tc
*.css
*.dvi
*.idv
*.lg
*.tmp
*.xref
lab_manual.html
html_output/
html_test/
44 changes: 44 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Repository Overview

This is the lab manual for the Contextual Dynamics Laboratory (CDL) at Dartmouth College. It's a LaTeX document using the Tufte-book class that describes lab policies, member responsibilities, and research approach.

## Build Commands

**Compile the PDF:**
```bash
./compile.sh
```

This runs `latex` multiple times (for cross-references and index), then `pdflatex`, and cleans up intermediate files. Requires a LaTeX distribution (e.g., `brew install --cask mactex` on macOS).

**HTML version:** The HTML version is automatically generated via GitHub Actions when changes are pushed to master. No manual build is needed. The workflow uses make4ht (TeX4ht) with `tufte.cfg` configuration to convert to tufte-css styled HTML.

## Project Structure

- `lab_manual.tex` - Main document source (single file containing all content)
- `lab_manual.pdf` - Compiled output (committed to repo)
- `tufte.cfg` - TeX4ht configuration for HTML generation
- `tufte-book.cls`, `tufte-common.def`, `tufte-handout.cls` - Custom Tufte template files
- `lab_logo/` - Lab logo images (PNG, PDF)
- `resources/` - Additional resources (cheatsheets, cluster tutorials)
- `.github/workflows/` - CI/CD workflows (LaTeX validation, HTML generation)

## LaTeX Conventions

The document uses several custom commands defined in `lab_manual.tex`:
- `\marginnote{}` - For margin notes (TASK items and NOTEs)
- `\newthought{}` - For section introductions
- `\ourschool` - Expands to "Dartmouth College"
- `\director`, `\coordinator` - Lab director references
- Links use `dartmouthgreen` color (RGB: 0, 105, 62)

## Workflow Notes

After editing `lab_manual.tex`:
1. Run `./compile.sh` to regenerate the PDF
2. Verify the PDF looks correct (check TOC links, margin notes positioning)
3. Commit both the `.tex` source and updated `.pdf`
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ All new lab members are required to read (and modify!) this repository *prior* t

A PDF of the latest version of the lab manual may always be found [here](https://github.com/ContextLab/lab-manual/blob/master/lab_manual.pdf).

An HTML version is also available at [contextlab.github.io/lab-manual](https://contextlab.github.io/lab-manual/). The HTML version is automatically generated from the LaTeX source whenever changes are pushed to the master branch.

## Building the PDF
To compile a PDF of the lab manual, you need to first install a working distribution of [LaTeX](https://www.latex-project.org/get/). If you're on a mac with [homebrew](https://brew.sh/), you can run `brew install --cask mactex`.

Expand Down
15 changes: 15 additions & 0 deletions toc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Generate table of contents from h2.chapterHead elements
document.addEventListener('DOMContentLoaded', function() {
var toc = document.getElementById('toc-list');
if (!toc) return;

var headings = document.querySelectorAll('h2.chapterHead');
headings.forEach(function(h) {
var li = document.createElement('li');
var a = document.createElement('a');
a.href = '#' + h.id;
a.textContent = h.textContent;
li.appendChild(a);
toc.appendChild(li);
});
});
129 changes: 129 additions & 0 deletions tufte.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
% tufte.cfg - TeX4ht configuration for Tufte-LaTeX to Tufte-CSS HTML conversion
% Based on: https://tex.stackexchange.com/questions/570630/can-a-tufte-latex-file-output-tufte-css-html
% Reference: https://edwardtufte.github.io/tufte-css/

\Preamble{xhtml}
\Configure{AddCss}{tufte.css}

% Helper macro to close current paragraph
\def\endparagraph{\ifvmode\IgnorePar\fi\EndP}

% Configure body to use article wrapper (tufte-css convention)
\Configure{@BODY}{\endparagraph\HCode{<article>}}
\Configure{@/BODY}{\endparagraph\HCode{</article>}}

% Configure sections (Tufte LaTeX makes \section and \subsection behave like starred versions)
\Configure{likesection}
{\endparagraph\HCode{<section>}}{\endparagraph\HCode{</section>}}
{\HCode{<h2 class="chapterHead">}}{\HCode{</h2>}\par\ShowPar}

\Configure{likesubsection}
{\endparagraph\HCode{<section>}}{\endparagraph\HCode{</section>}}
{\HCode{<h3 class="subsectionHead">}}{\HCode{</h3>}\par\ShowPar}

% Simple table of contents - will be populated by JavaScript
\renewcommand\tableofcontents{%
\endparagraph%
\HCode{<nav id="toc" class="toc"><h2>Contents</h2><ul id="toc-list"></ul></nav>}%
\HCode{<script src="toc.js"></script>}%
}

\makeatletter

% Configure title page
\renewcommand{\maketitle}{%
\begingroup%
\endparagraph\HCode{<h1>}\@title\HCode{</h1>}%
\HCode{<p class="subtitle">}\@author\HCode{</p>}%
\HCode{<p class="subtitle">}\@date\HCode{</p>}%
\endgroup
}

% Configure image dimensions
\Configure{Gin-dim}{}
\Css{img {
max-width: 100\%;
height: auto;
}}

% Fix soul package compatibility (for \allcaps, \smallcaps)
\@ifpackageloaded{soul}{%
\renewcommand{\allcaps}[1]{\MakeTextUppercase{#1}}%
\renewcommand{\smallcaps}[1]{{\scshape\MakeTextLowercase{#1}}}%
\renewcommand{\textsc}[1]{\textcaps{#1}}%
}{}

% Configure sidenotes with tufte-css checkbox toggle pattern
\long\def\@tufte@sidenote[#1][#2]#3{%
\stepcounter\@mpfn%
\bgroup%
\HCode{<label for="sidenote-\thempfn" class="margin-toggle sidenote-number"></label><input type="checkbox" id="sidenote-\thempfn" class="margin-toggle" />}%
\HCode{<span class="sidenote">}#3\HCode{</span>}%
\egroup%
}

% Configure margin notes (unnumbered)
% Use Unicode character directly for the circle-plus symbol
\renewcommand\marginnote[2][0pt]{%
\stepcounter\@mpfn%
\bgroup%
\HCode{<label for="marginnote-\thempfn" class="margin-toggle">⊕</label><input type="checkbox" id="marginnote-\thempfn" class="margin-toggle" />}%
\HCode{<span class="marginnote">}#2\HCode{</span>}%
\egroup%
}

% Configure verbatim environments
\ConfigureEnv{verbatim}{\endparagraph\HCode{<pre><code>}\NoFonts}{\EndNoFonts\endparagraph\HCode{</code></pre>}}{}{}

% Configure fullwidth environment
\ConfigureEnv{fullwidth}{\endparagraph\HCode{<div class="fullwidth">}%
\ConfigureList{list}{}{}{}{}%
\par\ShowPar\indent%
}
{\endparagraph\HCode{</div>}}{}{}

% Configure margin floats (marginfigure)
\NewConfigure{marginfloat}{2}

\renewenvironment{@tufte@margin@float}[2][-1.2ex]%
{\FloatBarrier%
\begingroup%
\let\textwidth\marginparwidth%
\def\@captype{#2}%
\par%
\Configure{HtmlPar}{\EndP\csname a:marginfloat\endcsname}{\EndP\csname a:marginfloat\endcsname}{\csname b:marginfloat\endcsname}{\csname b:marginfloat\endcsname}%
}
{\endgroup}

\Configure{marginfloat}{\HCode{<p><span class="marginnote">}%
\Configure{caption}{\HCode{<span class="figure">}}{:\space}{}{\HCode{</span>}}%
}{\HCode{</span></p>}}{}{}

\Css{.marginnote .figure{display:block;}}

% Configure regular floats
\renewenvironment{@tufte@float}[3][htbp]%
{\@float{#2}[#1]}{\end@float}

% Configure captions
\Configure{caption}{\HCode{<span class="marginnote">}}{:\space}{}{\HCode{</span>}}

% Configure fullwidth figures (figure*)
\ConfigureEnv{figure*}{
\Configure{float}{}{\endparagraph\HCode{<figure class="fullwidth">}}{\endparagraph\HCode{</figure>}\csname par\endcsname\ShowPar}
\Configure{caption}{\endparagraph\HCode{<span class="figure">}}{:\space}{}{\HCode{</span>}}
}{}{}{}

% Configure margin tables
\ConfigureEnv{margintable}{\endparagraph\HCode{<div class="margintable">}\Configure{caption}{}{:\space}{}{}}{\endparagraph\HCode{</div>}}{}{}

% Configure math display width to match tufte-css article width
\Css{div.math-display, div.par-math-display {width: 55\%}}

% Add custom stylesheet (loaded after tufte.css)
\Configure{AddCss}{lab-manual.css}

\makeatother

\begin{document}
\EndPreamble