$document-metadata.latex()$ $passoptions.latex()$ \documentclass[ $for(babel-otherlangs)$ $babel-otherlangs$, $endfor$ $if(babel-lang)$ $babel-lang$, $endif$ $if(fontsize)$ $fontsize$, $endif$ $if(papersize)$ $papersize$paper, $endif$ $for(classoption)$ $classoption$$sep$, $endfor$ ]{$documentclass$} $if(beamerarticle)$ \usepackage{beamerarticle} % needs to be loaded first $endif$ \usepackage{xcolor} $if(geometry)$ \usepackage[$for(geometry)$$geometry$$sep$,$endfor$]{geometry} $else$ \usepackage[left=2.8cm,right=2.8cm,top=3.2cm,bottom=3.2cm,headheight=14pt]{geometry} $endif$ \usepackage{amsmath,amssymb} $if(cancel)$ \usepackage{cancel} $endif$ %% Pandoc loads these conditionally (only when the document contains code %% blocks or tables), but this template's custom styling below uses their %% macros unconditionally — \DefineVerbatimEnvironment (fancyvrb) and %% \heavyrulewidth (booktabs). Load them up front so a document WITHOUT code %% or tables doesn't crash with "Undefined control sequence". All ship with %% BasicTeX/TinyTeX, and \usepackage is idempotent so pandoc re-requesting %% them later is a no-op. \usepackage{fancyvrb} \usepackage{longtable} \usepackage{booktabs} \usepackage{array} %% ══════════════════════════════════════════════════════════════════════════ %% Modern Styling (base LaTeX only — no extra packages required) %% ══════════════════════════════════════════════════════════════════════════ %% Load fontspec early. The actual font selection happens further down, AFTER %% pandoc's common partial is included, because that partial loads lmodern which %% would otherwise reset our font families to Latin Modern. \usepackage{fontspec} %% Accent colours (xcolor already loaded above) \definecolor{accent}{HTML}{4682B4} \definecolor{headingone}{HTML}{B83A4A} \definecolor{headingtwo}{HTML}{891401} \definecolor{headingthree}{HTML}{AC3600} \definecolor{muted}{HTML}{718096} \definecolor{rulecol}{HTML}{CBD5E0} %% Code colours: a soft fill for the code background, an accent stripe on the %% left, and a faint tint for inline \texttt. The Highlighting environment uses %% fancyvrb's per-line formatting hook to paint each line — page-breakable, with %% no `framed` / `mdframed` / `tcolorbox` dependency. \definecolor{shadecolor}{HTML}{F4F4F8} % soft neutral grey for code background \definecolor{codeborder}{HTML}{B0C4DE} % light steel blue for the left stripe \definecolor{inlinecodebg}{HTML}{F0F0F5} % background tint for inline code %% Inline code: give \texttt a faint rounded background. \let\oldtexttt\texttt \renewcommand{\texttt}[1]{{\setlength{\fboxsep}{1.5pt}\colorbox{inlinecodebg}{\oldtexttt{#1}}}} %% Paragraph spacing instead of indent \setlength{\parindent}{0pt} \setlength{\parskip}{6pt plus 2pt minus 1pt} %% Heading colours via @startsection (no titlesec needed) \makeatletter \renewcommand\section{\@startsection{section}{1}{\z@}% {-1.8em \@plus -0.5ex \@minus -0.2ex}% {0.6em \@plus 0.2ex}% {\Large\bfseries\color{headingone}}} \renewcommand\subsection{\@startsection{subsection}{2}{\z@}% {-1.3em \@plus -0.4ex \@minus -0.2ex}% {0.4em \@plus 0.2ex}% {\large\bfseries\color{headingtwo}}} \renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}% {-1em \@plus -0.3ex \@minus -0.2ex}% {0.2em \@plus 0.1ex}% {\normalsize\bfseries\color{headingthree}}} %% Title block (no titling package needed) \renewcommand{\maketitle}{% \begin{center}% \vspace*{0.5em}% {\Huge\bfseries\@title\par}% \vspace{0.4em}% {\color{accent}\rule{0.25\linewidth}{2pt}\par}% \vspace{0.3em}% {\large\color{muted}\@author\par}% {\small\color{muted}\@date\par}% \vspace{0.5em}% \end{center}% } \makeatother %% Header & footer (fancyhdr ships with BasicTeX) \usepackage{fancyhdr} \pagestyle{fancy} \fancyhf{} \renewcommand{\headrulewidth}{0.4pt} $if(title)$ \fancyhead[L]{\small\color{muted}\textit{$title$}} $endif$ \fancyhead[R]{\small\color{muted}\thepage} \fancypagestyle{plain}{% \fancyhf{}% \renewcommand{\headrulewidth}{0pt}% \fancyfoot[C]{\small\color{muted}\thepage}% } %% ══════════════════════════════════════════════════════════════════════════ $-- $-- section numbering $-- $if(numbersections)$ \setcounter{secnumdepth}{$if(secnumdepth)$$secnumdepth$$else$5$endif$} $else$ \setcounter{secnumdepth}{-\maxdimen} % remove section numbering $endif$ $fonts.latex()$ $font-settings.latex()$ %% Pandoc's syntax-highlighting macros load the `framed` package, which is NOT %% part of BasicTeX/TinyTeX. Pretend framed is already loaded so the \usepackage %% becomes a no-op; we replace its `snugshade` env with a fancyvrb-based version %% that needs nothing beyond what BasicTeX ships. Keeps the template fully self- %% contained — no extra packages to install. \IfFileExists{framed.sty}{}{% \expandafter\def\csname ver@framed.sty\endcsname{0000/00/00 v0 stub}% } $common.latex()$ %% ── System-font cascade (must come after common.latex's \usepackage{lmodern}) ── %% Each role tries a designed-for-screen font first, falling back through fonts %% guaranteed preinstalled on macOS or Windows. If nothing matches, fontspec %% keeps Latin Modern — no error, just a less polished look. $if(mainfont)$ $else$ %% Body font — modern humanist sans. Mapping=tex-text lets fontspec substitute %% glyphs the font lacks (e.g. → arrows in Charter) from the math font. %% Avenir Next (macOS) → Calibri (Windows) → Helvetica Neue (macOS) %% → Helvetica (macOS) → Arial (both) \IfFontExistsTF{Avenir Next}{% \setmainfont{Avenir Next}[Ligatures=TeX,Mapping=tex-text]% }{\IfFontExistsTF{Calibri}{% \setmainfont{Calibri}[Ligatures=TeX,Mapping=tex-text]% }{\IfFontExistsTF{Helvetica Neue}{% \setmainfont{Helvetica Neue}[Ligatures=TeX,Mapping=tex-text]% }{\IfFontExistsTF{Helvetica}{% \setmainfont{Helvetica}[Ligatures=TeX,Mapping=tex-text]% }{\IfFontExistsTF{Arial}{% \setmainfont{Arial}[Ligatures=TeX,Mapping=tex-text]% }{}}}}} %% Sans family — set the same as the main font so \sffamily and headings stay %% consistent. (We deliberately do NOT set \setromanfont, because in fontspec %% it's an alias for \setmainfont and would overwrite our body font.) \IfFontExistsTF{Avenir Next}{% \setsansfont{Avenir Next}[Ligatures=TeX,Mapping=tex-text]% }{\IfFontExistsTF{Calibri}{% \setsansfont{Calibri}[Ligatures=TeX,Mapping=tex-text]% }{\IfFontExistsTF{Helvetica Neue}{% \setsansfont{Helvetica Neue}[Ligatures=TeX,Mapping=tex-text]% }{\IfFontExistsTF{Helvetica}{% \setsansfont{Helvetica}[Ligatures=TeX,Mapping=tex-text]% }{\IfFontExistsTF{Arial}{% \setsansfont{Arial}[Ligatures=TeX,Mapping=tex-text]% }{}}}}} %% Glyph fallback: humanist sans body fonts often lack arrows. Route them to %% a font that has them so they render instead of as the .notdef glyph (?). %% Apple Symbols ships with macOS; on Windows, Segoe UI Symbol covers them. \IfFontExistsTF{Apple Symbols}{% \newfontfamily{\symbolFallback}{Apple Symbols}% \def\useSymbolFallback{1}% }{\IfFontExistsTF{Segoe UI Symbol}{% \newfontfamily{\symbolFallback}{Segoe UI Symbol}% \def\useSymbolFallback{1}% }{}} \ifdefined\useSymbolFallback \catcode`\→=\active \def→{{\symbolFallback\char"2192}}% \catcode`\←=\active \def←{{\symbolFallback\char"2190}}% \catcode`\↑=\active \def↑{{\symbolFallback\char"2191}}% \catcode`\↓=\active \def↓{{\symbolFallback\char"2193}}% \catcode`\⇒=\active \def⇒{{\symbolFallback\char"21D2}}% \catcode`\⇐=\active \def⇐{{\symbolFallback\char"21D0}}% \fi $endif$ $if(monofont)$ $else$ %% Mono cascade — MatchLowercase aligns x-heights with the body font: %% SF Mono (macOS) → Menlo (macOS) → Cascadia Code (Win 11) %% → Consolas (Windows) → Courier New (both) \IfFontExistsTF{SF Mono}{% \setmonofont{SF Mono}[Scale=MatchLowercase]% }{\IfFontExistsTF{Menlo}{% \setmonofont{Menlo}[Scale=MatchLowercase]% }{\IfFontExistsTF{Cascadia Code}{% \setmonofont{Cascadia Code}[Scale=MatchLowercase]% }{\IfFontExistsTF{Consolas}{% \setmonofont{Consolas}[Scale=MatchLowercase]% }{\IfFontExistsTF{Courier New}{% \setmonofont{Courier New}[Scale=MatchLowercase]% }{}}}}} $endif$ %% ── Code-block styling (no external dependencies) ── %% Pandoc wraps highlighted code as \begin{Shaded}\begin{Highlighting}… %% \end{Highlighting}\end{Shaded}, where Highlighting is a fancyvrb Verbatim %% (fancyvrb ships with BasicTeX). We redefine \FancyVerbFormatLine so each line %% is painted with a \colorbox — this gives a true page-breakable background %% without needing framed/mdframed/tcolorbox. The left accent stripe is layered %% on via fancyvrb's frame=leftline. \DefineVerbatimEnvironment{Highlighting}{Verbatim}{% commandchars=\\\{\},% frame=leftline,% framerule=2.5pt,% rulecolor=\color{codeborder},% framesep=8pt,% xleftmargin=2pt,% fontsize=\small,% formatcom=\HighlightingFormatLine% } %% Per-line background: each line is wrapped in a \colorbox so the fill flows %% across page breaks. Setting \fboxsep=0pt eliminates the vertical gap between %% adjacent boxes; a stretched \strut gives the line its full height so the %% boxes touch and form a continuous fill. \newcommand{\HighlightingFormatLine}{% \setlength{\fboxsep}{0pt}% \def\FancyVerbFormatLine##1{% \colorbox{shadecolor}{% \makebox[\dimexpr\linewidth-12pt][l]{\rule[-3pt]{0pt}{14pt}\hspace{6pt}##1\hspace{6pt}}% }% }% } %% pandoc only defines the Shaded environment via common.latex when the %% document actually contains highlighted code. For a document without code %% blocks it never exists, so \renewenvironment would fail with "Environment %% Shaded undefined". Define-or-redefine: create it if absent, otherwise renew. \makeatletter \@ifundefined{Shaded}{% \newenvironment{Shaded}{\par\vspace{4pt}}{\par\vspace{4pt}}% }{% \renewenvironment{Shaded}{\par\vspace{4pt}}{\par\vspace{4pt}}% } \makeatother %% ── Better horizontal divider ── %% Pandoc emits HRs as \begin{center}\rule{0.5\linewidth}{0.5pt}\end{center}. %% Redefining \rule globally would affect other uses, so we patch it only when it %% looks like pandoc's HR signature by wrapping in a smarter macro. \let\pandocOriginalRule\rule \renewcommand{\rule}[3][0pt]{% \ifdim#2=0.5\linewidth\relax {\centering \color{rulecol}\pandocOriginalRule[#1]{0.18\linewidth}{0.6pt}% \hspace{0.6em}\raisebox{-0.18ex}{\textcolor{accent}{\ensuremath{\bullet}}}\hspace{0.6em}% \color{rulecol}\pandocOriginalRule[#1]{0.18\linewidth}{0.6pt}\par}% \else \pandocOriginalRule[#1]{#2}{#3}% \fi } %% ── Table styling ── %% Editorial style: generous padding, dark-grey booktabs rules, light-grey %% header row fill. Everything used is in BasicTeX (longtable, booktabs, %% array, etoolbox, colortbl). \usepackage{etoolbox} \usepackage{colortbl} % for \arrayrulecolor / \rowcolor \definecolor{tableRule}{HTML}{4A5568} % dark grey for booktabs rules \definecolor{tableHeaderBg}{HTML}{F3F4F6} % very light grey for header row fill \arrayrulecolor{tableRule} \renewcommand{\arraystretch}{1.5} % taller rows for breathing room \setlength{\tabcolsep}{12pt} % generous horizontal padding \setlength{\heavyrulewidth}{1pt} % top/bottom rule weight \setlength{\lightrulewidth}{0.5pt} % midrule weight %% Header-row background — asymmetric per-cell overhang. %% \rowcolor applies the same per-cell overhang to every cell, so a single %% call can't both fill the 2*\tabcolsep inter-column gaps (needs \tabcolsep %% on each side) AND keep the outer edges flush with the booktabs rules %% (needs 0pt on the outer side). We solve it by letting \rowcolor handle %% interior cells with its default \tabcolsep overhang and injecting a %% \columncolor on the first and last columns of pandoc's column spec to %% override their outer overhang to 0pt. %% %% \columncolor is a delimiter token recognised by array's preamble parser %% — it must appear literally in the column spec, not be expanded from a %% wrapper macro at cell time. To make the column color conditional on %% "header vs body row", we point \columncolor at a named colour that's %% \colorlet-rebound by \toprule (to tableHeaderBg) and \midrule (back to %% white). Body-row columns then paint white-on-white — invisible. \colorlet{pdctmplDynColor}{white} %% Rewrite pandoc's longtable column spec: wrap the first column with %% >{\columncolor{pdctmplDynColor}[0pt][\tabcolsep]} and the last column %% with >{\columncolor{pdctmplDynColor}[\tabcolsep][0pt]}. Handles both %% simple `l`/`c`/`r` columns and `>{...}p{...}` columns (with one level of %% nested braces, which is what pandoc emits for %% `(\columnwidth - 2\tabcolsep) * \real{0.5}` widths). If the spec doesn't %% match the expected pattern the regex is a no-op and the original spec %% passes through unchanged. %% Inner padding for outer columns. The column spec ends with `@{}` to keep %% the booktabs rules flush with the table edge, which suppresses the outer %% \tabcolsep gap that would otherwise pad cell content from the rule ends. %% Two cases to handle: %% %% 1. Plain `l/c/r` cells (basic tables, body of aligned tables): \hspace* in %% the column's >{}/<{} hooks pushes content inward. %% 2. Pandoc's aligned-column headers wrap content in %% \begin{minipage}[b]{\linewidth}, which fills the entire (fixed) column %% width. \hspace* outside the minipage gets pushed past the rule end. %% Fix: shrink \linewidth inside such minipages so the column's >{}/<{} %% \hspace* sits visibly inside the rules. Done by patching \minipage to %% subtract 2*pad from its width arg whenever it sees \linewidth. \newlength{\pdctmplPadAmt} \setlength{\pdctmplPadAmt}{8pt} \newcommand{\pdctmplPadL}{\hspace*{\pdctmplPadAmt}} \newcommand{\pdctmplPadR}{\hspace*{\pdctmplPadAmt}} %% Patch \minipage: when called inside a longtable cell with width \linewidth %% (pandoc's pattern for aligned-header cells), shrink the width by 2*pad so %% the surrounding \pdctmplPadL/\pdctmplPadR fit between the minipage and the %% rule ends. The \pdctmplInTable flag, set/cleared by \longtable, scopes the %% patch so other minipages in the document are unaffected. \newif\ifpdctmplInTable \pdctmplInTablefalse \let\pdctmplOrigMinipage\minipage \renewcommand{\minipage}[2][c]{% \ifpdctmplInTable \pdctmplOrigMinipage[#1]{\dimexpr#2-2\pdctmplPadAmt\relax}% \else \pdctmplOrigMinipage[#1]{#2}% \fi } %% Pandoc may also wrap cells in \multicolumn{1}{}{...}, which bypasses %% the column spec's >{}/<{} hooks. Patch \multicolumn so single-column cells %% get the inner padding too. \let\pdctmplOrigMulticolumn\multicolumn \renewcommand{\multicolumn}[3]{\pdctmplOrigMulticolumn{#1}{#2}{\pdctmplPadL #3\pdctmplPadR}} \ExplSyntaxOn \tl_new:N \pdctmplStoredColspec \cs_new_protected:Npn \pdctmpl_rewrite_colspec:n #1 { \tl_set:Nn \l_tmpa_tl {#1} \regex_replace_once:nnN { \A \s* @ \cB. \cE. \s* } { } \l_tmpa_tl \regex_replace_once:nnN { \s* @ \cB. \cE. \s* \Z } { } \l_tmpa_tl \regex_replace_once:nnN { ( (?: > \cB. [^\cB.\cE.]* \cE. \s* )? (?: [lcr] | p \cB. [^\cB.\cE.]* (?: \cB. [^\cB.\cE.]* \cE. [^\cB.\cE.]* )* \cE. ) ) \s* \Z } { > \cB. \c{columncolor} \cB. pdctmplDynColor \cE. [\c{tabcolsep}] [0pt] \cE. \1 < \cB. \c{pdctmplPadR} \cE. } \l_tmpa_tl \tl_put_left:Nn \l_tmpa_tl { @{} > { \columncolor { pdctmplDynColor } [0pt] [\tabcolsep] \pdctmplPadL } } \tl_put_right:Nn \l_tmpa_tl { @{} } \tl_gset_eq:NN \pdctmplStoredColspec \l_tmpa_tl } \cs_new_eq:NN \pdctmplRewriteColspec \pdctmpl_rewrite_colspec:n \ExplSyntaxOff \let\pdctmplOrigLongtable\longtable \renewcommand{\longtable}[2][]{% \pdctmplRewriteColspec{#2}% \edef\pdctmplDoLongtable{% \noexpand\pdctmplOrigLongtable[\unexpanded{#1}]% {\unexpanded\expandafter{\pdctmplStoredColspec}}% }% \pdctmplDoLongtable% } %% \toprule rebinds pdctmplDynColor to tableHeaderBg and emits \rowcolor %% (which paints the interior cells with default \tabcolsep overhang); %% \midrule rebinds it back to white so body rows paint invisibly. \let\origtoprule\toprule \renewcommand{\toprule}{% \origtoprule[0.3pt]% \noalign{\global\colorlet{pdctmplDynColor}{tableHeaderBg}}% \rowcolor{tableHeaderBg}% } \let\origmidrule\midrule \renewcommand{\midrule}{% \noalign{\global\colorlet{pdctmplDynColor}{white}}% \origmidrule[0.3pt]% } %% Thinner bottom rule — booktabs' \bottomrule takes an optional width argument %% that overrides \heavyrulewidth for that one rule. Use it to render the %% bottom edge at 0.3pt while \toprule keeps the 1pt anchor on the header. \let\origbottomrule\bottomrule \renewcommand{\bottomrule}{\origbottomrule[0.3pt]} %% Tables sit left-aligned at the text margin with a touch of vertical air %% above and below. We intentionally do NOT force full-width via %% \extracolsep{\fill} — with only two columns it pushes the second column to %% the page edge, looking unbalanced. Letting tables size to their content %% renders better for typical markdown tables. \AtBeginEnvironment{longtable}{% \pdctmplInTabletrue% \setlength{\LTleft}{0pt}% \setlength{\LTright}{\fill}% \setlength{\LTpre}{8pt}% \setlength{\LTpost}{8pt}% \arrayrulecolor{tableRule}% } $for(header-includes)$ $header-includes$ $endfor$ $after-header-includes.latex()$ $hypersetup.latex()$ %% Default coloured hyperlinks (overridable via YAML colorlinks/linkcolor) $if(colorlinks)$ $else$ \hypersetup{colorlinks=true,linkcolor=accent,urlcolor=accent,citecolor=accent,filecolor=accent} $endif$ $if(pdf-trailer-id)$ \ifXeTeX \special{pdf:trailerid [ $pdf-trailer-id$ ]} \fi \ifPDFTeX \pdftrailerid{} \pdftrailer{/ID [ $pdf-trailer-id$ ]} \fi \ifLuaTeX \pdfvariable trailerid {[ $pdf-trailer-id$ ]} \fi $endif$ $if(title)$ \title{$title$$if(thanks)$\thanks{$thanks$}$endif$} $endif$ $if(subtitle)$ \usepackage{etoolbox} \makeatletter \providecommand{\subtitle}[1]{% add subtitle to \maketitle \apptocmd{\@title}{\par {\large #1 \par}}{}{} } \makeatother \subtitle{$subtitle$} $endif$ \author{$for(author)$$author$$sep$ \and $endfor$} \date{$date$} \begin{document} $if(has-frontmatter)$ \frontmatter $endif$ $if(title)$ \maketitle $if(abstract)$ \begin{abstract} $abstract$ \end{abstract} $endif$ $endif$ $for(include-before)$ $include-before$ $endfor$ $if(toc)$ $if(toc-title)$ \renewcommand*\contentsname{$toc-title$} $endif$ { $if(colorlinks)$ $if(toccolor)$ \hypersetup{linkcolor=$toccolor$} $endif$ $endif$ \setcounter{tocdepth}{$toc-depth$} \tableofcontents } $endif$ $if(lof)$ \listoffigures $endif$ $if(lot)$ \listoftables $endif$ $if(linestretch)$ \setstretch{$linestretch$} $endif$ $if(has-frontmatter)$ \mainmatter $endif$ $body$ $if(has-frontmatter)$ \backmatter $endif$ $if(nocite-ids)$ \nocite{$for(nocite-ids)$$it$$sep$, $endfor$} $endif$ $if(natbib)$ $if(bibliography)$ $if(biblio-title)$ $if(has-chapters)$ \renewcommand\bibname{$biblio-title$} $else$ \renewcommand\refname{$biblio-title$} $endif$ $endif$ \bibliography{$for(bibliography)$$bibliography$$sep$,$endfor$} $endif$ $endif$ $if(biblatex)$ \printbibliography$if(biblio-title)$[title=$biblio-title$]$endif$ $endif$ $for(include-after)$ $include-after$ $endfor$ \end{document}