831 lines
29 KiB
TeX
831 lines
29 KiB
TeX
% beamerthemeFHGR.sty
|
|
% A modernized, configurable Beamer FHGR theme.
|
|
% Author: Daniel Zünd
|
|
% Date: 2025-10-16
|
|
%
|
|
% Quick start
|
|
% \documentclass{beamer}
|
|
% \usetheme[dark,noprog]{FHGR} % all keys: see "Options" below / README.md
|
|
% \title{Deck title}\subtitle{Subtitle}\author{Jane Doe}
|
|
% \fullname{Prof. Dr. Jane Doe} % optional, title page only
|
|
% \shortname{CDS042} % optional, footline + title page
|
|
% \begin{document}
|
|
% \FHGRTitlePage % title slide
|
|
% \FHGRToC{Agenda} % ToC slide, image on the left half
|
|
% \begin{frame}{A slide} ... \end{frame}
|
|
% \FHGRClosingPage[][Thank you!]% closing slide
|
|
% \end{document}
|
|
%
|
|
% Every image is looked up with \IfFileExists, so a missing logo or background
|
|
% is skipped silently instead of aborting the build. The defaults expect the
|
|
% theme images under pics/theme_pics/.
|
|
%
|
|
% Commands defined here: \FHGRTitlePage, \FHGRToC, \FHGRClosingPage,
|
|
% \FHGRTable (env), \fullname, \shortname, \credit, \imagesource, \source.
|
|
|
|
% =============================
|
|
% Package metadata & engine setup
|
|
% =============================
|
|
\NeedsTeXFormat{LaTeX2e}
|
|
\ProvidesPackage{beamerthemeFHGR}[2025/10/16 v1.0 FHGR Beamer Theme]
|
|
|
|
% Covered overlay material (\pause, \onslide, [<+->]) is hidden completely.
|
|
% Put \setbeamercovered{transparent} in your preamble to grey it out instead.
|
|
\mode<presentation>{
|
|
\setbeamercovered{invisible}
|
|
}
|
|
|
|
% Ensure xcolor gets the `table` option (for \rowcolor/\rowcolors) BEFORE any
|
|
% package (e.g. tikz) loads xcolor without it.
|
|
\PassOptionsToPackage{table}{xcolor}
|
|
|
|
% Core deps (why each one is needed)
|
|
\RequirePackage{etoolbox} % \patchcmd, \pretocmd, \ifdefempty
|
|
\RequirePackage{iftex} % \ifPDFTeX engine test below
|
|
\RequirePackage{tikz} % title page, ToC panel, progress bar
|
|
\RequirePackage{calc} % infix length arithmetic
|
|
\RequirePackage{graphicx} % logos and background images
|
|
\RequirePackage{pgfkeys} % the /fhgr option keys
|
|
\RequirePackage{hyperref} % links + PDF bookmarks (see "Appendix")
|
|
\RequirePackage{listings} % code slides, see "Listings style"
|
|
\RequirePackage{appendixnumberbeamer}% \appendix restarts frame numbering
|
|
\RequirePackage{xparse} % \NewDocumentCommand: \FHGRToC, \FHGRClosingPage
|
|
|
|
|
|
% Font setup (pdfLaTeX vs Xe/Lua): pdfLaTeX gets a scaled Helvetica clone,
|
|
% Xe/LuaLaTeX needs Roboto installed system-wide.
|
|
\ifPDFTeX
|
|
\RequirePackage[scaled=0.92]{helvet}
|
|
\RequirePackage[T1]{fontenc}
|
|
\RequirePackage{textcomp}
|
|
\renewcommand\familydefault{\sfdefault}
|
|
\else
|
|
\RequirePackage{fontspec}
|
|
% You can change these to your corporate fonts
|
|
\setmainfont{Roboto}[Scale=0.92]
|
|
\setsansfont{Roboto}
|
|
\fi
|
|
|
|
% =============================
|
|
% Options via pgfkeys (usable with \usetheme[<keys>]{FHGR})
|
|
% =============================
|
|
% One switch per boolean key; the pgfkeys `.is if' handlers below flip them.
|
|
% Query them in your own templates with \ifFHGR@dark ... \else ... \fi.
|
|
\newif\ifFHGR@dark
|
|
\newif\ifFHGR@progressbar
|
|
\newif\ifFHGR@shownav
|
|
\newif\ifFHGR@shownumber
|
|
\newif\ifFHGR@showsection
|
|
\newif\ifFHGR@compactlists
|
|
\newif\ifFHGR@titlegradient
|
|
\newif\ifFHGR@titlefillimage
|
|
|
|
\pgfkeys{/fhgr/.is family, /fhgr,
|
|
% File paths (safe defaults) -- each is stored in the \FHGR@... macro named
|
|
% after it and read at typeset time, so a wrong path fails silently.
|
|
logo/.store in=\FHGR@logo, % footline logo, light mode
|
|
logo={pics/theme_pics/logo_green_small.png},
|
|
logowhite/.store in=\FHGR@logowhite, % footline logo, dark mode
|
|
logowhite={pics/theme_pics/logo_green_small.png},% same file as `logo' by default
|
|
biglogoblack/.store in=\FHGR@biglogoblack, % title page logo, light mode
|
|
biglogoblack={pics/theme_pics/logo_green.png},
|
|
biglogowhite/.store in=\FHGR@biglogowhite, % title page logo, dark mode
|
|
biglogowhite={pics/theme_pics/logo_green.png},
|
|
grlogo/.store in=\FHGR@grlogo, % stored only -- no template uses
|
|
grlogo={pics/theme_pics/graubuenden.png}, % it; free for your own slides
|
|
titlebg/.store in=\FHGR@titlebg, % background of title/ToC/closing
|
|
titlebg={pics/theme_pics/titlepage.png},
|
|
% Toggles -- `\usetheme[key]{FHGR}' / `\usetheme[nokey]{FHGR}', see below
|
|
dark/.is if=FHGR@dark, % dark background, light text
|
|
dark=false,
|
|
progressbar/.is if=FHGR@progressbar, % thin bar along the bottom edge
|
|
progressbar=true,
|
|
nav/.is if=FHGR@shownav, % beamer's navigation symbols
|
|
nav=false,
|
|
framenumber/.is if=FHGR@shownumber, % "n / total" in the footline
|
|
framenumber=true,
|
|
showsection/.is if=FHGR@showsection, % current section in the headline
|
|
showsection=false,
|
|
compactlists/.is if=FHGR@compactlists, % tighter list spacing
|
|
compactlists=true,
|
|
titlegradient/.is if=FHGR@titlegradient, % fade PNG over background images
|
|
titlegradient=true,
|
|
titlefillimage/.is if=FHGR@titlefillimage, % true: stretch background to the
|
|
titlefillimage=true, % slide; false: keep aspect ratio
|
|
% Branding colors: 6-digit HTML values without `#'. They become the named
|
|
% colours in the "Colors" section below (\color{camel}, ...).
|
|
color/green/.store in=\FHGR@green,
|
|
color/green=817E65,
|
|
color/red/.store in=\FHGR@red,
|
|
color/red=C60219,
|
|
color/gray/.store in=\FHGR@gray,
|
|
color/gray=595959,
|
|
color/lightgray/.store in=\FHGR@lightgray,
|
|
color/lightgray=CCCCCC,
|
|
color/darkgray/.store in=\FHGR@darkgray,
|
|
color/darkgray=3F3F3F,
|
|
color/camel/.store in=\FHGR@camel,
|
|
color/camel=B39048,
|
|
color/linen/.store in=\FHGR@linen,
|
|
color/linen=e1d3b5,
|
|
color/black/.store in=\FHGR@black,
|
|
color/black=1E1E1E,
|
|
color/blue/.store in=\FHGR@blue,
|
|
color/blue=4B92A4,
|
|
color/white/.store in=\FHGR@white,
|
|
color/white=F8F9FA
|
|
}
|
|
|
|
% \beamerthemeFHGRoptions{<keys>} -- set /fhgr keys with their full names, e.g.
|
|
% \beamerthemeFHGRoptions{logo=pics/mylogo.png,titlegradient=false}
|
|
% It can only run after \usetheme, i.e. after the colours below were already
|
|
% \definecolor'd, so color/* keys have no effect here -- recolour with
|
|
% \definecolor + \colorlet instead (see "Colors").
|
|
\def\beamerthemeFHGRoptions#1{\pgfkeys{/fhgr,#1}}
|
|
% Aliases accepted by \usetheme[...]{FHGR}: the value keys logo= and titlebg=,
|
|
% plus these on/off pairs -- dark/nodark, progressbar/noprog, nav/nonav,
|
|
% framenumber/noframenumber, showsection/nosection, compactlists/nocompactlists,
|
|
% titlegradient/notitlegradient, titlefillimage/notitlefillimage.
|
|
\DeclareOptionBeamer{logo}{\pgfkeys{/fhgr,logo={#1}}}
|
|
\DeclareOptionBeamer{titlebg}{\pgfkeys{/fhgr,titlebg={#1}}}
|
|
\DeclareOptionBeamer{dark}{\pgfkeys{/fhgr,dark}}
|
|
\DeclareOptionBeamer{nodark}{\pgfkeys{/fhgr,dark=false}}
|
|
\DeclareOptionBeamer{progressbar}{\pgfkeys{/fhgr,progressbar}}
|
|
\DeclareOptionBeamer{noprog}{\pgfkeys{/fhgr,progressbar=false}}
|
|
\DeclareOptionBeamer{nav}{\pgfkeys{/fhgr,nav}}
|
|
\DeclareOptionBeamer{nonav}{\pgfkeys{/fhgr,nav=false}}
|
|
\DeclareOptionBeamer{framenumber}{\pgfkeys{/fhgr,framenumber}}
|
|
\DeclareOptionBeamer{noframenumber}{\pgfkeys{/fhgr,framenumber=false}}
|
|
\DeclareOptionBeamer{showsection}{\pgfkeys{/fhgr,showsection}}
|
|
\DeclareOptionBeamer{nosection}{\pgfkeys{/fhgr,showsection=false}}
|
|
\DeclareOptionBeamer{compactlists}{\pgfkeys{/fhgr,compactlists}}
|
|
\DeclareOptionBeamer{nocompactlists}{\pgfkeys{/fhgr,compactlists=false}}
|
|
\DeclareOptionBeamer{titlegradient}{\pgfkeys{/fhgr,titlegradient}}
|
|
\DeclareOptionBeamer{notitlegradient}{\pgfkeys{/fhgr,titlegradient=false}}
|
|
\DeclareOptionBeamer{titlefillimage}{\pgfkeys{/fhgr,titlefillimage}}
|
|
\DeclareOptionBeamer{notitlefillimage}{\pgfkeys{/fhgr,titlefillimage=false}}
|
|
\ProcessOptionsBeamer
|
|
|
|
% =============================
|
|
% Colors
|
|
% =============================
|
|
\RequirePackage{xcolor}
|
|
\RequirePackage{tabularx}
|
|
\RequirePackage{colortbl}
|
|
\RequirePackage{environ}% \NewEnviron captures the whole body (needed to wrap tabularx)
|
|
% The palette. Usable anywhere: \textcolor{camel}{...}, \color{linen},
|
|
% tikz [fill=green]. Careful -- green/red/gray/black/blue/white deliberately
|
|
% shadow xcolor's standard names, so \color{red} is FHGR red, not pure red.
|
|
\definecolor{green}{HTML}{\FHGR@green}
|
|
\definecolor{red}{HTML}{\FHGR@red}
|
|
\definecolor{gray}{HTML}{\FHGR@gray}
|
|
\definecolor{lightGray}{HTML}{\FHGR@lightgray}
|
|
\definecolor{camel}{HTML}{\FHGR@camel}
|
|
\definecolor{linen}{HTML}{\FHGR@linen}
|
|
\definecolor{black}{HTML}{\FHGR@black}
|
|
\definecolor{blue}{HTML}{\FHGR@blue}
|
|
\definecolor{darkGray}{HTML}{\FHGR@darkgray}
|
|
\definecolor{white}{HTML}{\FHGR@white}
|
|
|
|
% Dark mode adjustments. These semantic aliases are what the templates use, and
|
|
% what you should prefer in your own slides -- they follow the `dark' toggle:
|
|
% FHGRBg page background FHGRTxt body text
|
|
% FHGRDeco titles, footline, progress bar
|
|
% FHGRItem list bullets/numbers
|
|
% FHGRBlockBg / FHGRBlockTitleBg / FHGRBlockTitleFg block colours
|
|
% \colorlet copies the *value*, not the name, so recolouring after \usetheme
|
|
% takes two steps: \definecolor{green}{HTML}{00693C}\colorlet{FHGRDeco}{green}
|
|
\ifFHGR@dark
|
|
\colorlet{FHGRBg}{black}
|
|
\colorlet{FHGRTxt}{white}
|
|
\colorlet{FHGRDeco}{green}
|
|
\colorlet{FHGRBlockBg}{gray}
|
|
\colorlet{FHGRBlockTitleBg}{darkGray}
|
|
\colorlet{FHGRBlockTitleFg}{camel}
|
|
\colorlet{FHGRItem}{camel}
|
|
\pagecolor{FHGRBg}
|
|
\else
|
|
\colorlet{FHGRBg}{white}
|
|
\colorlet{FHGRTxt}{black}
|
|
\colorlet{FHGRDeco}{green}
|
|
\colorlet{FHGRBlockBg}{lightGray!50}
|
|
\colorlet{FHGRBlockTitleBg}{lightGray}
|
|
\colorlet{FHGRBlockTitleFg}{camel}
|
|
\colorlet{FHGRItem}{camel}
|
|
\pagecolor{FHGRBg}
|
|
\fi
|
|
|
|
% =============================
|
|
% Public metadata helpers (optional)
|
|
% \fullname{Prof. Dr. Jane Doe} -> \insertfullname, title page meta line only
|
|
% \shortname{CDS042} -> \insertshortname, footline + title page
|
|
% Use them in the preamble next to \title/\author. Both start out empty; the
|
|
% footline then falls back to \insertauthor (see \FHGR@footmeta below).
|
|
% =============================
|
|
\newcommand*\fullname[1]{\gdef\FHGR@fullname{#1}}
|
|
\newcommand*\shortname[1]{\gdef\FHGR@shortname{#1}}
|
|
\def\FHGR@fullname{}
|
|
\def\FHGR@shortname{}
|
|
% Retrieval macros, for use inside custom templates.
|
|
\newcommand*\insertfullname{\FHGR@fullname}
|
|
\newcommand*\insertshortname{\FHGR@shortname}
|
|
|
|
% \FHGR@metajoin{<separator>}{<part>} -- typesets <part> only if it is non-empty,
|
|
% preceded by <separator> only if an earlier part was already set. Reset the run
|
|
% with \FHGR@metasepfalse, then call it once per part: no divider can then appear
|
|
% at the start or the end of the line, whichever parts happen to be empty.
|
|
% Emptiness is measured in a box rather than tested with \ifdefempty, because
|
|
% both \insertauthor and \insertshortname have a permanently non-empty
|
|
% replacement text (beamer runs \author{} itself; \insertshortname wraps
|
|
% \FHGR@shortname), so no \ifx test on them can ever detect "the user set nothing".
|
|
\newif\ifFHGR@metasep
|
|
\newcommand*\FHGR@metajoin[2]{%
|
|
\setbox\z@\hbox{#2}%
|
|
\ifdim\wd\z@>\z@
|
|
\ifFHGR@metasep#1\fi
|
|
#2\FHGR@metaseptrue
|
|
\fi
|
|
}
|
|
|
|
% Footline segment: \shortname (or \author as fallback) | short title.
|
|
\newcommand*\FHGR@footmeta{%
|
|
\FHGR@metasepfalse
|
|
\FHGR@metajoin{\,|\,}{\ifx\FHGR@shortname\@empty\insertauthor\else\insertshortname\fi}%
|
|
\FHGR@metajoin{\,|\,}{\insertshorttitle}%
|
|
}
|
|
|
|
% Title-page meta line: author | \shortname | \fullname.
|
|
\newcommand*\FHGR@titlemeta{%
|
|
\FHGR@metasepfalse
|
|
\FHGR@metajoin{~|~}{\insertauthor}%
|
|
\FHGR@metajoin{~|~}{\insertshortname}%
|
|
\FHGR@metajoin{~|~}{\insertfullname}%
|
|
}
|
|
|
|
% =============================
|
|
% Beamer color setup
|
|
% Maps the palette onto beamer's colour names. Override single entries after
|
|
% \usetheme, e.g. \setbeamercolor{block title}{bg=camel,fg=white}.
|
|
% =============================
|
|
\setbeamercolor*{normal text}{fg=FHGRTxt,bg=FHGRBg}
|
|
\setbeamercolor*{alerted text}{fg=red}
|
|
\setbeamercolor*{example text}{fg=green}
|
|
\setbeamercolor*{structure}{fg=FHGRTxt}
|
|
|
|
\setbeamercolor*{title}{fg=FHGRDeco}
|
|
\setbeamercolor*{subtitle}{fg=FHGRDeco}
|
|
\setbeamercolor*{frametitle}{fg=FHGRDeco}
|
|
\setbeamercolor*{framesubtitle}{fg=FHGRDeco}
|
|
\setbeamercolor*{section in head/foot}{fg=FHGRDeco}
|
|
\setbeamercolor*{section in toc}{fg=FHGRTxt}
|
|
\setbeamercolor*{subsection in toc}{fg=FHGRTxt}
|
|
|
|
\setbeamercolor{block title}{bg=FHGRBlockTitleBg,fg=FHGRBlockTitleFg}
|
|
\setbeamercolor{block title example}{bg=FHGRBlockTitleBg,fg=green}
|
|
\setbeamercolor{block title alerted}{bg=FHGRBlockTitleBg,fg=red}
|
|
\setbeamercolor{block body}{bg=FHGRBlockBg,fg=FHGRTxt}
|
|
\setbeamercolor{block body example}{bg=FHGRBlockBg,fg=FHGRTxt}
|
|
\setbeamercolor{block body alerted}{bg=FHGRBlockBg,fg=FHGRTxt}
|
|
|
|
\setbeamercolor{caption}{fg=FHGRTxt}
|
|
|
|
\setbeamercolor{itemize item}{fg=FHGRItem}
|
|
\setbeamercolor{itemize subitem}{fg=FHGRItem}
|
|
\setbeamercolor{itemize subsubitem}{fg=FHGRItem}
|
|
\setbeamercolor{enumerate item}{fg=FHGRItem}
|
|
\setbeamercolor{enumerate subitem}{fg=FHGRItem}
|
|
\setbeamercolor{enumerate subsubitem}{fg=FHGRItem}
|
|
\setbeamercolor{description item}{fg=FHGRItem}
|
|
\setbeamercolor{description subitem}{fg=FHGRItem}
|
|
\setbeamercolor{description subsubitem}{fg=FHGRItem}
|
|
|
|
\setbeamercolor{note title}{bg=FHGRBlockTitleBg,fg=FHGRTxt}
|
|
\setbeamercolor{note date}{fg=FHGRTxt}
|
|
|
|
|
|
% =============================
|
|
% Tables (opt-in)
|
|
% \begin{FHGRTable}[<width>]{<colspec>} width optional, default \textwidth
|
|
% \textbf{Head A} & \textbf{Head B} & \textbf{Head C} \\
|
|
% a1 & b1 & c1 \\
|
|
% a2 & b2 & c2 \\
|
|
% \end{FHGRTable}
|
|
% Header row is shaded camel; data rows auto-alternate plain / FHGRBlockTitleBg,
|
|
% so no manual \rowcolor per row is needed. Columns use tabularx (X, l, c, r, ...).
|
|
% Defined with \NewEnviron, so the body is captured wholesale in \BODY -- write
|
|
% ordinary rows, no \\ trickery. \rowcolors{2} is what drives the alternation,
|
|
% starting at row 2 so the camel header keeps its own colour.
|
|
% =============================
|
|
\NewEnviron{FHGRTable}[2][\textwidth]{%
|
|
\rowcolors{2}{FHGRBlockTitleBg}{}%
|
|
\begin{tabularx}{#1}{#2}%
|
|
\rowcolor{camel}\BODY
|
|
\end{tabularx}%
|
|
}
|
|
|
|
|
|
% =============================
|
|
% Listings style (opt-in)
|
|
% Applied to every listing already (\lstset{style=FHGR} below), so just:
|
|
% \begin{lstlisting}[language=Python,caption=Demo] ... \end{lstlisting}
|
|
% \lstinputlisting[language=C]{src/main.c}
|
|
% \lstinline|inline snippet|
|
|
% A frame containing a listing must be declared \begin{frame}[fragile]{...}.
|
|
% Override per listing with the usual keys, e.g. [numbers=none,frame=none].
|
|
% =============================
|
|
\lstdefinestyle{FHGR}{
|
|
backgroundcolor=\color{linen},
|
|
commentstyle=\color{green},
|
|
keywordstyle=\color{red},
|
|
numberstyle=\tiny\color{green},
|
|
stringstyle=\color{blue},
|
|
basicstyle=\ttfamily\footnotesize\color{black},
|
|
breaklines=true,
|
|
captionpos=b,
|
|
numbers=left,
|
|
numbersep=5pt,
|
|
showspaces=false,
|
|
showstringspaces=false,
|
|
showtabs=false,
|
|
tabsize=2,
|
|
frame=single,
|
|
}
|
|
\lstset{style=FHGR}
|
|
% listings is not UTF-8 aware on its own: map umlauts and ~ to real glyphs.
|
|
\lstset{literate={Ö}{{\"O}}1 {Ä}{{\"A}}1 {Ü}{{\"U}}1 {ü}{{\"u}}1 {ä}{{\"a}}1 {ö}{{\"o}}1 {~}{{\textasciitilde}}1}
|
|
% \lstinline inherits the surrounding text colour (white in dark mode, black in
|
|
% light mode) by overriding basicstyle without a colour in TextStyle mode.
|
|
\lst@AddToHook{TextStyle}{\lstset{basicstyle=\ttfamily\footnotesize}}
|
|
|
|
% =============================
|
|
% List spacing
|
|
% =============================
|
|
\ifFHGR@compactlists
|
|
\newcommand*\FHGR@compactlistparams{%
|
|
\setlength{\itemsep}{0.4ex}%
|
|
\setlength{\topsep}{0.4ex}%
|
|
\setlength{\parsep}{0pt}% \list derives \parskip from \parsep
|
|
}
|
|
\patchcmd{\list}%
|
|
{\csname @list\romannumeral\the\@listdepth\endcsname}%
|
|
{\csname @list\romannumeral\the\@listdepth\endcsname
|
|
\FHGR@compactlistparams}%
|
|
{}%
|
|
{\PackageWarning{beamerthemeFHGR}{Could not patch \string\list;
|
|
compact list spacing is not available}}%
|
|
\fi
|
|
|
|
% =============================
|
|
% Navigation symbols, progress bar, footline & headline
|
|
% =============================
|
|
% `nav=false' (the default) removes beamer's navigation symbol row entirely.
|
|
\ifFHGR@shownav\else
|
|
\setbeamertemplate{navigation symbols}{}
|
|
\fi
|
|
|
|
% Headline: current section on the top-left, only with `showsection=true'.
|
|
% The box is typeset either way, so the 2.2ex strip stays reserved and frame
|
|
% titles do not jump when a deck mixes both settings.
|
|
\setbeamertemplate{headline}{%
|
|
\leavevmode
|
|
\hbox{\begin{beamercolorbox}[wd=\paperwidth,ht=2.2ex,dp=1ex,leftskip=1em,rightskip=1em]{}
|
|
\ifFHGR@showsection
|
|
\usebeamerfont{section in head/foot}\insertsectionhead
|
|
\fi
|
|
\end{beamercolorbox}}
|
|
}
|
|
|
|
% Footline: logo | \shortname (or \author) | short title ... frame number,
|
|
% followed by the progress bar. The logo follows `dark', the counter needs
|
|
% `framenumber=true', the bar needs `progressbar=true'.
|
|
\setbeamertemplate{footline}{%
|
|
\leavevmode
|
|
\hbox{\begin{beamercolorbox}[wd=\paperwidth,ht=2.8ex,dp=1.2ex,leftskip=1em,rightskip=1em]{}
|
|
|
|
\ifFHGR@dark
|
|
\ifx\FHGR@logowhite\@empty\relax\else
|
|
\IfFileExists{\FHGR@logowhite}{\raisebox{-0.1ex}{\includegraphics[height=3em]{\FHGR@logowhite}}\hspace{0.6em}}{}%
|
|
\fi
|
|
\else
|
|
\ifx\FHGR@logo\@empty\relax\else
|
|
\IfFileExists{\FHGR@logo}{\raisebox{-0.1ex}{\includegraphics[height=3em]{\FHGR@logo}}\hspace{0.6em}}{}%
|
|
\fi
|
|
\fi
|
|
{\scriptsize \color{FHGRDeco}\FHGR@footmeta}
|
|
\hfill
|
|
\ifFHGR@shownumber{\color{FHGRDeco}
|
|
\scriptsize\insertframenumber\,/\,\inserttotalframenumber}\fi
|
|
\end{beamercolorbox}}
|
|
% Progress bar: width = frame / total, drawn as an overlay on the bottom edge.
|
|
% The \pgfmath scratch macros are scoped, so the result has to be \global to
|
|
% survive \endgroup and reach the tikzpicture below.
|
|
\ifFHGR@progressbar
|
|
\begingroup
|
|
\count255=\inserttotalframenumber\relax
|
|
\ifnum\count255<1 \count255=1\fi
|
|
\ifnum\count255<\c@framenumber \count255=\c@framenumber\fi % first pass: no .nav yet, total defaults to 1
|
|
\pgfmathsetmacro{\FHGR@ratio}{\insertframenumber/\the\count255}
|
|
\pgfmathparse{\FHGR@ratio*\paperwidth}%
|
|
\global\edef\FHGR@pbLen{\pgfmathresult pt}% <-- global!
|
|
\endgroup
|
|
|
|
\begin{tikzpicture}[remember picture,overlay]
|
|
\fill[FHGRDeco] (current page.south west)
|
|
rectangle ([xshift=\FHGR@pbLen,yshift=1pt] current page.south west);
|
|
\end{tikzpicture}%
|
|
\fi
|
|
}
|
|
|
|
% =============================
|
|
% Background & title page
|
|
% =============================
|
|
|
|
% Deliberately empty: the page colour comes from \pagecolor (see "Colors"), and
|
|
% \FHGRClosingPage installs its own background template when it needs one.
|
|
\setbeamertemplate{background}{%
|
|
}
|
|
|
|
% Title page, drawn as one tikz overlay: background image (titlebg,
|
|
% titlefillimage), fade PNG (titlegradient), logo (biglogoblack/biglogowhite,
|
|
% picked by `dark'), \inserttitle/\insertsubtitle, then the author meta line
|
|
% built from \author + \shortname + \fullname. Activated at the end of this
|
|
% block; render it with \FHGRTitlePage or beamer's plain \titlepage.
|
|
\defbeamertemplate*{title page}{FHGR}[1][]{%
|
|
\begingroup
|
|
\begin{tikzpicture}[remember picture,overlay]
|
|
|
|
% Full-page background image
|
|
\ifx\FHGR@titlebg\@empty\relax\else
|
|
\IfFileExists{\FHGR@titlebg}{%
|
|
\node[
|
|
anchor=south west,
|
|
inner sep=0pt,
|
|
outer sep=0pt
|
|
] at (current page.south west) {%
|
|
\ifFHGR@titlefillimage
|
|
\includegraphics[
|
|
width=\paperwidth,
|
|
height=\paperheight,
|
|
keepaspectratio=false
|
|
]{\FHGR@titlebg}%
|
|
\else
|
|
\includegraphics[
|
|
width=\paperwidth,
|
|
height=\paperheight,
|
|
keepaspectratio
|
|
]{\FHGR@titlebg}%
|
|
\fi
|
|
};
|
|
}{}%
|
|
\fi
|
|
|
|
% Smooth gradient overlay using PNG with alpha channel
|
|
\ifFHGR@titlegradient
|
|
\ifFHGR@dark
|
|
\IfFileExists{pics/theme_pics/titlefade_dark.png}{%
|
|
\node[
|
|
anchor=south west,
|
|
inner sep=0pt,
|
|
outer sep=0pt
|
|
] at (current page.south west) {%
|
|
\includegraphics[
|
|
width=\paperwidth,
|
|
height=\paperheight
|
|
]{pics/theme_pics/titlefade_dark.png}%
|
|
};
|
|
}{}%
|
|
\else
|
|
\IfFileExists{pics/theme_pics/titlefade_light.png}{%
|
|
\node[
|
|
anchor=south west,
|
|
inner sep=0pt,
|
|
outer sep=0pt
|
|
] at (current page.south west) {%
|
|
\includegraphics[
|
|
width=\paperwidth,
|
|
height=\paperheight
|
|
]{pics/theme_pics/titlefade_light.png}%
|
|
};
|
|
}{}%
|
|
\fi
|
|
\fi
|
|
|
|
% Logo top-left
|
|
\ifFHGR@dark
|
|
\IfFileExists{\FHGR@biglogowhite}{%
|
|
\node[
|
|
anchor=north west,
|
|
inner sep=0mm,
|
|
outer sep=3mm
|
|
] at (current page.north west) {%
|
|
\includegraphics[height=2.5em]{\FHGR@biglogowhite}%
|
|
};
|
|
}{}%
|
|
\else
|
|
\IfFileExists{\FHGR@biglogoblack}{%
|
|
\node[
|
|
anchor=north west,
|
|
inner sep=0mm,
|
|
outer sep=3mm
|
|
] at (current page.north west) {%
|
|
\includegraphics[height=2.5em]{\FHGR@biglogoblack}%
|
|
};
|
|
}{}%
|
|
\fi
|
|
|
|
% Title/subtitle block
|
|
\node[
|
|
anchor=south west,
|
|
text width=.8\paperwidth,
|
|
inner sep=0pt
|
|
] at ([xshift=8mm,yshift=25mm]current page.south west) {%
|
|
{\usebeamerfont{title}\color{FHGRTxt}\bfseries\inserttitle\par}
|
|
\vspace{0.6ex}
|
|
{\usebeamerfont{subtitle}\color{FHGRTxt}\insertsubtitle\par}
|
|
};
|
|
|
|
% Author/meta line at the very bottom-left
|
|
\node[
|
|
anchor=south west,
|
|
inner sep=0pt
|
|
] at ([xshift=1mm,yshift=1mm]current page.south west) {%
|
|
{\scriptsize\color{FHGRDeco}\FHGR@titlemeta}
|
|
};
|
|
|
|
\end{tikzpicture}
|
|
\endgroup
|
|
}
|
|
|
|
% ============================================
|
|
% \FHGRTitlePage[<extra>]
|
|
% - wraps \titlepage in one [plain,noframenumbering] frame, so the title slide
|
|
% carries no headline/footline and is not counted
|
|
% - <extra> is placed inside that frame, after the title page:
|
|
% \FHGRTitlePage
|
|
% \FHGRTitlePage[\note{Welcome, introduce yourself}]
|
|
% ============================================
|
|
\newcommand{\FHGRTitlePage}[1][]{%
|
|
\begin{frame}[plain,noframenumbering]
|
|
\titlepage
|
|
#1
|
|
\end{frame}
|
|
}
|
|
|
|
|
|
|
|
|
|
% Select our title page
|
|
\setbeamertemplate{title page}[FHGR]
|
|
|
|
% =============================
|
|
% Appendix
|
|
% Write \appendix before your backup slides: appendixnumberbeamer restarts
|
|
% the frame numbering there, and the \pretocmd below additionally swaps in a
|
|
% footline without the "n / total" counter, so backup slides are not counted.
|
|
% (The \makeatletter/\makeatother pairs in this file are no-ops inside a .sty;
|
|
% they are kept so these blocks can be pasted into a preamble unchanged.)
|
|
% =============================
|
|
|
|
% Bookmarks are plain PDF strings, where \translate cannot be executed: make it
|
|
% expand to its argument so translated headings stay readable in the outline.
|
|
\makeatletter
|
|
\pdfstringdefDisableCommands{%
|
|
\let\translate\@firstofone % \translate{Text} -> "Text"
|
|
}
|
|
\makeatother
|
|
|
|
|
|
\makeatletter
|
|
\pretocmd{\appendix}{%
|
|
% Footline without the frame counter (the appendix restarts numbering, so a
|
|
% "n / total" reading from here on would be misleading).
|
|
\setbeamertemplate{footline}{%
|
|
\leavevmode
|
|
\hbox{\begin{beamercolorbox}[wd=\paperwidth,ht=2.8ex,dp=1.2ex,leftskip=1em,rightskip=1em]{}
|
|
\ifFHGR@dark
|
|
\ifx\FHGR@logowhite\@empty\relax\else
|
|
\IfFileExists{\FHGR@logowhite}{\raisebox{-0.1ex}{\includegraphics[height=3em]{\FHGR@logowhite}}}{}%
|
|
\fi
|
|
\else
|
|
\ifx\FHGR@logo\@empty\relax\else
|
|
\IfFileExists{\FHGR@logo}{\raisebox{-0.1ex}{\includegraphics[height=3em]{\FHGR@logo}}}{}%
|
|
\fi
|
|
\fi
|
|
{\scriptsize \color{FHGRDeco}\FHGR@footmeta}
|
|
\hfill
|
|
\end{beamercolorbox}}%
|
|
}%
|
|
}{}{}
|
|
\makeatother
|
|
|
|
% ============================================
|
|
% TOC frame with image on the left
|
|
% \FHGRToC[<toc options>][<image>]{<title>}[<extra>]
|
|
% - <toc options> -> passed to \tableofcontents
|
|
% e.g. currentsection,currentsubsection
|
|
% - <image> -> optional; if empty use \FHGR@titlebg
|
|
% - <title> -> frame title, set in the frametitle font/colour
|
|
% - <extra> -> optional; added at the end of the frame, e.g. \note{...}
|
|
% Examples:
|
|
% \FHGRToC{Agenda}
|
|
% \FHGRToC[currentsection][pics/chapter2.png]{Where we are}
|
|
% ============================================
|
|
|
|
% Internal helper (used by \FHGRToC): image + fade on the left half of the
|
|
% slide, then an opaque FHGRBg panel on the right half to hold the ToC.
|
|
\makeatletter
|
|
\newcommand{\FHGR@tocimage}[1]{%
|
|
\begin{tikzpicture}[remember picture,overlay]
|
|
% Decide which image to use: argument or fallback to titlebg
|
|
\def\FHGR@img{#1}%
|
|
\ifx\FHGR@img\@empty
|
|
\def\FHGR@img{\FHGR@titlebg}%
|
|
\fi
|
|
|
|
% Draw image on the left half, full height
|
|
\ifx\FHGR@img\@empty\relax\else
|
|
\IfFileExists{\FHGR@img}{%
|
|
\node[
|
|
anchor=south west,
|
|
inner sep=0pt,
|
|
outer sep=0pt
|
|
] at (current page.south west)
|
|
{\includegraphics[height=\paperheight]{\FHGR@img}};
|
|
}{}%
|
|
\fi
|
|
|
|
% Gradient overlay on the image half
|
|
\ifFHGR@titlegradient
|
|
\ifFHGR@dark
|
|
\IfFileExists{pics/theme_pics/titlefade_dark.png}{%
|
|
\node[
|
|
anchor=south west,
|
|
inner sep=0pt,
|
|
outer sep=0pt
|
|
] at (current page.south west)
|
|
{\includegraphics[width=.5\paperwidth,height=\paperheight]{pics/theme_pics/titlefade_dark.png}};
|
|
}{}%
|
|
\else
|
|
\IfFileExists{pics/theme_pics/titlefade_light.png}{%
|
|
\node[
|
|
anchor=south west,
|
|
inner sep=0pt,
|
|
outer sep=0pt
|
|
] at (current page.south west)
|
|
{\includegraphics[width=.5\paperwidth,height=\paperheight]{pics/theme_pics/titlefade_light.png}};
|
|
}{}%
|
|
\fi
|
|
\fi
|
|
|
|
% Panel on the right half for the table of contents
|
|
\fill[FHGRBg]
|
|
([xshift=-.5\paperwidth]current page.north east)
|
|
rectangle
|
|
(current page.south east);
|
|
\end{tikzpicture}%
|
|
}
|
|
|
|
% \FHGRToC[<toc options>][<image>]{<title>}[<extra>] -- see the block above
|
|
\NewDocumentCommand{\FHGRToC}{ O{} O{} m O{}}{%
|
|
\begin{frame}
|
|
\FHGR@tocimage{#2}%
|
|
\begin{columns}[T,totalwidth=\paperwidth]
|
|
\column{0.5\paperwidth}
|
|
\column{0.5\paperwidth}
|
|
{\usebeamerfont{frametitle}%
|
|
\usebeamercolor[fg]{frametitle}%
|
|
\raggedright #3\par}%
|
|
\vspace{2em}%
|
|
\tableofcontents[#1]
|
|
\end{columns}
|
|
#4
|
|
\end{frame}
|
|
}
|
|
\makeatother
|
|
|
|
% ============================================
|
|
% Final slide
|
|
%
|
|
% \FHGRClosingPage [<image>] [<text>] -> fills slide (may stretch)
|
|
% \FHGRClosingPage*[<image>] [<text>] -> keepaspectratio
|
|
% - If <image> empty: uses \FHGR@titlebg
|
|
% - <text> optional: centered on slide
|
|
% Examples:
|
|
% \FHGRClosingPage % background only
|
|
% \FHGRClosingPage[][Thank you!] % default image + centered text
|
|
% \FHGRClosingPage*[pics/outro.png][Q&A] % own image, aspect kept
|
|
% \usebackgroundtemplate is set inside a \begingroup, so the background does
|
|
% not leak into the following slides. The frame itself is counted as usual.
|
|
% ============================================
|
|
|
|
\makeatletter
|
|
\NewDocumentCommand{\FHGRClosingPage}{ s O{} O{} }{%
|
|
\begingroup
|
|
|
|
% Decide which image to use: argument or fallback to titlebg
|
|
\def\FHGR@img{#2}%
|
|
\ifx\FHGR@img\@empty
|
|
\def\FHGR@img{\FHGR@titlebg}%
|
|
\fi
|
|
|
|
% Background image
|
|
\ifx\FHGR@img\@empty\relax\else
|
|
\IfFileExists{\FHGR@img}{%
|
|
\IfBooleanTF{#1}{%
|
|
% Starred: keep aspect ratio
|
|
\usebackgroundtemplate{%
|
|
\vbox to \paperheight{%
|
|
\vfil
|
|
\hbox to \paperwidth{%
|
|
\hfil
|
|
\includegraphics[
|
|
width=\paperwidth,
|
|
height=\paperheight,
|
|
keepaspectratio
|
|
]{\FHGR@img}%
|
|
\hfil
|
|
}%
|
|
\vfil
|
|
}%
|
|
}%
|
|
}{%
|
|
% Unstarred: fill whole slide
|
|
\usebackgroundtemplate{%
|
|
{\setkeys{Gin}{keepaspectratio=false}%
|
|
\includegraphics[
|
|
width=\paperwidth,
|
|
height=\paperheight
|
|
]{\FHGR@img}}%
|
|
}%
|
|
}%
|
|
}{}%
|
|
\fi
|
|
|
|
\frame{%
|
|
% Gradient overlay across the whole slide
|
|
\ifFHGR@titlegradient
|
|
\begin{tikzpicture}[remember picture,overlay]
|
|
\ifFHGR@dark
|
|
\IfFileExists{pics/theme_pics/titlefade_dark.png}{%
|
|
\node[
|
|
anchor=south west,
|
|
inner sep=0pt,
|
|
outer sep=0pt
|
|
] at (current page.south west) {%
|
|
\includegraphics[
|
|
width=\paperwidth,
|
|
height=\paperheight
|
|
]{pics/theme_pics/titlefade_dark.png}%
|
|
};
|
|
}{}%
|
|
\else
|
|
\IfFileExists{pics/theme_pics/titlefade_light.png}{%
|
|
\node[
|
|
anchor=south west,
|
|
inner sep=0pt,
|
|
outer sep=0pt
|
|
] at (current page.south west) {%
|
|
\includegraphics[
|
|
width=\paperwidth,
|
|
height=\paperheight
|
|
]{pics/theme_pics/titlefade_light.png}%
|
|
};
|
|
}{}%
|
|
\fi
|
|
\end{tikzpicture}%
|
|
\fi
|
|
|
|
% Optional centered text
|
|
\def\FHGR@finaltext{#3}%
|
|
\ifx\FHGR@finaltext\@empty\relax\else
|
|
\begin{tikzpicture}[remember picture,overlay]
|
|
\node[
|
|
anchor=center,
|
|
align=center
|
|
] at (current page.center) {%
|
|
{\usebeamerfont{title}\bfseries\color{FHGRTxt}\FHGR@finaltext}
|
|
};
|
|
\end{tikzpicture}%
|
|
\fi
|
|
}%
|
|
|
|
\endgroup
|
|
}
|
|
\makeatother
|
|
|
|
% =============================
|
|
% Convenience commands: small attribution lines, e.g. under a figure.
|
|
% \credit{Jane Doe} -> "Credit: Jane Doe"
|
|
% \imagesource{FHGR} -> "Bildquelle: FHGR"
|
|
% \source{Studie 2024} -> "Quelle: Studie 2024"
|
|
% Each one breaks the paragraph and flushes right, \tiny italic in FHGRDeco.
|
|
% Only the label differs -- pick by language, or \renewcommand one of them.
|
|
% =============================
|
|
\newcommand{\credit}[1]{\par\hfill {\tiny\color{FHGRDeco} Credit:\,\itshape #1}}
|
|
\newcommand{\imagesource}[1]{\par\hfill {\tiny\color{FHGRDeco} Bildquelle:\,\itshape #1}}
|
|
\newcommand{\source}[1]{\par\hfill {\tiny\color{FHGRDeco} Quelle:\,\itshape #1}}
|
|
|
|
% =============================
|
|
% End of file
|
|
% =============================
|