diff --git a/README b/README deleted file mode 100644 index 023525b..0000000 --- a/README +++ /dev/null @@ -1,234 +0,0 @@ -================================ -=== CDSC LaTeX Templates ======= -================================ - -Copyright (c) 2009-2026 Benjamin Mako Hill / - -This repository contains LaTeX configuration files and templates used to -format papers, memos, letters, and posters. All files are released under -the GNU GPL version 3 or later. - -The latest version can be found in git at: -https://gitea.communitydata.science/collective/cdsc_tex - -You can check out the latest version with: - - git clone https://gitea.communitydata.science/collective/cdsc_tex.git - -Bug reports, comments, questions, and patches can be directed to: - - Benjamin Mako Hill [work] - Benjamin Mako Hill [personal] - -To submit a patch, clone the repository, make your changes, and use -git format-patch to generate patch files to send by email: - - git format-patch origin/master - git send-email *.patch - -================================ -=== Dependencies =============== -================================ - -On Debian or Ubuntu, install the following packages: - - * latexmk - * texlive-luatex - * texlive-latex-recommended - * texlive-fonts-extra - * texlive-fonts-recommended - * texlive-bibtex-extra - - apt install latexmk texlive-luatex texlive-latex-recommended \ - texlive-fonts-extra texlive-fonts-recommended \ - texlive-bibtex-extra - -On other systems, installing a full TeX Live distribution should provide -everything needed. - -All four templates build with LuaLaTeX (via latexmk -lualatex). The text -fonts are Libertinus Serif and TeX Gyre Heros, both provided by -texlive-fonts-extra. - -The paper, memo, and letter templates need TeX Live 2025 or later. The -tagging code they rely on is not in TeX Live 2024, where the build -stops with "the key 'document/metadata/tagging' is unknown". Debian -trixie ships TeX Live 2024, so a trixie machine needs a newer TeX Live -from elsewhere in the archive. On Overleaf, choose the TeX Live -version under Menu > Settings > TeX Live version; 2025 or later is -required and is not always the default for an older project. - -================================ -=== Accessibility ============== -================================ - -The paper, memo, and letter templates produce tagged PDFs that declare -PDF/UA-2 (ISO 14289-2). The poster template does not; see below. - -Tagging is switched on by the tagging=on key in the \DocumentMetadata -block at the top of each template. That key is what does the work: it -loads the kernel code that puts headings, paragraphs, lists, tables, -and figures into the PDF's structure tree, which is what a screen -reader walks. The neighbouring pdfstandard=ua-2 key only writes the -conformance claim into the file's metadata. Setting the standard -without setting tagging=on yields a PDF that announces itself as -accessible and contains nothing for assistive software to read, so -keep the two together. - -The paper and memo templates were originally built on the memoir -class, which is incompatible with the LaTeX tagged-PDF code. They now -use the standard article class with custom styling (cdsc-paper.sty -and cdsc-memo.sty) to keep their previous look while supporting full -tagging. - -Writing an accessible document ------------------------------- - -Tagging gets you the structure; the content is still up to the author. -Three things matter most, and the paper template carries a worked -example of each: - - * Use \section and \subsection for headings rather than setting type - in bold by hand. Screen reader users navigate by the heading tree, - and hand-formatted text is invisible to it. - - * Give every figure an alt= description on \includegraphics, saying - what the reader is meant to take from it. A decorative image takes - \includegraphics[artifact]{...} instead, keeping it out of the - reading order. - - * Mark header rows on data tables with \tagpdfsetup{table/header-rows - ={1}} so their cells become TH rather than TD. Without it a table - reads as an undifferentiated grid of values. - -Customizing the styles ----------------------- - -Some common packages defeat tagging, and the failure is usually -silent: the document compiles without complaint and the tags are -simply missing. Before adding a package, check its status against the -LaTeX Tagging Project's list: - - https://latex3.github.io/tagging-project/tagging-status/ - -titlesec and titling are the two to know about here, because they are -the obvious tools for the job cdsc-paper.sty and cdsc-memo.sty do. -titlesec replaces the \@startsection hook that the tagging code uses -to emit heading tags, so loading it produces a PDF with no headings in -the structure tree and no error to say so. Both style files therefore -build their headings and title blocks from the article class's own -\@startsection and \@maketitle hooks. - -Verifying ---------- - -Check a built PDF against the standard with veraPDF: - - verapdf -f ua2 text.pdf - -It prints PASS or FAIL for the file, and --format text will list the -clauses that failed. All four of the tagged templates pass as shipped, -so a FAIL means something in the document needs attention rather than -something in the template. - -Run it. A document that declares PDF/UA-2 and does not meet it is -worse than one that makes no claim, because the claim is what a reader -relying on assistive software will trust. The declaration costs one -line and validating it is the only thing that makes the line true. - -veraPDF is not packaged in Debian; download it from -https://verapdf.org/ and put it on your PATH. - -For a quicker look at whether a PDF carries any structure at all, -without checking conformance: - - python3 -c "import pikepdf,sys; d=pikepdf.open(sys.argv[1]); \ - print(d.Root.get('/StructTreeRoot') and 'tagged' or 'UNTAGGED')" file.pdf - -Posters -------- - -The poster template is not accessible and makes no accessibility -claim. The beamer class rejects \DocumentMetadata outright, and the -LaTeX Tagging Project lists beamer and beamerposter as no-support, -meaning incompatible and not expected to change. When a poster needs -an accessible version, build a companion document from the paper or -memo template. - -================================ -=== Branches =================== -================================ - -This repository has two main branches: - - master Standard LaTeX templates (paper, memo, letter, poster) - knitr Knitr/R template for reproducible research documents - -================================ -=== Scripts ==================== -================================ - -new_tex_document ----------------- -Creates a new document directory from a template. Takes a document type -and destination directory as arguments: - - new_tex_document - -Available types: - - paper LaTeX paper template (master branch) - memo LaTeX memo template (master branch) - knitr Knitr/R paper template (knitr branch) - letter LaTeX letter template (master branch) - -Example: - - new_tex_document paper my-new-paper - -This creates my-new-paper/ populated with the template files, with the -main source file renamed to my-new-paper.tex (or .Rtex for knitr). - -rename_tex_to_dirname ---------------------- -Renames the single .tex file in the current directory to match the -directory name. Useful for cleaning up a template that was set up -manually: - - cd my-paper && rename_tex_to_dirname - -================================ -=== Shell Aliases ============== -================================ - -The file cdsc_tex_aliases.sh provides aliases for the old individual -script names, for convenience or backwards compatibility. Add the -following to your .bashrc or .zshrc: - - [[ -f ~/tex/cdsc_tex/cdsc_tex_aliases.sh ]] && \ - source ~/tex/cdsc_tex/cdsc_tex_aliases.sh - -This defines the following aliases (only if new_tex_document is in PATH): - - new_tex_memo → new_tex_document memo - new_knitr_document → new_tex_document knitr - new_tex_letter → new_tex_document letter - -================================ -=== Migration ================== -================================ - -The individual scripts new_knitr_document and new_tex_letter have -been consolidated into new_tex_document. The old scripts remain in -the repository but are superseded. - -To migrate, replace calls to the old scripts with new_tex_document: - - Old: new_knitr_document mydir - New: new_tex_document knitr mydir - - Old: new_tex_letter mydir - New: new_tex_document letter mydir - -Alternatively, source cdsc_tex_aliases.sh (see above) to keep using the -old names without changing your workflow. diff --git a/README.md b/README.md new file mode 100644 index 0000000..3c68b03 --- /dev/null +++ b/README.md @@ -0,0 +1,221 @@ +# CDSC LaTeX Templates + +Copyright (c) 2009-2026 Benjamin Mako Hill / + +This repository contains LaTeX configuration files and templates used to +format papers, memos, letters, and posters. All files are released under +the GNU GPL version 3 or later. + +The latest version can be found +[in git](https://gitea.communitydata.science/collective/cdsc_tex). + +You can check out the latest version with: + +``` +git clone https://gitea.communitydata.science/collective/cdsc_tex.git +``` + +Bug reports, comments, questions, and patches can be directed to: + +* Benjamin Mako Hill [work] +* Benjamin Mako Hill [personal] + +To submit a patch, clone the repository, make your changes, and use +`git format-patch` to generate patch files to send by email: + +``` +git format-patch origin/master +git send-email *.patch +``` + + +## Dependencies + +On Debian or Ubuntu, install the following packages: + +* latexmk +* texlive-luatex +* texlive-latex-recommended +* texlive-fonts-extra +* texlive-fonts-recommended +* texlive-bibtex-extra + +``` +apt install latexmk texlive-luatex texlive-latex-recommended \ + texlive-fonts-extra texlive-fonts-recommended \ + texlive-bibtex-extra +``` + +On other systems, installing a full TeX Live distribution should provide +everything needed. + +All four templates build with LuaLaTeX (via `latexmk -lualatex`). The text +fonts are Libertinus Serif and TeX Gyre Heros, both provided by +texlive-fonts-extra. + +The tagging code requires TeX Live 2025 or later. On Overleaf, set the +version under Menu > Settings > TeX Live version. Debian Trixie ships +TeX Live 2024; sid (unstable) has TeX Live 2026, which also works and +installs without pulling in much else. + + +## Accessibility + +The paper, memo, and letter templates produce tagged PDFs that declare +PDF/UA-2 (ISO 14289-2). The poster template does not; see below. + +Two keys in the `\DocumentMetadata` block at the top of each template do +this, and both are needed: `tagging=on` loads the kernel code that puts +headings, paragraphs, lists, tables, and figures into the PDF's +structure tree, and `pdfstandard=ua-2` writes the conformance claim. + +The paper and memo templates were originally built on the memoir +class, which is incompatible with the LaTeX tagged-PDF code. They now +use the standard article class with custom styling (`cdsc-paper.sty` +and `cdsc-memo.sty`) to keep their previous look while supporting full +tagging. + +### Writing an accessible document + +Tagging gets you the structure; the content is still up to the author. +The paper template carries a worked example of each of these: + +* Use `\section` and `\subsection` for headings rather than setting type + in bold by hand. Screen reader users navigate by the heading tree. + +* Give every figure an `alt=` description on `\includegraphics`, saying + what the reader is meant to take from it. A decorative image takes + `\includegraphics[artifact]{...}` instead. + +* Mark header rows on data tables with + `\tagpdfsetup{table/header-rows={1}}` so their cells become TH rather + than TD. + +### Customizing the styles + +Some common packages defeat tagging, and the failure is silent: the +document compiles without complaint and the tags are simply missing. +Before adding a package, check it against the LaTeX Tagging Project's +[status list](https://latex3.github.io/tagging-project/tagging-status/). + +`titlesec` and `titling` are the two to know about, because they are the +obvious tools for the job `cdsc-paper.sty` and `cdsc-memo.sty` do. +`titlesec` replaces the `\@startsection` hook the tagging code uses to +emit heading tags, so loading it produces a PDF with no headings in +the structure tree. + +### Verifying + +You can check a built PDF with [veraPDF](https://verapdf.org/): + +``` +verapdf -f ua2 text.pdf +``` + +It prints PASS or FAIL, and `--format text` lists the failing clauses. +All three tagged templates pass as shipped, so a FAIL points at the +document rather than the template. + +Note that a PASS is necessary but not sufficient. A document whose +body text is all marked as artifact passes too, because the standard +only requires that content which is not real be an artifact. + +You can confirm there is something in the structure tree as well: + +``` +python3 -c "import pikepdf,sys; d=pikepdf.open(sys.argv[1]); \ + print(d.Root.get('/StructTreeRoot') and 'tagged' or 'UNTAGGED')" file.pdf +``` + +### Posters + +The poster template is not accessible and makes no accessibility +claim. The beamer class rejects `\DocumentMetadata` outright, and the +LaTeX Tagging Project lists beamer and beamerposter as no-support, +meaning incompatible and not expected to change. When a poster needs +an accessible version, build a companion document from the paper or +memo template. + + +## Branches + +This repository has two main branches: + +* `master` — Standard LaTeX templates (paper, memo, letter, poster) +* `knitr` — Knitr/R template for reproducible research documents + + +## Scripts + +### new_tex_document + +Creates a new document directory from a template. Takes a document type +and destination directory as arguments: + +``` +new_tex_document +``` + +Available types: + +* `paper` — LaTeX paper template (master branch) +* `memo` — LaTeX memo template (master branch) +* `knitr` — Knitr/R paper template (knitr branch) +* `letter` — LaTeX letter template (master branch) + +Example: + +``` +new_tex_document paper my-new-paper +``` + +This creates `my-new-paper/` populated with the template files, with the +main source file renamed to `my-new-paper.tex` (or `.Rtex` for knitr). + +### rename_tex_to_dirname + +Renames the single .tex file in the current directory to match the +directory name. Useful for cleaning up a template that was set up +manually: + +``` +cd my-paper && rename_tex_to_dirname +``` + + +## Shell Aliases + +The file `cdsc_tex_aliases.sh` provides aliases for the old individual +script names, for convenience or backwards compatibility. Add the +following to your `.bashrc` or `.zshrc`: + +``` +[[ -f ~/tex/cdsc_tex/cdsc_tex_aliases.sh ]] && \ + source ~/tex/cdsc_tex/cdsc_tex_aliases.sh +``` + +This defines the following aliases (only if `new_tex_document` is in PATH): + +* `new_tex_memo` → `new_tex_document memo` +* `new_knitr_document` → `new_tex_document knitr` +* `new_tex_letter` → `new_tex_document letter` + + +## Migration + +The individual scripts `new_knitr_document` and `new_tex_letter` have +been consolidated into `new_tex_document`. The old scripts remain in +the repository but are superseded. + +To migrate, replace calls to the old scripts with `new_tex_document`: + +``` +Old: new_knitr_document mydir +New: new_tex_document knitr mydir + +Old: new_tex_letter mydir +New: new_tex_document letter mydir +``` + +Alternatively, source `cdsc_tex_aliases.sh` (see above) to keep using the +old names without changing your workflow. diff --git a/letter_template/text.tex b/letter_template/text.tex index ccec5cf..fd72b4f 100644 --- a/letter_template/text.tex +++ b/letter_template/text.tex @@ -1,12 +1,4 @@ % Tagged PDF (PDF/UA-2) accessibility setup. -% -% tagging=on is what actually builds the structure tree: it loads the -% kernel code that tags paragraphs, headings, lists, tables, and -% floats. Declaring pdfstandard=ua-2 on its own only writes the claim -% into the metadata; without tagging=on the PDF is marked as UA-2 but -% carries no structure for a screen reader to read. This needs TeX -% Live 2025 or later --- on Overleaf, set it in Menu > Settings > -% TeX Live version. \DocumentMetadata{ tagging=on, pdfversion=2.0, diff --git a/memo_template/cdsc-memo.sty b/memo_template/cdsc-memo.sty index 0332b9e..dc2290c 100644 --- a/memo_template/cdsc-memo.sty +++ b/memo_template/cdsc-memo.sty @@ -8,12 +8,8 @@ % line, sans-serif uppercase section headings, no paragraph indent, % and a small-caps "page/total" footer. % -% Headings come from the article class's own \@startsection hook -% rather than from titlesec. The tagging code hooks into -% \@startsection to emit the H1, H2, and H3 tags a screen reader -% navigates by; titlesec bypasses that hook, so loading it silently -% produces a PDF with no headings in the structure tree. See the -% Accessibility section of the README. +% Headings use the class's own \@startsection hook, not titlesec, +% which breaks tagging. See the Customizing section of the README. % % Copyright 2009-2026 Benjamin Mako Hill % Copyright 2008-2009 Kieran Healy @@ -43,15 +39,9 @@ \pagestyle{cdsc-page-memo} -%%% Section headings: sans-serif bold uppercase, with the tight -%%% before/after spacing the original memo style used. -%%% -%%% \@startsection takes {name}{level}{indent}{beforeskip}{afterskip} -%%% {style}. The style argument is applied to the whole heading as an -%%% argument, so \MakeUppercase can be appended to it; the tagging -%%% code wraps the section number in \NoCaseChange so the number is -%%% left alone. A negative afterskip makes a heading run in to the -%%% paragraph that follows it. +%%% Section headings: sans-serif bold uppercase. \@startsection applies +%%% the style argument to the whole heading, so \MakeUppercase can be +%%% appended; the tagging code wraps the number in \NoCaseChange. \makeatletter diff --git a/memo_template/text.tex b/memo_template/text.tex index 9fbe5c7..841608c 100644 --- a/memo_template/text.tex +++ b/memo_template/text.tex @@ -1,14 +1,4 @@ -% Tagged PDF (PDF/UA-2) accessibility setup. The article class works -% with the LaTeX tagging project, so we use the full \DocumentMetadata -% path here. -% -% tagging=on is what actually builds the structure tree: it loads the -% kernel code that tags paragraphs, headings, lists, tables, and -% floats. Declaring pdfstandard=ua-2 on its own only writes the claim -% into the metadata; without tagging=on the PDF is marked as UA-2 but -% carries no structure for a screen reader to read. This needs TeX -% Live 2025 or later --- on Overleaf, set it in Menu > Settings > -% TeX Live version. +% Tagged PDF (PDF/UA-2) accessibility setup. \DocumentMetadata{ tagging=on, pdfversion=2.0, diff --git a/paper_template/cdsc-paper.sty b/paper_template/cdsc-paper.sty index ee532e0..5e0df13 100644 --- a/paper_template/cdsc-paper.sty +++ b/paper_template/cdsc-paper.sty @@ -6,12 +6,9 @@ % that work. The look-and-feel is kept as close to the previous % cdsc-article chapterstyle as is practical. % -% Headings and the title block are built from the article class's own -% \@startsection and \@maketitle hooks rather than from titlesec and -% titling. The tagging code hooks into \@startsection to emit the H1, -% H2, and H3 tags a screen reader navigates by; titlesec bypasses that -% hook, so loading it silently produces a PDF with no headings in the -% structure tree. See the Accessibility section of the README. +% Headings and the title block use the class's own \@startsection and +% \@maketitle hooks, not titlesec and titling, which break tagging. +% See the Customizing section of the README. % % Copyright 2009-2026 Benjamin Mako Hill % Copyright 2008-2009 Kieran Healy @@ -50,15 +47,9 @@ \pagestyle{cdsc-page} -%%% Section heading styles. -%%% -%%% Each heading is declared through \@startsection, which takes: -%%% {name}{level}{indent}{beforeskip}{afterskip}{style} -%%% A negative beforeskip suppresses the paragraph indent that would -%%% otherwise follow the heading; a negative afterskip makes the -%%% heading run into the paragraph text rather than sit on its own -%%% line. The style argument receives the whole heading as its -%%% argument, so a case-changing command may be appended to it. +%%% Section headings. \@startsection takes {name}{level}{indent} +%%% {beforeskip}{afterskip}{style}; a negative afterskip runs the +%%% heading in to the following paragraph. \makeatletter @@ -75,7 +66,6 @@ {\normalsize\itshape}} % Subsubsections: small bold, run in to the following paragraph -% (the negative afterskip is what makes it run in) \renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}% {-3.25ex \@plus -1ex \@minus -.2ex}% {-0.5em}% @@ -99,14 +89,9 @@ \newcommand{\puB}{} \newcommand{\published}[1]{\gdef\puB{#1}} -% \raggedright rather than \flushleft: the flushleft environment is a -% trivlist, and starting one as a bare declaration leaves a list open -% in the structure tree. That produces "the number of automatic begin -% and end text-unit para hooks differ" and a mis-nested PDF. -% The vertical skips reproduce what titling's \pretitle/\posttitle, -% \preauthor/\postauthor, and \predate/\postdate produced. The date -% slot keeps its space even when \date{} is empty, which is what the -% previous title block did and what the template's spacing assumes. +% \raggedright, not \flushleft: flushleft is a trivlist and would leave +% a list open in the structure tree. The skips match titling's output; +% the date slot keeps its space even when \date{} is empty. \renewcommand{\@maketitle}{% \null \vskip 2em% diff --git a/paper_template/text.Rtex b/paper_template/text.Rtex index 8335334..3c2b6d8 100644 --- a/paper_template/text.Rtex +++ b/paper_template/text.Rtex @@ -1,14 +1,4 @@ -% Tagged PDF (PDF/UA-2) accessibility setup. The article class works -% with the LaTeX tagging project, so we use the full \DocumentMetadata -% path here. -% -% tagging=on is what actually builds the structure tree: it loads the -% kernel code that tags paragraphs, headings, lists, tables, and -% floats. Declaring pdfstandard=ua-2 on its own only writes the claim -% into the metadata; without tagging=on the PDF is marked as UA-2 but -% carries no structure for a screen reader to read. This needs TeX -% Live 2025 or later --- on Overleaf, set it in Menu > Settings > -% TeX Live version. +% Tagged PDF (PDF/UA-2) accessibility setup. \DocumentMetadata{ tagging=on, pdfversion=2.0, @@ -163,13 +153,8 @@ brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog \citep{989866}. -% ACCESSIBILITY: header-rows tells the tagging code which rows are -% headers, so their cells become TH rather than TD and a screen reader -% can announce which column a value belongs to. Without it, a table -% reads as an undifferentiated grid of numbers. kable puts the column -% names in a single header row, so {1} is right for the table below; -% use {1,2} where two rows are headers. Set it for each table, since -% it applies to the tables that follow it. +% header-rows makes the first row TH rather than TD. kable emits the +% column names as a single header row, so {1} is right here. \tagpdfsetup{table/header-rows={1}} \begin{table} \centering @@ -198,24 +183,23 @@ fox jumps over the lazy dog \citep{989866}. \section{Accessible Figures and Tables} -Table~\ref{tab:test} above is tagged with a header row. Figures need -alt text, which is what a screen reader announces in place of the -image. Describe what the reader is meant to take from the figure -rather than naming it: "Edit counts rising sharply after 2005" tells -them something, "Figure 1" does not. The caption is read separately, -so alt text that repeats it is wasted. These are worked examples; -delete this section when you start writing. +Table~\ref{tab:test} above is tagged with a header row, and the +commented-out block below shows a figure carrying alt text. Both are +here as worked examples; delete them along with this section when you +start writing. -% For a figure generated by a chunk, knitr passes the fig.alt option -% through to the \includegraphics call it writes: +% alt= is what a screen reader announces in place of the image. Say what +% the reader should take from it, not what it is called. A decorative +% image takes [artifact] instead, keeping it out of the reading order. % -% <>= +% For a chunk-generated figure, knitr passes fig.alt through to the +% \includegraphics call it writes: +% +% <>= % plot(year, edits) % @ % -% For a figure included from a file, put alt= on \includegraphics -% directly. A purely decorative image takes [artifact] instead, which -% keeps it out of the reading order entirely: +% For a figure included from a file, put alt= on \includegraphics: % % \begin{figure} % \centering @@ -225,9 +209,8 @@ delete this section when you start writing. % \label{fig:example} % \end{figure} -% A table used only to position things on the page, rather than to -% present data, should be marked so assistive software skips its -% structure: \tagpdfsetup{table/tagging=presentation} +% A layout table, used to position rather than present, takes +% \tagpdfsetup{table/tagging=presentation} % bibliography here \setcounter{biburlnumpenalty}{9001} diff --git a/poster_template/main.tex b/poster_template/main.tex index 6c549f6..e4ec7e8 100644 --- a/poster_template/main.tex +++ b/poster_template/main.tex @@ -1,15 +1,6 @@ -% ACCESSIBILITY: this poster is not a tagged PDF. The beamer class -% rejects \DocumentMetadata outright ("Class beamer Error: The beamer -% class is not compatible with \DocumentMetadata"), and the LaTeX -% Tagging Project lists both beamer and beamerposter as no-support, -% meaning incompatible and not expected to change. beamerposter also -% pulls in textpos and subfig, which are incompatible in their own -% right. -% -% There is no way to make this template produce an accessible PDF -% today. Rather than declare PDF/UA-2 and ship an untagged file, it -% makes no claim at all. If a poster has to be accessible, supply a -% tagged companion document built from the paper or memo template. +% Not a tagged PDF: beamer rejects \DocumentMetadata, and the LaTeX +% Tagging Project lists beamer and beamerposter as no-support. See the +% Posters section of the README. \documentclass[xcolor=dvipsnames, 12pt]{beamer} \usepackage[size=custom, width=114, height=80, scale=1.5]{beamerposter}