20
0

Re-vendor the theme from the trantor fork

Brings in the fixes from porting the first real deck: no header band on
untitled frames, divider titles in TrantorDark, \alert in the accent and
italic quotes, the title page, dividers, and panels usable inside a
document-opened frame, \plainpage, panel geometry pinned against
document overlay styles, a compressible title page bottom space, and
standout panels left out of the frame numbering.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-20 00:11:19 +09:00
parent bba35f7b8c
commit 75cfb2c762

View File

@@ -48,6 +48,14 @@
% itemize/enumerate labels in the body colour rather than the class default % itemize/enumerate labels in the body colour rather than the class default
\AddToHook{begindocument}{\colorlet{structure}{TrantorDark}} \AddToHook{begindocument}{\colorlet{structure}{TrantorDark}}
% \alert in the accent colour rather than the class's red, as metropolis
% coloured alerted text from the theme palette
\AddToHook{begindocument}{\colorlet{alert}{TrantorAccent}}
% beamer set quotations in italic; ported decks expect it
\AddToHook{env/quote/begin}{\itshape}
\AddToHook{env/quotation/begin}{\itshape}
% -- Header bar carrying the frame title (hidden on plain pages). % -- Header bar carrying the frame title (hidden on plain pages).
% headsep is what pads under the title; the height key alone only pads above. % headsep is what pads under the title; the height key alone only pads above.
\geometry{headsep=10pt} \geometry{headsep=10pt}
@@ -64,6 +72,41 @@
\EditInstance{frametitle}{header}{after-vspace = 6mm minus 3mm}% \EditInstance{frametitle}{header}{after-vspace = 6mm minus 3mm}%
} }
% -- A frame with no \frametitle gets no header band. ltx-talk draws it
% unconditionally, which leaves an empty dark slab across the top of every
% full-bleed image slide. metropolis omitted the bar on untitled frames and
% decks are written expecting that. \trantorEmptyHeadertrue restores the bar.
%
% The band is drawn from \@oddhead, so this replaces \ps@talk; \pagestyle has
% to be re-issued for the new definition to take.
\newif\iftrantorEmptyHeader
\trantorEmptyHeaderfalse
\ExplSyntaxOn
\cs_new_protected:Npn \trantor@header
{
\iftrantorEmptyHeader
\UseInstance { header } { std }
\else
% Guard the class internal: a class change should not make this an error.
\cs_if_exist:NTF \g__talk_frame_title_tl
{
\tl_if_empty:NF \g__talk_frame_title_tl
{ \UseInstance { header } { std } }
}
{ \UseInstance { header } { std } }
\fi
}
\cs_set_nopar:Npn \ps@talk
{
\cs_set_nopar:Npn \@oddhead { \trantor@header \hfil }
\cs_set_nopar:Npn \@oddfoot { \UseInstance { footer } { std } }
\cs_set_eq:NN \@evenhead \@oddhead
\cs_set_eq:NN \@evenfoot \@oddfoot
}
\ExplSyntaxOff
\pagestyle{talk}
% Like \frametitle, but forces a gap below the title on packed slides where the % 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. % header's own spacing collapses. The \par gets us into vertical mode first.
\NewDocumentCommand\stitle{m}{\frametitle{#1}\par\addvspace{4mm}} \NewDocumentCommand\stitle{m}{\frametitle{#1}\par\addvspace{4mm}}
@@ -99,6 +142,8 @@
% -- \appendix: frames after it are numbered among themselves and left out of % -- \appendix: frames after it are numbered among themselves and left out of
% the total. The count travels through the aux file, so it settles on the % the total. The count travels through the aux file, so it settles on the
% second run. % second run.
% ltx-talk gained its own \appendix upstream after 0.3.12; once a release
% ships it, revisit this in favour of the class's version.
\newif\iftrantorAppendix \newif\iftrantorAppendix
\trantorAppendixfalse \trantorAppendixfalse
\newcommand\trantorMainFrames{\@totalframes} \newcommand\trantorMainFrames{\@totalframes}
@@ -107,6 +152,30 @@
\global\trantorAppendixtrue \global\trantorAppendixtrue
\protected@write\@auxout{}{% \protected@write\@auxout{}{%
\string\gdef\string\trantorMainFrames{\the\value{frame}}}% \string\gdef\string\trantorMainFrames{\the\value{frame}}}%
\protected@write\@auxout{}{%
\string\gdef\string\trantorMainPanels{\the\value{trantorpanels}}}%
}
% -- Panels (standout pages) stay out of the frame numbering, as under
% metropolis, which set noframenumbering on standout frames. The class's frame
% counter cannot be touched -- notes and property records key on it -- so the
% panels are counted separately and subtracted for display. The totals travel
% through the aux file like \trantorMainFrames does.
\newcounter{trantorpanels}
\newcounter{trantorpanellast}
\newcommand\trantorTotalPanels{0}
\newcommand\trantorMainPanels{\trantorTotalPanels}
% \immediate: a deferred write would wait for a shipout that never comes.
\AtEndDocument{%
\immediate\write\@auxout{%
\string\gdef\string\trantorTotalPanels{\the\value{trantorpanels}}}%
}
% Count each panel frame once, though the body may run once per slide.
\newcommand\trantor@countpanel{%
\ifnum\value{trantorpanellast}=\value{frame}\else
\stepcounter{trantorpanels}% \stepcounter and \setcounter act globally
\setcounter{trantorpanellast}{\value{frame}}%
\fi
} }
% Count registers, not macros: pgfmath expands while parsing, and a macro % Count registers, not macros: pgfmath expands while parsing, and a macro
@@ -116,11 +185,13 @@
\newcommand\trantor@setcounts{% \newcommand\trantor@setcounts{%
\iftrantorAppendix \iftrantorAppendix
\trantor@n=\numexpr\value{frame}-\trantorMainFrames\relax \trantor@n=\numexpr\value{frame}-\trantorMainFrames
\trantor@d=\numexpr\@totalframes-\trantorMainFrames\relax -\value{trantorpanels}+\trantorMainPanels\relax
\trantor@d=\numexpr\@totalframes-\trantorMainFrames
-\trantorTotalPanels+\trantorMainPanels\relax
\else \else
\trantor@n=\value{frame}\relax \trantor@n=\numexpr\value{frame}-\value{trantorpanels}\relax
\trantor@d=\numexpr\trantorMainFrames\relax \trantor@d=\numexpr\trantorMainFrames-\trantorMainPanels\relax
\fi \fi
} }
@@ -210,6 +281,27 @@
\ExplSyntaxOff \ExplSyntaxOff
% Run #1 inside the current frame if there is one, else inside a fresh frame.
% Mirrors the class's \maketitle, so a document can wrap any of these in its
% own frame and add content alongside -- a \note, or \footline for a revision
% stamp -- following the beamer idiom.
\ExplSyntaxOn
\cs_new_protected:Npn \trantor@inframe #1
{
\bool_if:NTF \l__talk_frame_bool
{#1}
{ \begin { frame } #1 \end { frame } }
}
\ExplSyntaxOff
% \plainpage: suppress the footer progress bar and frame number on the current
% frame's pages, as the title, standout, and divider pages do. Use it at the
% top of a frame, e.g. one holding a full-bleed image.
\NewDocumentCommand\plainpage{}{%
\global\trantorPlainPagetrue
\thispagestyle{plain}%
}
% -- Title page. Drop a logo.png next to your slides, or redefine \titlelogo. % -- Title page. Drop a logo.png next to your slides, or redefine \titlelogo.
\newcommand{\titlelogo}{% \newcommand{\titlelogo}{%
\IfFileExists{logo.png} \IfFileExists{logo.png}
@@ -217,9 +309,8 @@
} }
\renewcommand{\maketitle}{% \renewcommand{\maketitle}{%
\global\trantorPlainPagetrue \trantor@inframe{%
\begin{frame}{}% \plainpage
\thispagestyle{plain}%
\vfill \vfill
\hspace*{0.04\paperwidth}% \hspace*{0.04\paperwidth}%
\begin{minipage}{0.82\paperwidth} \begin{minipage}{0.82\paperwidth}
@@ -251,18 +342,23 @@
\end{minipage}% \end{minipage}%
\end{minipage}% \end{minipage}%
\hspace*{0.04\paperwidth}% \hspace*{0.04\paperwidth}%
\vspace{0.12\paperheight}% % shrinkable, so a long author block compresses this space instead of
\end{frame}% % overfilling the fixed frame height
\vspace{0.12\paperheight minus 0.08\paperheight}%
}%
} }
% -- A full-bleed dark panel with the given body centred in a minipage of the % -- A full-bleed dark panel with the given body centred in a minipage of the
% given width. % given width.
\NewDocumentCommand \trantor@panel { m +m } {% \NewDocumentCommand \trantor@panel { m +m } {%
\global\trantorPlainPagetrue \trantor@inframe{%
\begin{frame}{}% \plainpage
\thispagestyle{plain}% \trantor@countpanel
\noindent \noindent
\begin{tikzpicture} % overlay=false explicitly: the panel is positioned from its bounding box,
% so it breaks if the document sets \tikzstyle{every picture}+=[overlay],
% which decks ported from beamer commonly do.
\begin{tikzpicture}[overlay=false, remember picture=false]
\useasboundingbox (0,0) rectangle (\linewidth,-\textheight); \useasboundingbox (0,0) rectangle (\linewidth,-\textheight);
\fill[TrantorDark] \fill[TrantorDark]
(-\Gm@lmargin, \paperheight) (-\Gm@lmargin, \paperheight)
@@ -276,26 +372,29 @@
\end{minipage}% \end{minipage}%
}; };
\end{tikzpicture}% \end{tikzpicture}%
\end{frame}% }%
} }
% -- Divider pages: the section title over a progress bar, set on the ordinary % -- Divider pages: the section title over a progress bar, set on the ordinary
% light background. Not plain pages: the footer bar and frame number stay. % light background. Not plain pages: the footer bar and frame number stay.
% Like the class's \maketitle, the dividers work inside a frame the document
% opened itself, so beamer's \begin{frame}\sectionpage\note{...}\end{frame}
% idiom carries over. Called between frames, they open their own.
\NewDocumentCommand \trantor@divider { +m } {% \NewDocumentCommand \trantor@divider { +m } {%
\begin{frame}{}% \trantor@inframe{%
\thispagestyle{plain}% \thispagestyle{plain}%
\vfill \vfill
\centering \centering
\begin{minipage}{0.52\linewidth}% \begin{minipage}{0.52\linewidth}%
\raggedright \raggedright
{\headerfont\Large\bfseries\trantorSectionTitle\par}% {\color{TrantorDark}\headerfont\Large\bfseries\trantorSectionTitle\par}%
\vspace{0.4em}% \vspace{0.4em}%
\trantorProgressBar{\linewidth}% \trantorProgressBar{\linewidth}%
#1% #1%
\end{minipage}% \end{minipage}%
\par \par
\vfill \vfill
\end{frame}% }%
} }
\NewDocumentCommand \sectionpage { } { \trantor@divider{} } \NewDocumentCommand \sectionpage { } { \trantor@divider{} }
@@ -304,7 +403,7 @@
\NewDocumentCommand \subsectionpage { } {% \NewDocumentCommand \subsectionpage { } {%
\trantor@divider{% \trantor@divider{%
\par\vspace{0.8em}% \par\vspace{0.8em}%
{\headerfont\large\bfseries\trantorSubsectionTitle\par}% {\color{TrantorDark}\headerfont\large\bfseries\trantorSubsectionTitle\par}%
}% }%
} }