From 9c473a84193351fc4cdb42e061517deaf30efbec Mon Sep 17 00:00:00 2001 From: Benjamin Mako Hill Date: Thu, 13 Aug 2026 19:11:51 -0700 Subject: [PATCH] Vendor the trantor theme for ltx-talk trantor is Marco Pompili's Metropolis-like theme for ltx-talk, added under its MIT license so the deck keeps roughly its present look after the class change. Two things differ from upstream: font selection moves out to the document, since this template ships OpenSans and RobotoMono, and the Euler maths font it loaded by default is dropped because lum-euler is not packaged in Debian's TeX Live. Upstream: https://github.com/mrc-pop/trantor Co-Authored-By: Claude Opus 5 (1M context) --- slides_template/LICENSE.trantor | 21 +++ slides_template/trantor.sty | 247 ++++++++++++++++++++++++++++++++ 2 files changed, 268 insertions(+) create mode 100644 slides_template/LICENSE.trantor create mode 100644 slides_template/trantor.sty diff --git a/slides_template/LICENSE.trantor b/slides_template/LICENSE.trantor new file mode 100644 index 0000000..c6d3b2e --- /dev/null +++ b/slides_template/LICENSE.trantor @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Marco Pompili + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/slides_template/trantor.sty b/slides_template/trantor.sty new file mode 100644 index 0000000..990a03b --- /dev/null +++ b/slides_template/trantor.sty @@ -0,0 +1,247 @@ +% trantor.sty -- a Metropolis-style theme for the ltx-talk class. +% LuaLaTeX only. Fonts: Libertinus Serif/Sans (text) + Euler (maths). +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{trantor}[2026-08-01 v1.0 Metropolis-like theme for ltx-talk] + +% LuaTeX only (XeTeX is unsupported and the fonts need a Unicode engine). +\RequirePackage{iftex} +\RequireLuaTeX +\RequirePackage{tikz} +\RequirePackage{pifont} + +% -- Fonts. Upstream sets Libertinus here and loads lum-euler for maths. +% Both are left to the document instead: this template ships OpenSans and +% RobotoMono, and lum-euler is not packaged in Debian's TeX Live. The document +% is expected to \setsansfont, \setmonofont and load a Unicode maths font +% before using anything below. \headerfont is what the theme uses for titles +% and other display text; redefine it if you want titles in a second face. +\renewcommand{\familydefault}{\sfdefault} +\linespread{1.18} +\providecommand\headerfont{\sffamily} +\makeatletter + +% Tighten the space around display maths -- the default 11pt reads as a big gap +% on a slide, especially inside a list. Re-applied on every \normalsize so the +% size files don't reset it. +\g@addto@macro\normalsize{% + \setlength\abovedisplayskip{5pt plus 2pt minus 1pt}% + \setlength\belowdisplayskip{5pt plus 2pt minus 1pt}% + \setlength\abovedisplayshortskip{5pt plus 2pt minus 1pt}% + \setlength\belowdisplayshortskip{5pt plus 2pt minus 1pt}% +} + +% -- Colours. Set your own accent anywhere in the preamble with, e.g., +% \definecolor{accent}{HTML}{BF1238} +\providecolor{accent}{HTML}{2A7AE2} +\colorlet{TrantorDark}{black} +% Lightest grey that still meets WCAG AA contrast (4.5:1) on white (~4.54:1). +\definecolor{TrantorMuted}{HTML}{767676} % affiliation, footline, arxiv +\AddToHook{begindocument}{\colorlet{TrantorAccent}{accent}} + +% itemize/enumerate labels in black rather than the class default +\AddToHook{begindocument}{\colorlet{structure}{black}} + +% -- Header bar carrying the frame title (hidden on plain pages). +\AddToHook{begindocument}{% + \EditInstance{header}{std}{ + background-color = white, + color = black, + print-frame-title = true, + height = 30pt, + font = \headerfont\bfseries, + left-hspace = \dimexpr\Gm@lmargin - 0.6cm\relax, + }% + \EditInstance{footer}{std}{element-order = {}}% + \EditInstance{frametitle}{header}{after-vspace = 6mm minus 3mm}% +} + +% Like \frametitle, but forces a gap below the title on packed slides where the +% header's own spacing collapses. The \par gets us into vertical mode first. +\NewDocumentCommand\stitle{m}{\frametitle{#1}\par\addvspace{4mm}} + +% \standoutline{...}: a centred line of text in the title's sans/size/colour, +% for emphasis within a normal (light) frame, e.g. closing a slide. +\NewDocumentCommand\standoutline{m}{% + \par + \begingroup + \centering\headerfont\Large\bfseries\color{TrantorDark}#1\par + \endgroup +} + +% Tick and cross, for marking things right or wrong. +\NewDocumentCommand\yes{}{\ding{51}} +\NewDocumentCommand\no{}{\ding{55}} + +% \footline{...}: a small reference or citation pinned to the bottom-left of +% the slide. Overlaid, so it can go anywhere inside the frame. +\NewDocumentCommand\footline{m}{% + \begin{tikzpicture}[remember picture, overlay] + \node[anchor=south west, xshift=1ex, yshift=0.7ex, font=\scriptsize, text=TrantorMuted] + at (current page.south west) {#1}; + \end{tikzpicture}% +} + +% \arxiv{1306.5001}: a small, grey "arXiv:" tag linked to the abstract. +% Meant to sit inline next to a statement, e.g. a theorem. +\NewDocumentCommand\arxiv{m}{% + \href{https://arxiv.org/abs/#1}{{\headerfont\scriptsize\color{TrantorMuted}arXiv:#1}}% +} + +% -- Bottom progress bar + frame counter (hidden on plain pages). +\newif\iftrantorPlainPage +\trantorPlainPagefalse + +\AddToHook{shipout/foreground}{% + \iftrantorPlainPage\else + \trantorArtifactBegin + \begin{tikzpicture}[remember picture, overlay] + \pgfmathsetmacro{\trantorratio}{(\@totalframes > 0) ? (\theframe / \@totalframes) : 0}% + \fill[TrantorAccent] + (current page.south west) + rectangle + ([xshift=\trantorratio\paperwidth, yshift=1pt] current page.south west); + \node[anchor=south east, inner sep=5pt, font=\tiny, text=TrantorDark] + at (current page.south east) {\theframe\,/\,\@totalframes}; + \end{tikzpicture}% + \trantorArtifactEnd + \fi + \global\trantorPlainPagefalse +} + +% -- Remember the current section title, and dim the others in the mini-TOC. +\ExplSyntaxOn +\tl_new:N \g__trantor_section_tl + +\AddToHook{section/begin}{ + \cs_if_exist:NT \l__talk_section_tl { + \tl_gset:NV \g__trantor_section_tl \l__talk_section_tl + } +} + +\cs_new_protected:Npn \__trantor_print_section: { \tl_use:N \g__trantor_section_tl } +\cs_set_eq:NN \trantorSectionTitle \__trantor_print_section: + +% Suspend tagging around the theme's decorative / pagination graphics when +% tagging is on (a no-op otherwise), so the progress bar and frame counter stay +% out of the structure tree instead of being flagged as loose content. +\cs_new_protected:Npn \trantorArtifactBegin + { \cs_if_exist:NT \tag_suspend:n { \tag_suspend:n { trantor } } } +\cs_new_protected:Npn \trantorArtifactEnd + { \cs_if_exist:NT \tag_resume:n { \tag_resume:n { trantor } } } + +% Soften the dimming of inactive TOC entries on the section page (0.2 -> 0.7). +% ltx-talk exposes no key for this yet, so we override the class-private +% \__talk_toc_dest:w. Revisit if a supported interface appears or the internal +% changes. +\cs_set_protected:Npn \__talk_toc_dest:w #1 . #2 . #3 . #4 . #5 \q_stop #6 + { + \bool_lazy_or:nnTF + { + \bool_lazy_and_p:nn + { \int_compare_p:nNn { \value { section } } = {#2} } + { \int_compare_p:nNn { \value { subsection } } = 0 } + } + { + \bool_lazy_and_p:nn + { \int_compare_p:nNn { \value { section } } = {#2} } + { \int_compare_p:nNn { \value { subsection } } = {#3} } + } + {#6} + { \opacity_begin:n { 0.7 } #6 \opacity_end: } + } +\ExplSyntaxOff + +% -- Title page. Drop a logo.png next to your slides, or redefine \titlelogo. +\newcommand{\titlelogo}{% + \IfFileExists{logo.png} + {\includegraphics[height=1.4cm, alt={Organisation logo}]{logo.png}}{}% +} + +\renewcommand{\maketitle}{% + \global\trantorPlainPagetrue + \begin{frame}{}% + \thispagestyle{plain}% + \vfill + \hspace*{0.04\paperwidth}% + \begin{minipage}{0.82\paperwidth} + \raggedright + {\color{TrantorDark}\headerfont\Large\bfseries \@title\par}% + \vspace{0.5em}% + {\color{TrantorAccent}\rule{\linewidth}{0.8pt}\par}% + \vspace{1.3em}% + % Metadata on the left, logo on the right; bottom-aligned so the logo sits + % level with the date and grows upward rather than below it. + \begin{minipage}[b]{0.66\linewidth} + \raggedright + {\normalsize \@author\par}% + \ifx\@institute\empty\else + \vspace{0.2em}% + {\small\color{TrantorMuted} \@institute\par}% + \fi + \vspace{0.2em}% + {\small \@date\par}% + \end{minipage}% + \hfill + \begin{minipage}[b]{0.30\linewidth} + \raggedleft + \titlelogo + \end{minipage}% + \end{minipage}% + \hspace*{0.04\paperwidth}% + \vspace{0.12\paperheight}% + \end{frame}% +} + +% -- Section divider page (dark full-bleed panel with the mini-TOC). +\NewDocumentCommand \sectionpage { } {% + \global\trantorPlainPagetrue + \begin{frame}{}% + \thispagestyle{plain}% + \noindent + \begin{tikzpicture} + \useasboundingbox (0,0) rectangle (\linewidth,-\textheight); + \fill[TrantorDark] + (-\Gm@lmargin, \paperheight) + rectangle + (\dimexpr\paperwidth-\Gm@lmargin\relax, -\paperheight); + \node[text=white, anchor=center, inner sep=0pt] + at (0.5\linewidth, -0.5\textheight) {% + \begin{minipage}{\linewidth} + \centering + \setcounter{tocdepth}{1}% + \colorlet{structure}{white}% + \setlength{\parskip}{1.2em}% spacing between TOC entries + \headerfont\Large + \tableofcontents + \end{minipage}% + }; + \end{tikzpicture}% + \end{frame}% +} + +% \standout{...}: a full frame with the same dark panel as \sectionpage, +% and the given text centred on it. +\NewDocumentCommand \standout { +m } {% + \global\trantorPlainPagetrue + \begin{frame}{}% + \thispagestyle{plain}% + \noindent + \begin{tikzpicture} + \useasboundingbox (0,0) rectangle (\linewidth,-\textheight); + \fill[TrantorDark] + (-\Gm@lmargin, \paperheight) + rectangle + (\dimexpr\paperwidth-\Gm@lmargin\relax, -\paperheight); + \node[text=white, anchor=center, inner sep=0pt] + at (0.5\linewidth, -0.5\textheight) {% + \begin{minipage}{0.8\linewidth} + \centering + \headerfont\LARGE\bfseries + #1 + \end{minipage}% + }; + \end{tikzpicture}% + \end{frame}% +} + +\makeatother