PhD

The LaTeX sources of my Ph.D. thesis
git clone https://esimon.eu/repos/PhD.git
Log | Files | Refs | README | LICENSE

thesis.cls (25279B)


      1 \NeedsTeXFormat{LaTeX2e}
      2 \ProvidesClass{thesis}[2021/01/01 Local class]
      3 
      4 % Some colored output for ease of debugging
      5 \directlua{tcolor=require("lib/terminal color")}
      6 
      7 \RequirePackage{etoolbox} % Because we are in the third millennium
      8 \RequirePackage{expl3} % For LaTeX3 code
      9 \RequirePackage{luacode} % Handling of lua code inside tex files
     10 \RequirePackage{pgffor} % For \foreach loop
     11 \RequirePackage{xparse} % For modern \NewDocumentCommand, etc
     12 \RequirePackage{xkeyval} % For handling class options
     13 
     14 
     15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     16 %%% Common Error Help Texts %%%%%%%%%%%%%%%%%%%%%%
     17 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     18 
     19 \NewDocumentCommand\thesis@warning{m}{\directlua{tcolor.warning("\luatexluaescapestring{#1}")}}
     20 
     21 \NewDocumentCommand\thesis@options@error{m}{
     22 	\ClassError{thesis}{#1}{%
     23 		The options provided to the thesis class must explicitly contain one of `print',\MessageBreak
     24 		`digital' or `presentation'.
     25 	}%
     26 }
     27 
     28 \NewDocumentCommand\thesis@patch@error{m m}{
     29 	\csname #1Error\endcsname{thesis}{#2}{%
     30 		You're most likely seeing this error because of modifications to the latex\MessageBreak
     31 		ecosystem which are not compatible with the thesis code source. To ensure the\MessageBreak
     32 		code is compiled correctly, use the texlive 2021 distribution as described in\MessageBreak
     33 		the README. Another option is to adapt the \protect\patchcmd\space responsible for this\MessageBreak
     34 		error, although this might prove more time consuming.
     35 	}%
     36 }
     37 
     38 
     39 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     40 %%% Class Options %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     41 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     42 
     43 % print, digital or presentation
     44 \newif\ifthesis@digital
     45 \newif\ifthesis@print
     46 \newif\ifthesis@presentation
     47 \DeclareOptionX{digital}{\thesis@digitaltrue}
     48 \DeclareOptionX{print}{\thesis@printtrue}
     49 \DeclareOptionX{presentation}{\thesis@presentationtrue}
     50 
     51 % debug
     52 \newcount\thesis@debug
     53 \thesis@debug=0
     54 \DeclareOptionX{thesisdebug}{\thesis@debug=#1}
     55 
     56 % lineno
     57 \newif\ifthesis@lineno
     58 \thesis@linenofalse
     59 \DeclareOptionX{lineno}{\thesis@linenotrue}
     60 
     61 % summary
     62 \newif\ifthesissummary
     63 \thesissummaryfalse
     64 \DeclareOptionX{summary}{\thesissummarytrue}
     65 
     66 \ProcessOptionsX\relax
     67 
     68 % check print, digital and presentation consistency
     69 \newcount\thesis@format@count
     70 \thesis@format@count0\relax
     71 \ifthesis@digital
     72 	\advance\thesis@format@count1\relax
     73 \fi
     74 \ifthesis@print
     75 	\advance\thesis@format@count1\relax
     76 \fi
     77 \ifthesis@presentation
     78 	\advance\thesis@format@count1\relax
     79 \fi
     80 \ifnum\thesis@format@count=1\else
     81 	\thesis@options@error{Exactly one of `digital', `print' or `presentation' must be given}
     82 \fi
     83 
     84 
     85 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     86 %%% Class Setup %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     87 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     88 
     89 \ifthesis@presentation
     90 	\PassOptionsToClass{aspectratio=169}{beamer}
     91 	\LoadClass{beamer}
     92 	\usetheme{thesis}
     93 \else
     94 	\PassOptionsToClass{a4paper,10pt}{book}
     95 	\LoadClass{book}
     96 \fi
     97 
     98 % Basic dependencies
     99 \RequirePackage{fontspec} % For modern font interface
    100 \ifthesis@presentation\else
    101 	\PassOptionsToPackage{table}{xcolor}
    102 \fi
    103 \RequirePackage{xcolor} % For color handling
    104 \RequirePackage{csquotes} % For context sensitive quotes
    105 \RequirePackage{caption} % For custom float and caption style
    106 \RequirePackage{booktabs} % For fancy \toprule &cie
    107 \RequirePackage{marginnote} % For non-floating marginpar
    108 
    109 % A keywords definition command, used for PDF metadata and in the manuscript
    110 \DeclareRobustCommand\keywords[1]{\gdef\@keywords{#1}}
    111 
    112 % Continue page numbering when switching to main matter
    113 \ifthesis@presentation\else
    114 	\patchcmd{\mainmatter}
    115 		{\pagenumbering{arabic}}
    116 		{\gdef\thepage{\@arabic\c@page}}
    117 		{}
    118 		{\thesis@patch@error{Class}{Can't keep continuous folio, patch failed.}}
    119 \fi
    120 
    121 % Simple space after period
    122 \frenchspacing
    123 
    124 % Use smaller font inside the margin column and be more lenient to bad spacing
    125 \NewDocumentCommand\marginsize{}{\fontsize\@viiipt{9.5}\selectfont\hbadness=7500}
    126 \DeclareCaptionFont{marginsize}{\marginsize}
    127 
    128 %%%%%%%%%%%%%%%%%%%%
    129 % Margin Paragraph %
    130 %%%%%%%%%%%%%%%%%%%%
    131 \let\oldmarginpar\marginpar
    132 \RenewDocumentCommand\marginpar{+m}{\oldmarginpar{\marginsize{}\ignorespaces#1}}
    133 \NewDocumentEnvironment{marginparagraph}{o +b}
    134 	{%
    135 		\IfNoValueTF{#1}{%
    136 			\marginpar{#2}%
    137 		}{%
    138 			\marginnote{#2}[#1]%
    139 		}%
    140 	}{}
    141 \AfterEndEnvironment{marginparagraph}{\ignorespaces}
    142 
    143 % For marginnote package
    144 \RenewDocumentCommand\marginfont{}{\marginsize{}}
    145 \RenewDocumentCommand\raggedleftmarginnote{}{}
    146 \RenewDocumentCommand\raggedrightmarginnote{}{}
    147 
    148 %%%%%%%%%%%%%%%
    149 % Debug boxes %
    150 %%%%%%%%%%%%%%%
    151 % Mark overfull \hbox{}es
    152 \ifnum\thesis@debug>0
    153 	\setlength\overfullrule{2mm}
    154 \fi
    155 
    156 % Display box construction
    157 \ifnum\thesis@debug>1
    158 	\RequirePackage{lua-visual-debug}
    159 \fi
    160 
    161 %%%%%%%%%%%%%%%
    162 % Page Layout %
    163 %%%%%%%%%%%%%%%
    164 % This instantiate two geometries: withmarginpar and withoutmarginpar
    165 \ifthesis@presentation\else
    166 	\directlua{require("lib/layout").set{
    167 		twoside=\ifthesis@print true\else false\fi,
    168 		top="2cm",
    169 		mpwidth="5cm",
    170 		mpsep="5mm",
    171 		debug=\ifnum\thesis@debug>1 true\else false\fi}}
    172 \fi
    173 
    174 %%%%%%%%%%%
    175 % Headers %
    176 %%%%%%%%%%%
    177 \ifthesis@presentation\else
    178 	\RequirePackage{fancyhdr}
    179 	\fancyhf{}
    180 	\RenewDocumentCommand\headrulewidth{}{0mm}
    181 	\RenewDocumentCommand\footrulewidth{}{0mm}
    182 
    183 	\ifthesis@digital
    184 		\fancypagestyle{plain}{%
    185 				\fancyhf[HR]{\thepage}%
    186 				\fancyhf[HEL]{\ifthesissummary\rightmark\else\leftmark\fi}%
    187 				\fancyhf[HOL]{\rightmark}%
    188 		}
    189 	\else %print
    190 		\fancypagestyle{plain}{%
    191 				\fancyhf[HEL,HOR]{\thepage}%
    192 				\fancyhf[HER]{\ifthesissummary\rightmark\else\leftmark\fi}%
    193 				\fancyhf[HOL]{\rightmark}%
    194 		}
    195 	\fi
    196 	\pagestyle{plain}
    197 
    198 	% Setup header content
    199 \fi
    200 
    201 \DeclareDocumentCommand\chaptermark{m}{\markboth{\if@mainmatter\thechapter\ \fi#1}{}}
    202 \DeclareDocumentCommand\sectionmark{m}{\markright{\thesection\ #1}}
    203 
    204 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    205 % Commands for switching geometry %
    206 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    207 % marginparwidth + marginparsep
    208 \ifthesis@presentation\else
    209 \NewDocumentCommand\margintotal{}{55mm}
    210 
    211 \NewDocumentCommand\withmarginpar{}{%
    212 	\loadgeometry{withmarginpar}%
    213 	\fancyheadoffset[R]{\margintotal}% fix fancyhdr
    214 	\edef\marginnotetextwidth{\the\textwidth}% fix marginnote
    215 	\setlength{\@sidenotes@extrawidth}{\margintotal}%fix sidenotes
    216 }
    217 \NewDocumentCommand\withoutmarginpar{}{%
    218 	\loadgeometry{withoutmarginpar}%
    219 	\fancyheadoffset[R]{0mm}% fix fancyhdr
    220 	\setlength{\@sidenotes@extrawidth}{0mm}%fix sidenotes
    221 }
    222 
    223 % Temporary fullwidth environment
    224 \NewDocumentEnvironment{fullwidth}{}
    225 	{\begin{adjustwidth}{}{-\margintotal}}
    226 	{\end{adjustwidth}}
    227 \fi
    228 
    229 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    230 % Add version information to every page %
    231 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    232 \RequirePackage{eso-pic} % for AddToShipoutPictureFG
    233 \directlua{draft_version = require("lib/draft version")}
    234 \NewDocumentCommand\draftVersion{}{\directlua{draft_version.draft_version()}}
    235 \ifnum\thesis@debug>0
    236 	% Version information is inserted by the beamer style for the presentation
    237 	\ifthesis@presentation\else
    238 		\AddToShipoutPictureFG{%
    239 			\AtPageLowerLeft{%
    240 				\hspace{2mm}%
    241 				\makebox[0pt][l]{%
    242 					\rotatebox{90}{%
    243 						\hspace{2mm}%
    244 						\color{black}\ttfamily\footnotesize %
    245 						draft \draftVersion}}}}
    246 	\fi
    247 \fi
    248 
    249 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    250 % Add line numbers to every pages %
    251 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    252 \RequirePackage{siunitx}
    253 \ifthesis@lineno
    254 	\newcount\thesis@lineno
    255 	\thesis@lineno=1
    256 	\AddToShipoutPictureBG{%
    257 		\ifnum\value{page}>2\relax%
    258 			\AtPageUpperLeft{%
    259 				\ifthesis@print%
    260 					\ifodd\c@page%
    261 						\hspace{5mm}%
    262 					\else%
    263 						\hspace{19mm}%
    264 					\fi%
    265 				\else%
    266 					\hspace{7.5mm}%
    267 				\fi%
    268 				\normalfont\normalsize%
    269 				\begin{minipage}[t]{1cm}%
    270 					\begin{singlespace}%
    271 						\hbadness=10000%
    272 						\vskip 32mm%
    273 						\foreach \i in {1,...,54}{%
    274 							\makeatletter%
    275 								\textcolor{black!50}{\num[minimum-integer-digits=4]{\the\thesis@lineno}}\\%
    276 								\global\advance\thesis@lineno1\relax%
    277 							\makeatother%
    278 						}%
    279 					\end{singlespace}%
    280 				\end{minipage}%
    281 			}%
    282 		\fi%
    283 	}
    284 \fi
    285 
    286 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    287 % Report all moved marginpar at the end %
    288 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    289 \directlua{moved_marginpar = require("lib/moved marginpar")}
    290 \NewDocumentCommand\marginparmoved{m}{\directlua{moved_marginpar.declare(#1)}}
    291 \patchcmd{\@addmarginpar}
    292 	{\@latex@warning@no@line {Marginpar on page \thepage\space moved}}
    293 	{\marginparmoved{\thepage}}
    294 	{}
    295 	{\thesis@warning{Patch failed, can't remove annoying `moved marginpar' messages.}}
    296 
    297 %%%%%%%%%%
    298 % Titles %
    299 %%%%%%%%%%
    300 \ifthesis@presentation\else
    301 \RequirePackage{titlesec}
    302 \newfontfamily\garamond{EB Garamond}[Ligatures=TeX]
    303 \titleformat{\chapter}% command
    304 	[display]% shape
    305 	{\garamond\huge}% format
    306 	{\chaptertitlename\ \thechapter}% label
    307 	{7.5mm}% label-title separation
    308 	{\begin{fullwidth}\raggedright\Huge}% title before code
    309 	[\end{fullwidth}]% title after code
    310 \titleformat*{\section}{\garamond\raggedright\LARGE}
    311 \titleformat*{\subsection}{\garamond\Large}
    312 \titleformat*{\subsubsection}{\garamond\large}
    313 
    314 % Number \subsubsection
    315 \setcounter{secnumdepth}{3}
    316 \setcounter{tocdepth}{3}
    317 
    318 \ifthesissummary
    319 	\RenewDocumentCommand\thesection{}{\@arabic\c@section}
    320 \fi
    321 \fi
    322 
    323 
    324 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    325 %%% Fonts %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    326 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    327 
    328 \RequirePackage{amsmath}
    329 \RequirePackage{amssymb}
    330 \RequirePackage{mathtools}
    331 \RequirePackage[math-style=ISO,warnings-off={mathtools-colon,mathtools-overbracket}]{unicode-math}
    332 
    333 % Use the old \mathcal style
    334 \DeclareMathAlphabet{\mathcal}{OMS}{cmsy}{m}{n}
    335 
    336 % Use the standard Latin Modern font for most things
    337 \setmathfont{LatinModernMath}
    338 
    339 % Except for the fancy script style
    340 \setmathfont[range=scr]{XITS Math}
    341 
    342 % Symbols with no glyph in Latin Modern
    343 \setmathfont[range={\setminus}]{XITS Math}
    344 
    345 % Remove incorrect skip when a block start with a display equation
    346 \NewDocumentCommand\unskipdisplay{}{\vspace*{-\baselineskip}\setlength\belowdisplayshortskip{0pt}}
    347 
    348 %%%%%%%%%%%%%%%%%%%%%%%%%
    349 % Uppercase PDF strings %
    350 %%%%%%%%%%%%%%%%%%%%%%%%%
    351 \usepackage{letltxmacro} % For let'ing robust command
    352 \LetLtxMacro{\oldtextsc}{\textsc}
    353 
    354 % Avoid hyperref redefinition
    355 \AtBeginDocument{
    356 	\patchcmd{\pdfstringdef}%
    357 		{\textsc}%
    358 		{\oldtextsc}%
    359 		{}%
    360 		{\thesis@patch@error{Class}{%
    361 			Patch failed, can't change \protect\pdfstringdef\space to fix \protect\textsc\MessageBreak
    362 			for uppercase PDF string.}}%
    363 }
    364 
    365 \ExplSyntaxOn
    366 \ifthesis@presentation
    367 \def\textsc#1{%
    368 	{\text{\text_uppercase:n{#1}}}%
    369 }
    370 \else
    371 \def\textsc#1{%
    372 	\texorpdfstring%
    373 		{{%
    374 			\ifdim\fontdimen1\font>0pt\slshape\fi% Italic small caps can appear in the bibliography but are not available in latin modern, replace them with slanted small caps.
    375 			\oldtextsc{#1}}}%
    376 		{\text_uppercase:n{#1}}% Use uppercase for PDF strings (e.g. in PDF bookmarks) where small caps should appear.
    377 }
    378 \fi
    379 \ExplSyntaxOff
    380 
    381 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    382 %%% Floats Handling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    383 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    384 
    385 \ifthesis@presentation\else
    386 \RequirePackage{newfloat} % For defining new floats
    387 \RequirePackage{tocloft} % For defining List of Illustrations
    388 \RequirePackage[oneside]{sidenotes} % For margin floats
    389 
    390 \pretocmd{\sidenotetext}%
    391 	{\edef\@currentlabel{\thesidenote}}%
    392 	{}%
    393 	{\thesis@patch@error{Class}{Prepend failed, can't add label information to \string\sidenotetext.}}%
    394 
    395 % Add an \ignorespaces since a ~ is placed after the note number and we often start the note with a linebreak.
    396 \RenewDocumentCommand\sidenote{o o +m}{%
    397   \sidenotemark[#1]%
    398   \sidenotetext[#1][#2]{\ignorespaces #3}%
    399   \@sidenotes@multimarker%
    400 }
    401 \fi
    402 
    403 %%%%%%%%%%%%%%%%%%%
    404 % Algorithm float %
    405 %%%%%%%%%%%%%%%%%%%
    406 \ifthesis@presentation\else
    407 % List of Algorithms
    408 \NewDocumentCommand\listalgorithmname{}{List of Algorithms}
    409 \newlistof[chapter]{algorithm}{loa}{\listalgorithmname}
    410 % Use the same spacing than the one of List of Figures/Tables
    411 \setlength{\cftalgorithmnumwidth}{2.3em}
    412 \setlength{\cftalgorithmindent}{1.5em}
    413 
    414 % Create the standard environment
    415 \DeclareFloatingEnvironment[fileext=loa,name=Algorithm]{algorithm}
    416 
    417 % Create the margin environment
    418 \newsavebox{\@sidenotes@marginalgorithmbox}
    419 \DeclareCaptionStyle{marginalgorithm}{font=marginsize}
    420 \NewDocumentEnvironment{marginalgorithm}{o}
    421 	{%
    422 		\begin{lrbox}{\@sidenotes@marginalgorithmbox}%
    423 			\begin{minipage}{\marginparwidth}%
    424 				\captionsetup{type=algorithm,style=marginalgorithm}%
    425 	}
    426 	{%
    427 			\end{minipage}%
    428 		\end{lrbox}%
    429 		\@sidenotes@placemarginal{#1}{\usebox{\@sidenotes@marginalgorithmbox}}%
    430 	}
    431 \fi
    432 
    433 %%%%%%%%%%%%%%%%%%%%%
    434 % Margin Appearance %
    435 %%%%%%%%%%%%%%%%%%%%%
    436 \ifthesis@presentation\else
    437 % Use the smaller font inside margins
    438 \captionsetup{font=marginsize}
    439 \AtBeginEnvironment{marginfigure}{\marginsize}
    440 \AtBeginEnvironment{margintable}{\marginsize}
    441 \AtBeginEnvironment{marginalgorithm}{\marginsize}
    442 
    443 % Smaller spacing between figure and caption
    444 \setlength{\abovecaptionskip}{2mm}
    445 \fi
    446 
    447 % Modify marginnote package to always print on the right
    448 \patchcmd{\@mn@@@marginnote}
    449 	{\if@tempswa\rlap}
    450 	{\iftrue\rlap}
    451 	{}
    452 	{\thesis@patch@error{Class}{%
    453 		Patch failed, can't fix \protect\marginnote\space such that it always\MessageBreak
    454 		places on the right.}}
    455 
    456 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    457 % Chapter handling for TOC & LOI %
    458 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    459 \ifthesis@presentation\else
    460 \NewDocumentCommand\fixloititlefont{m}{
    461 	\expandafter\gdef\csname cft#1titlefont\endcsname{\garamond\Huge}
    462 }
    463 
    464 \foreach \loi in {toc, lof, lot, loa}{
    465 	\expandafter\fixloititlefont\expandafter{\loi}
    466 }
    467 
    468 \AddToHookNext{begindocument}{
    469 	\pretocmd{\tableofcontents}
    470 		{\cleardoublepage\pdfbookmark[chapter]{\contentsname}{contents}}
    471 		{}
    472 		{\thesis@patch@error{Class}{Prepend failed, can't \string\cleardoublepage\space before \string\tableofcontents.}}
    473 }
    474 \fi
    475 
    476 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    477 % Lower case for special headers %
    478 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    479 \ifthesis@presentation\else
    480 \NewDocumentCommand\MakeMarkcase{}{} % For biblatex
    481 \NewDocumentCommand\thesis@lower@head{m m}{% Patch command for frontmatter lists
    482 	\RenewDocumentCommand{#1}{}{\@mkboth{#2}{#2}}%
    483 }
    484 \thesis@lower@head{\cftmarktoc}{\contentsname}
    485 \thesis@lower@head{\cftmarklof}{\listfigurename}
    486 \thesis@lower@head{\cftmarklot}{\listtablename}
    487 \thesis@lower@head{\cftmarkloa}{\listalgorithmname}
    488 \fi
    489 
    490 %%%%%%%%%%%%%%%%%%%%%%%%
    491 % Algorithm formatting %
    492 %%%%%%%%%%%%%%%%%%%%%%%%
    493 \RequirePackage{algpseudocodex}
    494 \NewDocumentCommand\FunctionOutput{}{\State\textsl{Output}:}
    495 \NewDocumentCommand\FunctionOutputs{s}{%
    496 	\IfBooleanTF#1%
    497 		{\State\hphantom{\textsl{Outputs}:}}%
    498 		{\State\textsl{Outputs}:}%
    499 }
    500 \NewDocumentCommand\FunctionInput{}{\State\textsl{Input}:}
    501 \NewDocumentCommand\FunctionInputs{s}{%
    502 	\IfBooleanTF#1%
    503 		{\State\hphantom{\textsl{Inputs}:}}%
    504 		{\State\textsl{Inputs}:}%
    505 }
    506 \RenewDocumentCommand\algorithmicfunction{}{\textbf{algorithm}}
    507 
    508 % Remove left margin in algorithms
    509 \expandafter\patchcmd\csname\string\algorithmic\endcsname
    510 	{\leftmargin\labelwidth \addtolength{\leftmargin}{\labelsep}}
    511 	{\leftmargin 0mm}
    512 	{}
    513 	{\thesis@patch@error{Class}{Patch failed, can't remove left margin of \protect\algorithmic.}}
    514 
    515 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    516 % Universal Caption Command %
    517 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    518 \ifthesis@presentation\else
    519 % Store the type of float (m=main area, s=side margin, w=wide)
    520 \def\thesis@float@type{}
    521 
    522 % Modify \thesis@float@type to match the environment
    523 \NewDocumentCommand\thesis@patch@float@type{m m}{%
    524 	\expandafter\pretocmd\csname#1\endcsname{\ifx\thesis@float@type\empty\def\thesis@float@type{#2}\fi}{}{\thesis@patch@error{Class}{Prepend failed, can't add float type information to #1.}}%
    525 	\expandafter\pretocmd\csname end#1\endcsname{\def\thesis@float@type{}}{}{\thesis@patch@error{Class}{Prepend failed, can't reinitialize float type information after #1.}}%
    526 }
    527 \thesis@patch@float@type{figure}{m}
    528 \thesis@patch@float@type{figure*}{w}
    529 \thesis@patch@float@type{marginfigure}{s}
    530 \thesis@patch@float@type{table}{m}
    531 \thesis@patch@float@type{table*}{w}
    532 \thesis@patch@float@type{margintable}{s}
    533 \thesis@patch@float@type{algorithm}{m}
    534 \thesis@patch@float@type{marginalgorithm}{s}
    535 
    536 % Caption box for main area floats
    537 \newsavebox{\thesis@caption@box}
    538 
    539 % Universal caption command:
    540 % For side margin floats, use standard \caption
    541 % For wide floats, use sidenotes' \sidecaption
    542 % For main area floats, align the bottom of the caption with the bottom the figure, except if a star is given, then the tops are aligned.
    543 \NewDocumentCommand\scaption{s O{#3} m O{0mm}}{%
    544 	\if m\thesis@float@type\relax% main area float
    545 		\begin{lrbox}{\thesis@caption@box}%
    546 			\begin{minipage}{\marginparwidth}%
    547 				\caption[#2]{#3}%
    548 			\end{minipage}%
    549 		\end{lrbox}%
    550 		\IfBooleanTF#1%
    551 			{\def\thesis@caption@offset{0mm}}%
    552 			{\def\thesis@caption@offset{-\ht\thesis@caption@box-\dp\thesis@caption@box}}%
    553 		\marginnote{\usebox{\thesis@caption@box}}[\dimexpr\thesis@caption@offset+#4\relax]%
    554 	\else%
    555 		\if s\thesis@float@type\relax% side margin float
    556 			\caption[#2]{#3}%
    557 		\else% wide float
    558 			\sidecaption[#2][#4]{#3}%
    559 		\fi%
    560 	\fi%
    561 }
    562 \fi
    563 
    564 
    565 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    566 %%% Bibliograhpy %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    567 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    568 
    569 \RequirePackage[
    570 		style=authoryear-comp,
    571 		maxcitenames=2,
    572 		mincitenames=1,
    573 		maxbibnames=10,
    574 		minbibnames=9,
    575 		uniquelist=false,
    576 		dateera=secular,
    577 		dateeraauto=500,
    578 		dateuncertain=true
    579 	]{biblatex}
    580 
    581 % Homogenize formatting of @misc title
    582 \DeclareFieldFormat[misc]{title}{\mkbibquote{#1}}
    583 
    584 % Remove leading zeros for years earlier than 1000
    585 \let\blx@imc@mkyearzeros\blx@imc@stripzeros
    586 
    587 % Make prefix appears first in citation (de Saussure 1916) but not in the bibliography (Saussure, Ferdinand de…)
    588 \AtBeginDocument{\toggletrue{blx@useprefix}}
    589 \AtBeginBibliography{\togglefalse{blx@useprefix}}
    590 
    591 % Prefer smallcaps for era abbreviations
    592 \DefineBibliographyStrings{english}{
    593 	commonera       = {\textsc{ce}},
    594 	beforecommonera = {\textsc{bce}},
    595 }
    596 \DefineBibliographyStrings{french}{
    597 	commonera       = {de~n.~è.},
    598 	beforecommonera = {av.~n.~è.},
    599 }
    600 
    601 % Break URLs anywhere in bibliography
    602 \setcounter{biburllcpenalty}{100}
    603 \setcounter{biburlucpenalty}{200}
    604 \setcounter{biburlnumpenalty}{100}
    605 
    606 % Sort by family name without prefix first
    607 \DeclareSortingNamekeyTemplate{
    608 	\keypart{\namepart{family}}
    609 	\keypart{\namepart{prefix}}
    610 	\keypart{\namepart{given}}
    611 	\keypart{\namepart{suffix}}
    612 }
    613 
    614 %%%%%%%%%%%%%%%%%%%%%%%%
    615 % References in margin %
    616 %%%%%%%%%%%%%%%%%%%%%%%%
    617 \DeclareFieldFormat{linkedtitle}{%
    618 	\iffieldundef{url}%
    619 		{%
    620 			\printfield{\currentfield}%
    621 			\thesis@warning{No url provided for \string\sidecited\space``\thefield{title}''}{}%
    622 		}%
    623 		{\mkbibquote{\href{\thefield{url}}{#1}\isdot}}%
    624 }
    625 \newbibmacro{shortseries}{\printfield{shortseries}}
    626 
    627 \NewDocumentCommand\citationBadness{}{\hbadness=7500}
    628 
    629 \DeclareCiteCommand{\sideciteContent}
    630 	{\citationBadness\usebibmacro{prenote}}% precode
    631 	{% loopcode
    632 		\printnames{labelname}%
    633 		\setunit{\printdelim{nametitledelim}}\newblock%
    634 		\printfield[linkedtitle]{title}%
    635 		\setunit{\addspace}%
    636 		\usebibmacro{shortseries}%
    637 		\setunit{\addspace}%
    638 		\printfield[bibhyperref]{year}%
    639 	}% end loopcode
    640 	{\par}% sepcode
    641 	{\usebibmacro{postnote}}% postcode
    642 
    643 \NewDocumentCommand\sidecite{m o}{%
    644 	\IfNoValueTF{#2}{%
    645 		\marginpar{\sideciteContent{#1}}%
    646 	}{% else if #2 is given
    647 		\marginnote{\sideciteContent{#1}}[#2]%
    648 	}%
    649 }
    650 
    651 \NewDocumentCommand\thesis@new@cite{m}{%
    652 	\expandafter\NewDocumentCommand\csname #1x\endcsname{O{} O{} m o}{%
    653 		\csname #1\endcsname[##1][##2]{##3}%
    654 		\sidecite{##3}[##4]%
    655 	}%
    656 }
    657 
    658 \thesis@new@cite{cite}
    659 \thesis@new@cite{Cite}
    660 \thesis@new@cite{textcite}
    661 \thesis@new@cite{Textcite}
    662 \thesis@new@cite{parencite}
    663 \thesis@new@cite{Parencite}
    664 
    665 
    666 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    667 %%% Figure Drawing %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    668 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    669 
    670 %%%%%%%%%%%%
    671 % PGF/TikZ %
    672 %%%%%%%%%%%%
    673 \RequirePackage{tikz}
    674 \usetikzlibrary{arrows.meta} % for more arrow shapes
    675 \usetikzlibrary{backgrounds} % for drawing behind things
    676 \usetikzlibrary{calc} % for let
    677 \usetikzlibrary{colorbrewer} % for color schemes
    678 \usetikzlibrary{decorations.pathreplacing} % for decorate
    679 \usetikzlibrary{decorations.text} % for text along path
    680 \usetikzlibrary{matrix} % for matrix of nodes
    681 \usetikzlibrary{tikzmark} % to easily reference coordinates on the page
    682 \usetikzlibrary{overlay-beamer-styles} % handle background layers when using beamer overlays
    683 \usetikzlibrary{patterns} % for patterns
    684 \usetikzlibrary{patterns.meta} % for parametrized patterns
    685 \usetikzlibrary{positioning} % for above=of
    686 \usetikzlibrary{shapes.geometric} % for regular polygon
    687 \usetikzlibrary{svg.path}
    688 
    689 % Use plain arrows
    690 \tikzset{arrow/.style={-{Latex}}}
    691 
    692 % Consistent transparency values for figures
    693 \def\transparencyDefault{0.3}
    694 \def\transparencyLow{0.1}
    695 \tikzset{faded/.style={opacity=\transparencyDefault}}
    696 \tikzset{ultra faded/.style={opacity=\transparencyLow}}
    697 
    698 %%%%%%%%%%%%%
    699 % PGF plots %
    700 %%%%%%%%%%%%%
    701 \RequirePackage{pgfplots}
    702 \pgfplotsset{compat=1.17}
    703 
    704 % Use Tufte-inspired style
    705 \pgfplotsset{
    706     modern/.style={
    707         enlargelimits=false,
    708         separate axis lines,
    709         semithick,
    710         axis x line*=bottom,
    711         axis x line shift=10pt,
    712         axis y line*=left,
    713         axis y line shift=10pt,
    714         every axis/.append style={thick},
    715         tick style={thick, black},
    716         tick align=outside,
    717     }
    718 }
    719 
    720 
    721 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    722 %%% Block Formatting %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    723 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    724 
    725 \NewDocumentEnvironment{spacedblock}{}
    726 	{\begin{trivlist}\item\relax}
    727 	{\end{trivlist}}
    728 
    729 \NewDocumentEnvironment{indentedexample}{}
    730 	{%
    731 		\begin{spacedblock}%
    732 		\hfill%
    733 		\begin{minipage}{\dimexpr\textwidth-2cm}%
    734 	}
    735 	{%
    736 		\end{minipage}%
    737 		\hfill\null%
    738 		\end{spacedblock}%
    739 	}
    740 
    741 
    742 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    743 %%% Epigraph %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    744 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    745 
    746 \RequirePackage{adjustbox}
    747 
    748 % For vertically flowing text (e.g. chinese)
    749 \newsavebox{\thesis@tate@box}
    750 \NewDocumentCommand\tate{m}{%
    751 	\begin{lrbox}{\thesis@tate@box}%
    752 		#1%
    753 	\end{lrbox}%
    754 	\boxdir\thesis@tate@box RTT%
    755 	\usebox{\thesis@tate@box}%
    756 }
    757 
    758 % For a double quote character I like
    759 \newfontfamily\bonum{TeX Gyre Bonum}[Ligatures=TeX]
    760 
    761 \NewDocumentEnvironment{epigraphcontent}{O{4cm} m m m +b}
    762 	{%
    763 			\textcolor{black!30}{\bonum\fontsize{36pt}{36pt}\selectfont\raisebox{-16pt}[8pt][0pt]{``}}%
    764 			\itshape\,\ignorespaces #5\strut\\%
    765 			\upshape\null\hfill%
    766 			\begin{minipage}[b]{#1}%
    767 				\vphantom{---}\llap{--- }%
    768 				\if\relax\detokenize{#2}\relax\else%
    769 					#2, %
    770 				\fi%
    771 				#3 (#4)\strut%
    772 			\end{minipage}%
    773 	}{}
    774 
    775 \NewDocumentEnvironment{translatedepigraphcontent}{O{4cm} m m m m +b}
    776 	{%
    777 			\textcolor{black!30}{\bonum\fontsize{36pt}{36pt}\selectfont\raisebox{-16pt}[8pt][0pt]{``}}%
    778 			\itshape\,\ignorespaces #6\strut\\%
    779 			\upshape\textcolor{black!30}{\bonum\fontsize{36pt}{36pt}\selectfont\raisebox{-16pt}[8pt][0pt]{``}}%
    780 			\itshape\,\ignorespaces #5\strut\\%
    781 			\upshape\null\hfill%
    782 			\begin{minipage}[b]{#1}%
    783 				\vphantom{---}\llap{--- }%
    784 				\if\relax\detokenize{#2}\relax\else%
    785 					#2, %
    786 				\fi%
    787 				#3 (#4)\strut%
    788 			\end{minipage}%
    789 	}{}
    790 
    791 \newlength{\thesis@epigraph@dash@width}
    792 \settowidth{\thesis@epigraph@dash@width}{--- }
    793 \NewDocumentEnvironment{epigraph}{O{4cm} m m m o o +b}
    794 	{%
    795 		\begin{marginparagraph}[#6]%
    796 			\raisebox{-\baselineskip}[0mm][\totalheight]{\parbox[t]{\marginparwidth}{%
    797 				\hbadness=7000%
    798 				\begin{epigraphcontent}[#1]{#2}{#3}{#4}%
    799 					#7%
    800 				\end{epigraphcontent}%
    801 				\IfValueT{#5}%
    802 					{\newline\null\hfill\begin{minipage}{\dimexpr#1+\thesis@epigraph@dash@width\relax}%
    803 						#5%
    804 					\end{minipage}}%
    805 			}}%
    806 		\end{marginparagraph}%
    807 	}{}
    808 
    809 \NewDocumentEnvironment{translatedepigraph}{O{4cm} m m m m o +b}
    810 	{%
    811 		\begin{marginparagraph}[#6]%
    812 			\raisebox{-\baselineskip}[0mm][\totalheight]{\parbox[t]{\marginparwidth}{%
    813 				\hbadness=7000%
    814 				\begin{translatedepigraphcontent}[#1]{#2}{#3}{#4}{#5}%
    815 					#7%
    816 				\end{translatedepigraphcontent}%
    817 			}}%
    818 		\end{marginparagraph}%
    819 	}{}
    820 
    821 % Fix problem with luatex vertical typesetting
    822 \newlength{\thesis@tate@fix@horizontal}
    823 \newlength{\thesis@tate@fix@vertical@height}
    824 \newlength{\thesis@tate@fix@vertical@delta}
    825 \NewDocumentCommand\tatefix{m m m}{%
    826 	\setlength{\thesis@tate@fix@horizontal}{#1}%
    827 	\setlength{\thesis@tate@fix@vertical@height}{#2}%
    828 	\setlength{\thesis@tate@fix@vertical@delta}{#3}%
    829 }
    830 
    831 \NewDocumentEnvironment{cjkepigraphcontent}{O{} +b}
    832 	{%
    833 		\lapbox[\width]{\thesis@tate@fix@horizontal}{%
    834 			\begin{minipage}[b]{5mm}%
    835 				\raisebox{-\thesis@tate@fix@vertical@delta}[\dimexpr\totalheight-\thesis@tate@fix@vertical@height\relax][0mm]{\tate{#1{「#2」}}}%
    836 			\end{minipage}%
    837 		}%
    838 		\tatefix{0mm}{0mm}{0mm}%
    839 	}{}
    840 
    841 \NewDocumentEnvironment{cjkepigraph}{O{} m m o +b}
    842 	{%
    843 		\begin{marginparagraph}%
    844 			\begin{minipage}[b]{#2}
    845 				#3
    846 			\end{minipage}%
    847 			\begin{cjkepigraphcontent}[#1]%
    848 				#5%
    849 			\end{cjkepigraphcontent}%
    850 			\IfValueT{#4}%
    851 				{\newline\null\hfill\begin{minipage}{#2}%
    852 					\hbadness=7000%
    853 					#4%
    854 				\end{minipage}}%
    855 		\end{marginparagraph}%
    856 	}{}