PhD

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

thesis.cls (23656B)


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