diff --git a/slides_template/LICENSE.trantor b/slides_template/LICENSE.trantor deleted file mode 100644 index c6d3b2e..0000000 --- a/slides_template/LICENSE.trantor +++ /dev/null @@ -1,21 +0,0 @@ -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 index 990a03b..3bb84b6 100644 --- a/slides_template/trantor.sty +++ b/slides_template/trantor.sty @@ -1,5 +1,9 @@ % trantor.sty -- a Metropolis-style theme for the ltx-talk class. -% LuaLaTeX only. Fonts: Libertinus Serif/Sans (text) + Euler (maths). +% LuaLaTeX only. +% +% Copyright (c) 2026 Marco Pompili, https://github.com/mrc-pop/trantor +% Received under the MIT license and redistributed here, with modifications, +% under the GNU GPL version 3 or later. See COPYING. \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{trantor}[2026-08-01 v1.0 Metropolis-like theme for ltx-talk] @@ -30,24 +34,38 @@ \setlength\belowdisplayshortskip{5pt plus 2pt minus 1pt}% } -% -- Colours. Set your own accent anywhere in the preamble with, e.g., -% \definecolor{accent}{HTML}{BF1238} +% -- Palette. Four colours drive everything the theme draws. Override any of +% them in the preamble, before or after loading trantor: +% +% \definecolor{accent}{HTML}{BF1238} +% \colorlet{TrantorDark}{makopurple1} +% +% accent progress bars and emphasis +% TrantorDark header band, section dividers, standout panels, frame numbers +% TrantorLight text on dark, and anything that has to read against it +% TrantorMuted affiliations, footlines, arxiv tags. This is the lightest grey +% that still meets WCAG AA contrast (4.5:1) on white (~4.54:1). \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 +\providecolor{TrantorDark}{HTML}{000000} +\providecolor{TrantorLight}{HTML}{FFFFFF} +\providecolor{TrantorMuted}{HTML}{767676} \AddToHook{begindocument}{\colorlet{TrantorAccent}{accent}} -% itemize/enumerate labels in black rather than the class default -\AddToHook{begindocument}{\colorlet{structure}{black}} +% itemize/enumerate labels in the body colour rather than the class default +\AddToHook{begindocument}{\colorlet{structure}{TrantorDark}} % -- Header bar carrying the frame title (hidden on plain pages). +% The band is a rule of height (header height - headsep) with depth headsep, so +% headsep is the only thing that puts space under the title. geometry owns it. +\geometry{headsep=10pt} + + \AddToHook{begindocument}{% \EditInstance{header}{std}{ - background-color = white, - color = black, + background-color = TrantorDark, + color = TrantorLight, print-frame-title = true, - height = 30pt, + height = 40pt, font = \headerfont\bfseries, left-hspace = \dimexpr\Gm@lmargin - 0.6cm\relax, }% @@ -87,6 +105,52 @@ \href{https://arxiv.org/abs/#1}{{\headerfont\scriptsize\color{TrantorMuted}arXiv:#1}}% } +% -- \appendix, which ltx-talk does not provide. Frames after it keep counting +% but are left out of the total, so the denominator is the last frame of the +% talk proper. This is what appendixnumberbeamer does for beamer. The count is +% carried through the aux file, so it settles on the second run. +\newif\iftrantorAppendix +\trantorAppendixfalse +\newcommand\trantorMainFrames{\@totalframes} + +% Appendix frames are numbered among themselves, as appendixnumberbeamer does, +% but by subtracting an offset rather than resetting the counter. The class +% records a property per frame keyed on that counter, so resetting it collides +% with ltx-talk's own frame. labels and breaks \ref to a frame. Properly +% this belongs in the class, which could renumber and relabel together. +\NewDocumentCommand \appendix { } {% + \global\trantorAppendixtrue + \protected@write\@auxout{}{% + \string\gdef\string\trantorMainFrames{\the\value{frame}}}% +} + +% Numerator and denominator for the frame counter and the progress bars. These +% are count registers rather than macros because pgfmath expands its argument +% while parsing, and a macro carrying a conditional sends it into a loop. +\newcount\trantor@n +\newcount\trantor@d + +\newcommand\trantor@setcounts{% + \iftrantorAppendix + \trantor@n=\numexpr\value{frame}-\trantorMainFrames\relax + \trantor@d=\numexpr\@totalframes-\trantorMainFrames\relax + \else + \trantor@n=\value{frame}\relax + \trantor@d=\numexpr\trantorMainFrames\relax + \fi +} + +\newcommand\trantorFrameNumber{\trantor@setcounts\the\trantor@n} +\newcommand\trantorTotalFrames{\trantor@setcounts\the\trantor@d} + +\newcommand\trantor@setratio{% + \ifnum\trantor@d>0 + \pgfmathsetmacro{\trantorratio}{min(\the\trantor@n / \the\trantor@d, 1)}% + \else + \def\trantorratio{0}% + \fi +} + % -- Bottom progress bar + frame counter (hidden on plain pages). \newif\iftrantorPlainPage \trantorPlainPagefalse @@ -95,13 +159,15 @@ \iftrantorPlainPage\else \trantorArtifactBegin \begin{tikzpicture}[remember picture, overlay] - \pgfmathsetmacro{\trantorratio}{(\@totalframes > 0) ? (\theframe / \@totalframes) : 0}% + \trantor@setcounts + \trantor@setratio \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}; + \node[anchor=south east, inner sep=5pt, font=\scriptsize, text=TrantorDark] + at (current page.south east) + {\the\trantor@n\,/\,\the\trantor@d}; \end{tikzpicture}% \trantorArtifactEnd \fi @@ -121,6 +187,21 @@ \cs_new_protected:Npn \__trantor_print_section: { \tl_use:N \g__trantor_section_tl } \cs_set_eq:NN \trantorSectionTitle \__trantor_print_section: +% Likewise the subsection, for \subsectionpage. Cleared at each new section so +% that a stale subsection title cannot leak into the next one. +\tl_new:N \g__trantor_subsection_tl + +\AddToHook{section/begin}{ \tl_gclear:N \g__trantor_subsection_tl } + +\AddToHook{subsection/begin}{ + \cs_if_exist:NT \l__talk_subsection_tl { + \tl_gset:NV \g__trantor_subsection_tl \l__talk_subsection_tl + } +} + +\cs_new_protected:Npn \__trantor_print_subsection: { \tl_use:N \g__trantor_subsection_tl } +\cs_set_eq:NN \trantorSubsectionTitle \__trantor_print_subsection: + % 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. @@ -192,33 +273,49 @@ \end{frame}% } -% -- Section divider page (dark full-bleed panel with the mini-TOC). -\NewDocumentCommand \sectionpage { } {% - \global\trantorPlainPagetrue +% -- Divider pages, following metropolis: on the ordinary light background, a +% block set in the middle of the slide holding the section title over a +% progress bar, and for a subsection the subsection title beneath that. The +% bar is the same progress the footer bar shows, drawn at half width. The +% footer bar and frame number stay, so these are not plain pages in the sense +% the shipout hook means. +\newlength\trantor@barwidth +\newlength\trantor@barfill + +% \trantorProgressBar{}: filled to the current position, grey after. +\NewDocumentCommand \trantorProgressBar { m } {% + \setlength\trantor@barwidth{#1}% + \trantor@setcounts + \trantor@setratio + \setlength\trantor@barfill{\trantorratio\trantor@barwidth}% + \textcolor{TrantorDark}{\rule{\trantor@barfill}{0.6pt}}% + \textcolor{TrantorDark!20}{% + \rule{\dimexpr\trantor@barwidth-\trantor@barfill\relax}{0.6pt}}% +} + +\NewDocumentCommand \trantor@divider { m } {% \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}% + \vfill + \centering + \begin{minipage}{0.52\linewidth}% + \raggedright + {\headerfont\Large\bfseries\trantorSectionTitle\par}% + \vspace{0.4em}% + \trantorProgressBar{\linewidth}% + \IfBlankF{#1}{% + \par\vspace{0.8em}% + {\headerfont\large\bfseries #1\par}% + }% + \end{minipage}% + \par + \vfill \end{frame}% } +\NewDocumentCommand \sectionpage { } { \trantor@divider {} } +\NewDocumentCommand \subsectionpage { } { \trantor@divider {\trantorSubsectionTitle} } + % \standout{...}: a full frame with the same dark panel as \sectionpage, % and the given text centred on it. \NewDocumentCommand \standout { +m } {% @@ -232,7 +329,7 @@ (-\Gm@lmargin, \paperheight) rectangle (\dimexpr\paperwidth-\Gm@lmargin\relax, -\paperheight); - \node[text=white, anchor=center, inner sep=0pt] + \node[text=TrantorLight, anchor=center, inner sep=0pt] at (0.5\linewidth, -0.5\textheight) {% \begin{minipage}{0.8\linewidth} \centering