% Maximilian Stabel (c) 2023
% inspired by LaTeX cookbook https://github.com/alexpovel/latex-cookbook/

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{ethesis}[2023/11/18 ETH Zurich thesis package collection]

% Require LuaTex and fail early if another engine is used
\RequirePackage{iftex}
\RequireLuaTeX{}

\RequirePackage{kvoptions}
\SetupKeyvalOptions{
    family=ETH,
    prefix=ETH@
} % user shorter prefix ETH (instead of ethesis)
%\DeclareStringOption[initial (always set)]{keyname}[default (aka. default value if key is provided)]
\DeclareBoolOption{debug}
\DeclareStringOption[english]{language}  % Passed to polyglossia, e.g. english or german
\DeclareDefaultOption{%
    \ifx\CurrentOptionValue\relax
    \PackageWarningNoLine{\@currname}{
        Unknown option '\CurrentOption'\MessageBreak
    }
    % Pass through any option (overwriting defaults) and load it
    \expandafter\PassOptionsToClass{\expandafter\CurrentOption}{\@baseclass}
}
\ProcessKeyvalOptions*

% Print warning on unknown option
% \DeclareOption*{\PackageWarning{examplepackage}{Unknown '\CurrentOption'}}
% \ProcessOptions\relax  % Execute above options


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Debug
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\ifETH@debug
    \RequirePackage{showframe} 	% Shows boxes around the text area, margin, header and footer
    \RequirePackage{showlabels} % Output the content of \label commands to the document where they are used
    \KOMAoptions{draft=true}		% Print markers for overfull boxes/lines
\fi

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Set language
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Use English
\RequirePackage{polyglossia}
\setmainlanguage{english}
\RequirePackage[english=british,autostyle=true]{csquotes}
\RequirePackage[\ETH@language]{tracklang}  % Language Tracking, i.e. what has polyglossia been requested to use?


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Typography and Misc.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\RequirePackage{etoolbox}  	% Programming facilities
\RequirePackage{xpatch}     % Enhanced version of etoolbox
\RequirePackage{import}		% Relative path imports
\RequirePackage{pdflscape} 	% Pages in landscape format
\RequirePackage{xspace}
\RequirePackage[listings=false]{scrhack}
\RequirePackage[inline]{enumitem}  % For inline enumerations


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Scientifics Typesetting
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\RequirePackage{chemmacros}% \ch{}, \chcpd[]{compound} etc.
\chemsetup{%
    formula=chemformula,%
    chemformula/font-family=tgpl,% Use math font family
}

% Some new custom environments. Very simple definitions that behave just like the
% widely known AMSMath math environment as specified in the last argument.
\NewChemReaction{reactionsgather}{gather}% Like AMSmath's `gather`
\NewChemReaction{reactionsgather*}{gather*}

% Sort reaction counter underneath chapter, see
% https://tex.stackexchange.com/questions/530210/how-to-cross-reference-reactions-in-chemmacros-chapter#comment1340793_530210
\renewcommand*{\thereaction}{\thechapter.\arabic{reaction}}

\RequirePackage{siunitx}% Typesetting physical units correctly
\sisetup{%
    % For siunitx v3, the following block replaces what used to be
    % `detect-all` (removed in that release, see
    % https://github.com/josephwright/siunitx/blob/main/CHANGELOG.md#v300 ).
    % It allows the `siunitx` output to match surrounding text/math (italics/bold/...,
    % roman/sans/... etc. as much as possible)
    mode=match,
    propagate-math-font=true,
    reset-math-version=false,
    reset-text-family=false,
    reset-text-series=false,
    reset-text-shape=false,% Not part of official fix, but still added (see https://collaborating.tuhh.de/alex/latex-cookbook/-/issues/8)
    text-family-to-math=true,
    text-series-to-math=true,
    %
    % Requires siunitx v3+, see also https://tex.stackexchange.com/a/468031/120853,
    % https://github.com/josephwright/siunitx/issues/532 :
    text-font-command=\unitnumberfont,
    %
    % Alternative range-phrase:
    % en-dash via '--', but inside \text{}, so it's not 'two minus signs'
    % range-phrase={\,\text{--}\,},
    range-units=single,% single: Print unit only once, at end
    per-mode=symbol,
}%
% Second setup step, with locales. See also
% https://tex.stackexchange.com/a/46979/120853
\gappto{\blockextras@german}{%
    \sisetup{locale=DE}
}
\gappto{\blockextras@english}{%
    \sisetup{locale=US}
}

% Declare units ourselves:
% Set as text so it stays a hyphen in math mode, as opposed to minus sign
\DeclareSIUnit{\volpercent}{Vol.\text{-}\%}
\DeclareSIUnit{\watthour}{Wh}%
\DeclareSIUnit{\annum}{a}%
\DeclareSIUnit{\atmosphere}{atm}%
\DeclareSIUnit{\partspermillion}{ppm}%
\DeclareSIUnit{\bar}{bar}% https://tex.stackexchange.com/a/598473/120853
\DeclareSIUnit{\sample}{S}
\DeclareSIUnit{\belm}{Bm}
\DeclareSIUnit{\beluv}{uV}
\DeclareSIUnit{\vpp}{\(\text{V}_{\text{pp}}\)}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Tikz + Plots
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\RequirePackage{pgfplots}		% Also loads Tikz
\pgfplotsset{compat=1.18}       % Set compatibility version. Can be updated as required
\RequirePackage{pgfplotstable}	% For advanced table calcs, e.g. 'y expr' to mathematically process input data:
\RequirePackage[edges]{forest}	% Comprehensive trees
\RequirePackage{tikz-3dplot}
\RequirePackage[european, siunitx]{circuitikz}

% Only use libraries as needed to keep compilation times low
\usetikzlibrary{
    positioning,	% Relative positioning etc.
    calc,			% Calculate distances, coordinates etc.
    shapes, 		% For cross out
    backgrounds,	% Draw on background layer
    fit,			% Fit new node around existing coordinates
    decorations,
    arrows,
    arrows.spaced,
    intersections,
    trees,
    % circuits.ee.IEC,% Electrical engineering circuits lib, using circuitikz instead!
    patterns,
    3d,
    tikzmark,		% Marks/coordinates at arbitrary positions
}
\usepgfplotslibrary{
    colorbrewer,
    units,
    dateplot,
    fillbetween,
    groupplots,
}

% Print a contour around letters, e.g. black text with a white border on some noisy
% background, so that text remains legible.
% NOT COMPATIBLE WITH XELATEX! Requires pdflatex or lualatex (our case)
\RequirePackage[outline]{contour}
\contourlength{0.12em}

\newcommand*{\ctrw}[1]{% Black text, white contour
    \hypersetup{hidelinks}% Hide links, which might be colored
    \contour{white}{\textcolor{black}{#1}}%
}%

\newcommand*{\ctrb}[1]{% White text, black contour
    \hypersetup{hidelinks}% Hide links, which might be colored
    \contour{black}{\textcolor{white}{#1}}%
}



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Colour
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Load this before unicode-math font specifications to make colors available there
\RequirePackage[usenames,dvipsnames]{xcolor}

% ETH color scheme
% https://ethz.ch/staffnet/en/service/communication/corporate-design/farbe.html

% ETH Blue
\definecolor{blue}{HTML}{215CAF}
\definecolor{blue8}{HTML}{4D7DBF}
\definecolor{blue6}{HTML}{7A9DCF}
\definecolor{blue4}{HTML}{A6BEDF}
\definecolor{blue2}{HTML}{D3DEEF}
\definecolor{blue1}{HTML}{E9EFF7}
\definecolor{blued}{HTML}{08407E}

% ETH Petrol
\definecolor{petrol}{HTML}{007894}
\definecolor{petrol8}{HTML}{3395AB}
\definecolor{petrol6}{HTML}{66AFC0}
\definecolor{petrol4}{HTML}{99CAD5}
\definecolor{petrol2}{HTML}{CCE4EA}
\definecolor{petrol1}{HTML}{E7F4F7}
\definecolor{petrold}{HTML}{00596D}

% ETH Green
\definecolor{green}{HTML}{627313}
\definecolor{green8}{HTML}{818F42}
\definecolor{green6}{HTML}{A1AB71}
\definecolor{green4}{HTML}{C0C7A1}
\definecolor{green2}{HTML}{E0E3D0}
\definecolor{green1}{HTML}{EFF1E7}
\definecolor{greend}{HTML}{365213}

% ETH Bronze
\definecolor{bronze}{HTML}{8E6713}
\definecolor{bronze8}{HTML}{A58542}
\definecolor{bronze6}{HTML}{BBA471}
\definecolor{bronze4}{HTML}{D2C2A1}
\definecolor{bronze2}{HTML}{E8E1D0}
\definecolor{bronze1}{HTML}{F4F0E7}
\definecolor{bronzed}{HTML}{956013}

% ETH Red
\definecolor{red}{HTML}{B7352D}
\definecolor{red8}{HTML}{C55D57}
\definecolor{red6}{HTML}{D48681}
\definecolor{red4}{HTML}{E2AEAB}
\definecolor{red2}{HTML}{F1D7D5}
\definecolor{red1}{HTML}{F8EBEA}
\definecolor{redd}{HTML}{96272D}

% ETH Purple
\definecolor{purple}{HTML}{A30774}
\definecolor{purple8}{HTML}{B73B92}
\definecolor{purple6}{HTML}{CA6CAE}
\definecolor{purple4}{HTML}{DC9EC9}
\definecolor{purple2}{HTML}{EFD0E3}
\definecolor{purple1}{HTML}{F8E8F3}
\definecolor{purpled}{HTML}{8C0A59}

% ETH Grey
\definecolor{grey}{HTML}{6F6F6F}
\definecolor{grey8}{HTML}{8C8C8C}
\definecolor{grey6}{HTML}{A9A9A9}
\definecolor{grey4}{HTML}{C5C5C5}
\definecolor{grey2}{HTML}{E2E2E2}
\definecolor{grey1}{HTML}{F1F1F1}
\definecolor{greyd}{HTML}{575757}

% Use the colors for different things
% Can be redefined by user
\definecolor{blankcolor}{named}{grey8}		% Used for the text on 'blank' pages
\definecolor{chaptercolor}{named}{grey8}	% Used for the big chapter numbers in the title
\definecolor{accentcolor}{named}{redd}  	% Used for accents, e.g. some chapter headings
\definecolor{externallink}{named}{redd} 	% Used for URLs
\definecolor{internallink}{named}{blued}	% Used for links to Figures/Tables/Listings/...
\definecolor{reflink}{named}{greend} 		% Used for links into the bibliography/glossary/index
\definecolor{margincolor}{named}{grey8} 	% Used for the text in the margin
\definecolor{titlecolor}{named}{accentcolor}% Used for the title on the titlepage


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Document metadata commands
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% \title{}, \subtitle{}, \author{}, \date{}
% See also https://stackoverflow.com/a/2833982

% Logo
\newcommand*{\logo}[1]{%
    \renewcommand*{\@logo}{#1}%
}
\newcommand*{\@logo}{%
    \ClassWarning{ethesis}{No \noexpand\logo given}
}

% Born
\newcommand*{\born}[1]{%
    \renewcommand*{\@born}{#1}%
}
\newcommand*{\@born}{%
    \ClassWarning{ethesis}{No \noexpand\born given}
}

% Citizen
\newcommand*{\citizen}[1]{%
    \renewcommand*{\@citizen}{#1}%
}
\newcommand*{\@citizen}{%
    \ClassWarning{ethesis}{No \noexpand\citizen given}
}

% Examiner
\newcommand*{\examiner}[1]{%
    \renewcommand*{\@examiner}{#1}%
}
\newcommand*{\@examiner}{%
    \ClassWarning{ethesis}{No \noexpand\examiner given}
}

% Supervisor
\newcommand*{\supervisor}[1]{%
    \renewcommand*{\@supervisor}{#1}%
}
\newcommand*{\@supervisor}{%
    \ClassWarning{ethesis}{No \noexpand\supervisor given}
}

% Degree
\newcommand*{\degree}[1]{%
    \renewcommand*{\@degree}{#1}%
}
\newcommand*{\@degree}{%
    \ClassWarning{ethesis}{No \noexpand\degree given}
}

% Degree Shorthand / Abbreviation
\newcommand*{\shortdegree}[1]{%
    \renewcommand*{\@shortdegree}{#1}%
}
\newcommand*{\@shortdegree}{%
    \ClassWarning{ethesis}{No \noexpand\shortdegree given}
}

% Student ID number
\newcommand*{\idnumber}[1]{%
    \renewcommand*{\@idnumber}{#1}%
}
\newcommand*{\@idnumber}{%
    \ClassWarning{ethesis}{No \noexpand\idnumber given}%{\@ehc}%
}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Fonts
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\RequirePackage{fontspec}  % Requires LuaLaTeX

% Advanced typesetting for kerning etc.
% Enable tracking (i.e. be able to change the added space between letters)
% Does this by default for smallcaps (textsc/scshape)
\RequirePackage{microtype}
\PassOptionsToPackage{tracking=true}{microtype}
\microtypesetup{protrusion=true,expansion=true}  % classicthesis

% Using 'shortcuts' package option, do e.g. 'fast\-/paced' to get a breakable
% 'fast-pace' word in print.
% Otherwise, LaTeX does not hyphenate/linebreak words that already come with a hyphen,
% since that could be ambiguous
\RequirePackage[shortcuts]{extdash}

% Looking at CTAN, `fontawesome5' looks much more recent and packs many more symbols
% in comparison to `fontawesome'.
% It ships with its own font files, so no need to specify here.
\RequirePackage{fontawesome5}% High-quality Unicode vector web symbols

% Redefine modern kaofonts
\RenewDocumentCommand{\kao@fontmethodModern}{}{%
    \RequirePackage{amssymb}         % Must be loaded before unicode-math
    \RequirePackage[force]{filehook} % Fixes an error
    \RequirePackage{unicode-math}    % Math fonts in xetexorluatex
    \setromanfont[
        Numbers=Lowercase,
        Scale=1.04,
    ]{TeX Gyre Pagella}
    \setsansfont[
        Scale=1,
    ]{Merriweather Sans}
    \setmonofont[
        Scale=0.89,
        AutoFakeSlant,
    ]{inconsolata}
    \setmathfont[
        mathrm=sym,
        mathit=sym,
        mathsf=sym,
        mathbf=sym,
        mathtt=sym,
        NFSSFamily=tgpl,
    ]{TeX Gyre Pagella Math}
    \newfontfamily{\unitnumberfont}[
        % New font family for typesetting units.
        % Required since otherwise, numbers typeset with \qty/\num etc. from siunitx
        % might be hanging if that feature is turned on in the main font (OldStyle numbers).
        % To ensure these physical numbers are always upright, set Numbers:
        Numbers=Uppercase,
        % Color=LightCyan4,% Toggle color for debugging (should be xcolor name)
    ]{TeX Gyre Pagella}% Load existing fond, see also https://tex.stackexchange.com/a/351100/120853
}
\kao@fontmethodModern

% Helper functions with regex to print the current font (LaTeX3)
% Intro to LaTeX3: https://www.latex-project.org/help/documentation/usrguide3.pdf
\ExplSyntaxOn
\cs_generate_variant:Nn \regex_extract_once:nnN { nx }  % Generate nxN variant from nnN variant
\NewDocumentCommand{\matchfirstword}{m}{
    \regex_extract_once:nxN { \A \W*([A-Za-z\-\_]*).* \Z } { #1 } \l_tmpa_seq  % Match regex and store first match
    \seq_item:Nn \l_tmpa_seq {2}  % Print the first group (first element is the whole match, i.e. everything)
}
\NewDocumentCommand{\matchlastnumber}{m}{
    \regex_extract_once:nxN { \d+(\.\d*)?pt } { #1 } \l_tmpb_seq  % Match regex and store first match in \l_tmpb_seq
    \seq_if_empty:NTF \l_tmpb_seq { \f@size{}pt } { \seq_item:Nn \l_tmpb_seq{1} }  % Print the first group, if the sequence is not empty. if it is, print \f@size
}

% Place in group '{}' to "contain" the effects of the '\normalsize' font switch
% define new global command with \tl_gset:Nx,
% first argument is a literal command name (N) thus without braces
% second argument will be fully expanded at time of definition, i.e. now (x)
{ \normalsize \tl_gset:Nx \normalfontsize {\f@size} }
\ExplSyntaxOff

% Convenience functions to show the font and fontsize
%\NewDocumentCommand{\showfont}{}{\directlua{tex.print(font.fonts[font.current()].fullname)}}
\NewDocumentCommand{\showfont}{}{\matchfirstword{\fontname\font}}
\NewDocumentCommand{\mathfont}{}{\matchfirstword{\fontname\textfont0}}
\NewDocumentCommand{\mathoperatorfont}{}{\matchfirstword{\fontname\textfont1}}
\NewDocumentCommand{\showfontsize}{}{\matchlastnumber{\fontname\font}}
\NewDocumentCommand{\mathfontsize}{}{\matchlastnumber{\fontname\textfont0}}
\NewDocumentCommand{\mathoperatorfontsize}{}{\matchlastnumber{\fontname\textfont1}}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Headings (Chapter/Section/...)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Set KOMA fonts for book-specific elements
\addtokomafont{part}{\normalfont\scshape\lsstyle\bfseries}
\addtokomafont{partentry}{\normalfont\scshape\lsstyle\bfseries}
\addtokomafont{chapter}{\normalfont\scshape\lsstyle}
\addtokomafont{chapterentry}{\normalfont\scshape\lsstyle}

% Set KOMA fonts for elements common to all classes
\addtokomafont{section}{\normalfont\scshape\lsstyle}%\MakeLowercase}
\addtokomafont{subsection}{\normalfont\scshape\lsstyle}%\MakeLowercase}
\addtokomafont{subsubsection}{\normalfont\scshape\lsstyle}%\MakeLowercase}
\addtokomafont{paragraph}{\normalfont\normalsize}
\setkomafont{descriptionlabel}{\normalfont\scshape\lsstyle}

% Dictum (Inspirational Quote/Schlauer Spruch below part/chapter/section heading)
\renewcommand*{\dictumwidth}{0.5\textwidth}
\renewcommand*{\dictumauthorformat}[1]{--- #1\bigskip}
\setkomafont{dictum}{\normalfont\normalcolor\itshape\small}
\setkomafont{dictumauthor}{\upshape}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Graphics
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\RequirePackage{graphicx}
\graphicspath{{images/}{figures/}{pictures/}{plots/}{schematics/}{./}{data/}}  % Paths in which to look for images

\RequirePackage{svg}
% See also:
% https://tex.stackexchange.com/a/158612/120853.
% pdftexcmds package etc. no longer seems necessary.
% svg package documentation states that it is a dependency, but done automatically.
% https://tex.stackexchange.com/a/74693/120853

% Build failed on my system due to lack of the 'canberra' module,
% see for a fix: https://askubuntu.com/a/872397/978477

% Running the document to generate the PDF and PDF_TEX file from the original SVG
% will require SHELL ESCAPE (--shell-escape), aka elevation.
% However, after the auxiliary images have been created, they only need to be input;
% shell-escape will no longer be required.
\svgsetup{%
    inkscapepath=svgsubdir,% Put into subdirectory of where original SVG was found
    % In most cases, we include SVGs that contain no text, then add it in a
    % tikzpicture overlay. Therefore, don't generate *.pdf_tex file.
    % Toggle this back to true wherever needed, on a per-file basis
    inkscapelatex=false,
}

% When placing nodes over included SVGs using Tikz,
% we require some help to debug the positions:
\newcommand*{\debugtikzsvg}{%
    % This has to be evoked within a TikZ scope of:
    % `\begin{scope}[x={(image.south east)},y={(image.north west)}]`
    % The image we invoke the grid "on top of" needs to be labelled "image":
    \draw[help lines, xstep=0.02,ystep=0.02, opacity=0.5]
    (image.south west) grid (image.north east);
    \draw[gray, thick, xstep=0.1,ystep=0.1, opacity=0.8]
    (image.south west) grid (image.north east);
    %
    \foreach \posfraction in {%
            0, 0.1, ...,1%
        }{%
            \foreach \startpoint/\endpoint/\nodeorientation in {% 2D-grid
                    south west/south east/below,%
                    north west/north east/above,%
                    south east/north east/right,%
                    south west/north west/left%
                }{
                    \node[\nodeorientation, opacity=0.5]
                    at ($(image.\startpoint)!\posfraction!(image.\endpoint)$)
                    {%
                        \pgfmathparse{int(\posfraction*10)}% Round result
                        \num{\pgfmathresult}%
                    };
                }%
        }%
}%

\NewDocumentCommand{\captiontitle}{m}{\textbf{#1}}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Typeset code snippets
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\RequirePackage[%
    outputdir=out,  % must match build dir in .latexmkrc!
]{minted}

\setminted{% Global `minted` aka code syntax highlighting options
    % If code is indented in the LaTeX source, this is reflected in the print.
    % This option automatically removes as much whitespace as the first line of a listing
    % is indented by (note: requires `python` to be available, not only `pygmentize`)
    autogobble=true,
    %
    % Assuming the code to be displayed is written at 80-90 characters per line,
    % \footnotesize makes sure it fits onto one line (roughly).
    fontsize=\footnotesize,
    %
    breaklines=true,
    breakanywhere=false, % default "false"; could be ugly, only use if required
    breakbytokenanywhere=true, % Breaks tokens on non-spaces too
    %
    % Regular LaTeX can occur in these (on UK Keyboard: SHIFT+`).
    % Otherwise, you'll have to copy-paste this whenever needed.
    % The problem is that the escapechar has to be quite exotic so it never occurs
    % in source code.
    escapeinside=¬¬,
    %
    frame=leftline, % leftline pulls it together visually quite nicely
    framerule=1pt, % default is 0.4pt
    rulecolor=\color{grey4},
    %
    numbers=left,
    numberfirstline=true, % Always color the first line despite `stepnumber` setting
    % stepnumber=5, % Interval of line numbering
    numbersep=2pt, % Horizontal distance between line number and line
    %
    % Used highlighting style, see https://pygments.org/demo/#try or `python -m pygments -L`
    % For colorful output, I like:
    % `paraiso-light` (prob. too light for print), `manni`, `tango`, `lovelace`
    % For grayscale:
    % `algol`
    style=manni,  %xcode?
}

\setmintedinline{% Overwrite `\setminted` settings
    fontsize=auto,% Reset to surrounding font size so its fits into the text flow
}

% Set up the floating environment, e.g. what is says in the caption of floats:
% \SetupFloatingEnvironment{listing}{% Requires `newfloat` usage, kaobook already defines style for old "float" package
%     name=\TransListing{},
%     listname=\TransListOfListings{},
% }
% Create a new environment for breaking code listings across pages.
% see: https://github.com/gpoore/minted/issues/189
\newenvironment{longlisting}{\captionsetup{type=listing}}{}
% Setup for referencing the floats correctly is done in `cleveref` settings!

% In code environments, to be able to copy from the PDF (despite that not being a good
% idea usually), we want the line numbers to not be part of the selection.
% This command prints them, but renders the actual copied content empty,
% on supported readers like Adobe Acrobat.
\RequirePackage{accsupp}% https://tex.stackexchange.com/a/57160/120853

\newcommand*{\emptyaccsupp}[1]{%
    \BeginAccSupp{ActualText={}}#1\EndAccSupp{}%
}%

\renewcommand*{\theFancyVerbLine}{ % Redefine how line numbers are printed
    \textcolor{grey}{\ttfamily\tiny\emptyaccsupp{\arabic{FancyVerbLine}}}
}

% Colors for escaped, normal LaTeX in code environments
\newcommand*{\phstring}[1]{%
    \textcolor{red}{#1}%
}%
\newcommand*{\phnum}[1]{%
    \textcolor{blue}{#1}%
}%
\newcommand*{\phother}[1]{%
    \textcolor{green}{#1}%
}%
\newcommand*{\phnote}[1]{%
    {%
            \hypersetup{allcolors=bronze}% If references occur in here
            \textbf{\textcolor{bronze}{#1}}%
        }%
}%


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Penalties
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\clubpenalty         = 10000  % No single line at the end of a page
\widowpenalty        = 10000  % No single line at the beginning of a page
\displaywidowpenalty = 10000  % No single line of an equation on a new page

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Deliberately blank pages
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Alternative to fancyhdr. KOMA-script for page/header/footer layout
\RequirePackage{scrlayer-scrpage}  % automark headers and footers with current chapter

% https://tex.stackexchange.com/a/205536/120853
\renewcommand*{\blankpage}{
    \par\vspace*{\fill}
    \begin{center}
        \textcolor{blankcolor}{
            This page intentionally left blank.%
            % https://web.archive.org/web/20041119090707/https://www3.epa.gov/ttn/oarpg/t1/memoranda/eipfin.pdf
        }
    \end{center}
    \vspace{\fill}
}

\DeclareNewLayer[%
    foreground,%
    textarea,%
    contents=\blankpage,%
]{blankpage.fg}
\DeclarePageStyleByLayers{blank}{blankpage.fg}
\KOMAoptions{cleardoublepage=blank}              % Blank page before new chapter and other cleardouble
\patchcmd{\partheademptypage}{empty}{blank}{}{}  % Blank page also after part page


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% System Information Banner
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Provides \hologo and \Hologo to typeset various logos, like the LuaLaTeX logo.
\RequirePackage{hologo}

% Using fontspec, this document is incompatible with anything but XeLaTeX/LuaLaTeX.
% LuaLaTeX can grab additional memory as needed, therefore no issues with tikz and no
% need to tikzexternalize (!).
% Further, contour-package and XeLaTeX are strictly incompatible (LuaLaTeX works).
% Therefore, only ever use LuaLaTeX anyway.

\RequirePackage{xstring}% String manipulation macros

% Print only what occurs after 'This is ' and store in macro given in brackets at end.
% luatexbanner is provided by luatex engine, but prints 'This is luatex XYX' usually.
% https://tex.stackexchange.com/a/394043/120853
\StrBehind*{\luatexbanner}{This is }[\shortbanner]

% Take input and substitute strings; here: make plain LuaTeX string into pretty logo.
% StrSubstitue has no starred variant, therefore dekotenize.
% https://tex.stackexchange.com/a/350583/120853
\StrSubstitute{\shortbanner}{\detokenize{LuaTeX}}{\hologo{LuaTeX}}[\prettybanner]

% Generate some control sequences which contain metadata, which can be inserted e.g.
% into the PDF metadata (e.g. to have the exact git commit SHA of a build).
% See % https://www.overleaf.com/learn/latex/Articles/An_Introduction_to_LuaTeX_(Part_2):_Understanding_%5Cdirectlua
% for how to inline Lua code in TeX.
% It's an absolute abomination; the below code first passes through TeX, gets expanded,
% then gets processed by Lua.
% Hence, there is a lot of escaping going on.
\directlua{%
local function get_cmd_stdout(cmd)
% -- See: https://stackoverflow.com/a/326715/11477374
local fh = assert(io.popen(cmd))
local first_line = assert(fh:read())
fh:close()
return first_line
end
%
% -- Environment variables as used e.g. in GitLab CI.
% -- Otherwise, e.g. when developing locally, use commands as a fallback.
local macro_content_sources = {
GitRefName = {
        env = "CI_COMMIT_REF_NAME",
        cmd = "git rev-parse --abbrev-ref HEAD",
    },
GitShortSHA = {
        env = "CI_COMMIT_SHORT_SHA",
        cmd = "git rev-parse --short HEAD",
    },
}
%
for macro_name, content_sources in pairs(macro_content_sources) do
% -- Default: check for environment variable:
local env = content_sources.env
local cmd = content_sources.cmd
% -- Default value:
local content = "n.a."
local env_content = os.getenv(env)
%
% -- Empty string evaluates to true:
if env_content and env_content \noexpand~= "" then
texio.write_nl("Found and will be using environment variable '"..env.."'.")
content = env_content
else
texio.write_nl("Environment variable '"..env.."' undefined or empty, trying fallback command.")
% -- luatex reference for shell escape:
% -- "0 means disabled, 1 means anything is permitted, and 2 is restricted"
if status.shell_escape == 1 then
local cmd_success, cmd_stdout = pcall(get_cmd_stdout, cmd)
if cmd_success then
texio.write_nl("Fallback command '"..cmd.."' succeeded.")
content = cmd_stdout
else
texio.write_nl("Fallback command '"..cmd.."' unsuccessful.")
end
else
texio.write_nl("shell-escape is disabled, cannot use fallback command.")
end
end
%
% -- Shouldn't happen, would be programmer error, therefore assert Python-style
assert(content, "Content not defined (neither success nor fallback present)")
%
% --[[
%     The `content` can contain unprintable characters, like underscores in git branch
%     names. Towards this end, use detokenize in the macro itself, which will make all
%     characters printable (assigns category code 12). See also:
%     https://www.overleaf.com/learn/latex/Articles/An_Introduction_to_LuaTeX_(Part_2):_Understanding_%5Cdirectlua
% --]]
local escaped_content = "\unexpanded{\\detokenize{"..content.."}"}
%
texio.write_nl("Providing new macro '"..macro_name.."' with contents: '"..escaped_content.."'.")
% --  Set a macro (newcommand) see also: https://tex.stackexchange.com/a/450892/120853
token.set_macro(macro_name, escaped_content)
end
}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Arrays / Tables
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\RequirePackage{tabu}  % For longtabu in the glossary

\RequirePackage{array}
\newcolumntype{M}[1]{>{\centering\arraybackslash}m{#1}}  % Vert.+Hor. centered cells

% A command to have a cell with vertical text as a multirow:
\newcommand*{\multirotatecell}[2]{%
    \multirow{#1}{*}{%
        \begin{tabular}{@{}c@{}}%
            \rotatebox[origin=c]{90}{#2}%
        \end{tabular}%
    }%
}%

\RequirePackage{tabularray} % Powerful, up and coming package
\UseTblrLibrary{booktabs}   % Get `\toprule` etc. for tabularrays
\UseTblrLibrary{siunitx}    % Get S column type

\RequirePackage{multirow}   % Cells spanning multiple rows (like multicolumn)
\RequirePackage{booktabs}   % Pretty tables; an absolute must

% More vertical stretch for more relaxed visuals in all tables (global setting)
\renewcommand*{\arraystretch}{1.3}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Default Titlepage
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% This uses the information from \title{}, \author{}, ... to generate a titlepage
% with the '\maketitle' command. Adapted from latex-mimosis
\RequirePackage{datetime2}

% Set the fonts for the titlepage
\newkomafont{titlepagetext}{\normalfont\normalsize}
\setkomafont{title}{\Large\scshape\lsstyle}
\setkomafont{author}{\Large\scshape\lsstyle}
\setkomafont{subtitle}{\usekomafont{titlepagetext}}
\setkomafont{date}{\usekomafont{titlepagetext}}
\newkomafont{born}{\usekomafont{titlepagetext}}
\newkomafont{examiner}{\usekomafont{titlepagetext}}
\newkomafont{supervisor}{\usekomafont{examiner}}
\newkomafont{degree}{\usekomafont{titlepagetext}}

% Make the default titlepage command
% Don't use \\ for space _between_ paragraphs
% use \vfill, \vspace, \bigskip, \medskip, \smallskip, ... instead
% use \par to force a paragraph end (and then use above command)
% If copying elsewhere, remember that spaces and newlines are handled different inside *.cls files!
\renewcommand{\maketitle}{
\begin{titlepage}
    \begin{center}

        \vspace*{\fill} % starred version to not discard space at beginning/end of page

        {\color{titlecolor}\usekomafont{title}\@title}\par
        \bigskip

        {\usekomafont{author}\@author}\par
        \bigskip

        {
            \usekomafont{born}
            born on \@born\\
            citizen of \@citizen
            \par % Line spacing is only updated after paragraph ends
        }
        \vfill


        {\usekomafont{titlepagetext}{A thesis submitted to attain the degree of}\par}
        {
            \usekomafont{degree}
            \@degree\\
            (\@shortdegree)\par
        }


        \vfill

        \@logo\par
        {\usekomafont{titlepagetext}{examined by}\par}
        \smallskip
        {\usekomafont{examiner}\@examiner\par}

        \bigskip

        {\usekomafont{titlepagetext}{supervised by\par}}
        \smallskip
        {\usekomafont{supervisor}\@supervisor\par}

        \bigskip

        {\usekomafont{date}\@date}
    \end{center}
\end{titlepage}

{
\thispagestyle{empty}
\vspace*{\fill}
\@lowertitleback
}

{
\cleardoubleoddpage
\thispagestyle{empty}
\begin{center}
    \vspace*{\fill}
    \@dedication
    \vspace*{\fill}
\end{center}
}
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Redefine Kaobook's Margin TOC
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


\RenewDocumentCommand{\margintoc}{O{\mtocshift}}{ % The first parameter is the vertical offset; by default it is \mtocshift
    \begingroup%
    % Move regular section and subsection to level 6 so that they won't be included and instead set let the mtoc versions take their place.
    % Adapted from https://tex.stackexchange.com/a/133559/226693
    \etocsetlevel{section}{6}
    \etocsetlevel{subsection}{6}
    \etocsetlevel{mtocsection}{1}
    \etocsetlevel{mtocsubsection}{2}

    % Define default widths
    \def\margintocnumwidth{8mm}% was -.8mm before  <--- CHANGE HERE
    \def\margintocpagenumwidth{8pt}%
    \setlength{\RaggedRightParfillskip}{0pt}

    % Dry run to get the needed widths
    \etocsetstyle{mtocsection}%
    {}%
    {\setbox0\hbox{{\usekomafont{section}\small\etocthenumber\kern.8mm}}%%
        \setbox1\hbox{{\usekomafont{section}\small\etocthepage}}}%
    {\ifdim\wd0>\margintocnumwidth \edef\margintocnumwidth{\the\wd0} \fi%%
        \ifdim\wd1>\margintocpagenumwidth \edef\margintocpagenumwidth{\the\wd1} \fi}%
    {}%
    \etocsetstyle{mtocsubsection}%
    {}%
    {\setbox0\hbox{{\usekomafont{section}\small\mdseries\etocthenumber\kern.8mm}}%
        \setbox1\hbox{{\usekomafont{section}\small\mdseries\etocthepage}}}%
    {\ifdim\wd0>\margintocnumwidth \edef\margintocnumwidth{\the\wd0} \fi%
        \ifdim\wd1>\margintocpagenumwidth \edef\margintocpagenumwidth{\the\wd1} \fi}%
    {}%
    \etocsetstyle{subsubsection}%
    {}%
    {}%
    {}%
    {}%
    \etocsetstyle{paragraph}%
    {}%
    {}%
    {}%
    {}%
    \etocsettocstyle{}{%
        \global\let\margintocnumwidth\margintocnumwidth%
        \global\let\margintocpagenumwidth\margintocpagenumwidth%
    }%
    \localtableofcontents%

    % Set the style for section entries
    \etocsetstyle{mtocsection}%
    {\parindent 0pt \parskip 2.5pt \parfillskip 0pt \RaggedRight}%
    {\leftskip \margintocnumwidth \rightskip \margintocpagenumwidth}%
    {\makebox[0pt][r]{\makebox[\margintocnumwidth][l]{\etocnumber}}\etocname\nobreak\leaders\hbox{\hbox to 1.5ex {\hss.\hss}}\hfill\rlap{\makebox[\margintocpagenumwidth][r]{\etocpage}}\par}%
    {}%
    % Set the style for subsection entries
    \etocsetstyle{mtocsubsection}%
    {\parindent 0pt \parskip 0pt \parfillskip 0pt \RaggedRight}%
    {\leftskip \margintocnumwidth \rightskip \margintocpagenumwidth}%
    {\makebox[0pt][r]{\makebox[\margintocnumwidth][l]{\mdseries\etocnumber}}{\mdseries\etocname\nobreak\leaders\hbox{\hbox to 1.5ex {\hss.\hss}}\hfill\rlap{\makebox[\margintocpagenumwidth][r]{\mdseries\etocpage}}}\par}%
    {\parskip 2.5pt}%
    % Set the global style of the toc
    \etocsettocstyle{\usekomafont{section}\small}{}%
    \etocsetnexttocdepth{\themargintocdepth}%
    % Print the table of contents in the margin
    \marginnote[#1]{\localtableofcontents}%
    \FloatBarrier%
    \endgroup%
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Hyperref and PDFs appearance
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\RequirePackage{hyperref}
\PassOptionsToPackage{pdfusetitle}{hyperref}
\hypersetup{%
% Unicode settings are automatically true for luatex engine,
% don't specify manually
colorlinks=true,		% No ugly frames, but still colored
linkcolor=internallink, % Color of normal internal links
citecolor=reflink,		% Color of bibliographical citations in text
filecolor=externallink, % Color for URLs which open local files
urlcolor=externallink,  % Color for linked URLs
% hidelinks,			% Toggle here!
plainpages=false,%
pdfsubject={%
        \@subtitle
    },
pdfkeywords={%
        latex,%
        lualatex,%
        modern,%
        thesis,%
    },
pdfcreator={%
LuaLaTeX with hyperref,
glossaries-extra/bib2gls
and biblatex/biber
[\GitRefName{}@\GitShortSHA{}]%
},
bookmarksnumbered=true,%
% Default opening of the document in supported PDF viewers:
pdfpagelayout=TwoPageRight,
pdfdisplaydoctitle,% https://tex.stackexchange.com/a/435434/120853
}%

% Appearance of the bookmarks popup in viewers that support it
\RequirePackage{bookmark}% Control bookmark appearance in PDF
\bookmarksetup{%
    open,% Open bookmark pane in PDF viewer
    openlevel=1,% Open first two levels, hide all subsections etc. (0-indexed)
    addtohook={%
            \ifnum\bookmarkget{level}=0% Only print top-level (0) bookmarks bold
                \bookmarksetup{bold}%
            \fi%
        },%
}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% A signature field with places for the date and time
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newcommand{\signaturefield}[1][\@author]{%
    % This should only occur on pages with a lot of other pages behind it, to support
    % writing on it here.
    % If is occurs at the beginning of the document, put it recto. At the end, verso.
    % Else, writing and stamping on here won't have much support.
    \vspace*{1.5cm}% Leave room for signature
    \begin{center}
        \begin{tabular}{%
                % Columns widths control signature line length
                M{12em}
                M{4em}% Empty middle
                M{12em}
            }
            \cmidrule{1-1}            \cmidrule{3-3}
            Place, date &  & #1 \\
        \end{tabular}
    \end{center}
}
