%!TEX root=template.tex

%% ----------------------------------------------------------------------------
%%  novathesis — nt-packages.sty
%% ----------------------------------------------------------------------------
%%
%% Version 8.4.0 (2026-09-27)
%% Copyright (C) 2004-26 by João M. Lourenço <joao.lourenco@fct.unl.pt>
%% Departamento de Informática (www.di.fct.unl.pt)
%% Faculdade de Ciências e Tecnologia (www.fct.unl.pt)
%% Universidade NOVA de Lisboa (www.unl.pt)
%%
%% All package loading: memoir base class, utility packages, fonts & encodings,
%% language support, graphics, bibliography, hyperref & glossaries.
%% ----------------------------------------------------------------------------

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% WRITE-REGISTER GUARD (must come before any other \newwrite)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% pdflatex and xelatex are limited to 16 \write registers; LuaTeX allows 65536.
% Since 8.0 glossaries are handled by bib2gls and no longer consume registers,
% so the class floor dropped to 9 and a typical document fits comfortably
% within 16.  morewrites (which virtualises the pool but makes a pdflatex pass
% roughly 9x slower) is therefore NOT loaded by default.
%
% A document that overshoots the 16 registers -- reported as "No room for a
% new \write" -- can re-enable morewrites by defining \ntmorewrites BEFORE
% \documentclass:
%
%     \def\ntmorewrites{}
%     \documentclass{novathesis}
%
% or, with the build system, by passing FASTWRITES=0 (see the Makefile).
% LuaLaTeX never needs morewrites, so the switch is a no-op there.
%
% The extra consumers beyond the class floor are one register each for
% \listofalgorithms and \listoflistings (only when actually used), plus
% whatever the document's own packages allocate (e.g. minted, via fancyvrb).
% Only such register-heavy documents need \ntmorewrites.  (The symbols
% glossary costs nothing: under bib2gls "record" mode no glossary consumes a
% \write register, which is why 'symbols' is passed to glossaries-extra
% unconditionally further down.)
%
% Legacy note: \ntnomorewrites (the pre-8.0 opt-out) is now redundant, since
% skipping is the default; it is still honoured and overrides \ntmorewrites.
\RequirePackage{iftex}
\ifluatex\else
  \ifdefined\ntmorewrites
    \ifdefined\ntnomorewrites\else\RequirePackage{morewrites}\fi
  \fi
\fi

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% KERNEL & CORE UTILITIES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Save \Roman / \@Roman immediately — pdflatex + greek (LGR encoding)
% clobbers them, and we need the originals for the \annex command.
\let\oldRoman=\Roman
\let\old@Roman=\@Roman

% ── Hook API ──────────────────────────────────────────────────────────
% Thin wrappers over the LaTeX kernel hook engine (LaTeX 2020-10-01+).
% Hook names are namespaced under 'novathesis/' to avoid conflicts with
% kernel or package hooks.  \ActivateGenericHook (LaTeX 2024+) makes
% \UseHook a silent no-op when no code has been added to the hook.
\newcommand*{\NTAddToHook}[2]{\AddToHook{novathesis/#1}{#2}}
\newcommand*{\NTDeclareHook}[1]{\ActivateGenericHook{novathesis/#1}}
\newcommand*{\NTRunHook}[1]{\ActivateGenericHook{novathesis/#1}\UseHook{novathesis/#1}}

% ── Directory macros ──────────────────────────────────────────────────
\def\DIRCONFIG{0-Config}
\def\DIRFRONTMATTER{1-FrontMatter}
\def\DIRMAINMATTER{2-MainMatter}
\def\DIRBACKMATTER{3-BackMatter}
\def\DIRBIBLIOGRAPHY{4-Bibliography}
\def\DIRFIGURES{5-Figures}
\def\DIRNTFILES{./novathesisFiles}
\def\DIRSTYFILES{\DIRNTFILES/StyFiles}
\def\DIRFONTSTYLES{\DIRNTFILES/FontStyles}
\def\DIRSCHOOLS{\DIRNTFILES/Schools}
\def\DIRSTRINGS{\DIRNTFILES/Strings}
\def\DIRCHAPSTYLES{\DIRNTFILES/ChapStyles}
\def\DIRIMAGES{\DIRNTFILES/Images}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% MEMOIR BASE CLASS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand*{\ntmemoirsetup}[1]{\PassOptionsToClass{#1}{memoir}}
\input{\DIRCONFIG/0_memoir}
\LoadClass{memoir}

\OnehalfSpacing


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% CORE PACKAGES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\RequirePackage[table,svgnames]{xcolor} % Must be loaded first to avoid option clashes
% iftex (\ifpdftex, \ifxetex, \ifluatex, \iftutex …) is already loaded by the
% write-register guard at the top of this file.
% ifplatform removed: its \ifwindows/\iflinux/\ifmacosx are unused here, and it
% shell-escapes `uname` into \jobname.w18 on every build — a per-build cost and,
% under parallel matrix builds sharing one cwd, a race (see build notes).
\RequirePackage{xfor}        % Extended \foreach loop (\xfor, \xforeach)
\RequirePackage{etoolbox}    % Programmer's toolbox: hooks, patching, booleans
\RequirePackage{xstring}     % String manipulation (\StrBehind, \StrCut, …)
\RequirePackage{catchfile}   % Read a file's contents into a macro
\RequirePackage{varwidth}    % Variable-width minipage environment
\RequirePackage{calc}        % Arithmetic in length/counter expressions
\RequirePackage{hologo}      % Typeset TeX-family logos
% Some logo names are newer than the hologo build a TeX distribution ships
% with (e.g. "TeXLive" was only added to hologo in 2025/11/11, so Overleaf's
% currently-deployed hologo -- and any older local TeX Live -- doesn't know
% it and \hologo{TeXLive} raises "Unknown logo"). Provide hand-made stand-ins
% for such names below, but ALWAYS prefer hologo's own definition when it
% exists: \ifcsname HoLogo@<name>\endcsname is hologo's internal storage for
% a known logo (stable across all hologo versions, old and new alike), so
% the moment the installed hologo is updated to know a name, this wrapper
% silently steps aside and defers to it -- no further changes needed here.
\ExplSyntaxOn
\cs_new:Npn \nt@hologo@fallback@TeXLive { \hologoRobust{TeX}\,Live }
% Wrap \hologo in \NoCaseChange so \MakeUppercase never uppercases logo names
% (LaTeX 2020+ case-changing engine uppercases even protected-command arguments).
\cs_set:Npn \hologo #1
  {
    \NoCaseChange
      {
        \cs_if_exist:cTF { HoLogo@#1 }
          { \hologoRobust{#1} }
          {
            \cs_if_exist:cTF { nt@hologo@fallback@#1 }
              { \use:c { nt@hologo@fallback@#1 } }
              { \hologoRobust{#1} } % unknown to both -- let hologo raise its own error
          }
      }
  }
\ExplSyntaxOff
% In PDF strings (bookmarks) render \hologo{X} as plain text "X".
\AtBeginDocument{%
  \pdfstringdefDisableCommands{%
    \def\hologo#1{#1}%
  }%
}

% Add StyFiles and Strings to \input search path so bare filenames work
\xappto\input@path{{\DIRSTYFILES/}{\DIRSTRINGS/}}

\RequirePackage{nt-options}       % Key-value option system (internal, l3keys-backed -- see its own header)
\RequirePackage{nt-version}       % \novathesisversion / \novathesisdate
\RequirePackage{nt-covers}  % Cover page rendering engine
\RequirePackage{memstore}         % Data storage API (\NewMemStore, \MemSet, \MemGet, …)
\RequirePackage{stocksize}        % Paper / stock size handling


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% FONTS & ENCODINGS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\RequirePackage[verbose=silent]{microtype}  % Microtypography: character protrusion & font expansion

\iftutex
  \RequirePackage[no-math]{fontspec}  % OpenType font selection (XeLaTeX / LuaLaTeX)
  \defaultfontfeatures{Ligatures=TeX}
\else
  \RequirePackage[T1]{fontenc}  % 256-glyph output encoding (pdfLaTeX)
\fi

% Preferred sans-serif stack: Inter → Helvet → Gillius2 → LaTeX default
\ExplSyntaxOn
% The ClassWarning text uses "~" instead of literal spaces: under
% ExplSyntaxOn, space (catcode 9) is ignored, but "~" is catcode 10
% (an ordinary interword space), so it survives untouched.
\IfFileExists { inter.sty }
  { \RequirePackage[scaled=0.95]{inter} }
  % { \RequirePackage[scaled=MatchLowercase]{inter} }
  {
    \IfFileExists { helvet.sty }
      { \RequirePackage[scaled=0.95]{helvet} }
      {
        \IfFileExists { gillius2.sty }
          { \RequirePackage[scaled=0.95]{gillius2} }
          { \ClassWarning{novathesis}{Could~not~find~a~suitable~Sans~Serif~font…~using~the~default!} }
      }
  }
\ExplSyntaxOff

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% LANGUAGE & LOCALIZATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\RequirePackage[english]{babel}  % Multilingual support; active language switched later

% Provide fallback stubs for older babel versions that lack these commands
\AtBeginDocument{%
  \ifx\bbl@ensure@bcp\@undefined
    \newcommand{\bbl@ensure@bcp}[2]{#2}%
  \fi
  \ifx\bbl@ensure@english\@undefined
    \newcommand{\bbl@ensure@english}[1]{#1}%
  \fi
}

\IfFileExists{fvextra.sty}{\RequirePackage{fvextra}}{}% Load before csquotes if available (suppresses ordering warning for minted users)
\RequirePackage{csquotes}  % Must be loaded before biblatex


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% GRAPHICS & TABLES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\RequirePackage{tikz}     % PGF/TikZ drawing engine (used by cover renderer)
\RequirePackage[nobeamer]{graphbox} % Loads graphicx + \includegraphics[align=…]
\RequirePackage{colortbl} % Coloured table cells (\columncolor, \rowcolor, …)
\RequirePackage{xurl}               % Loads 'url' with improved line-breaking

% Silence the harmless "multiple pdfs with page group included in a single
% page" warning emitted when several PDF logos (with transparency groups) are
% placed on one cover page.  This is a pdfTeX-only warning: LuaTeX does not
% emit it (and setting its \pdfvariable form here disturbs backend init), and
% XeTeX uses a different backend.  Guard on the primitive so it acts only
% where it exists (pdfTeX).
\ifdefined\pdfsuppresswarningpagegroup \pdfsuppresswarningpagegroup=1 \fi

% ── Customize Graphcics package ───────────────────────────────────────
\expandafter\graphicspath\expandafter{\expandafter{\DIRFIGURES/}}
\DeclareGraphicsExtensions{.pdf,.png,.tif,.jpg}
\providecommand*\appendtographicspath[1]{\xappto\Ginput@path{#1}}
\providecommand*\prependtographicspath[1]{\xpreto\Ginput@path{#1}}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% BIBLIOGRAPHY & INDEXING
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% \ntbibsetup{key=value,...} — pass options to biblatex before it is loaded.
% Must be called before \begin{document}.
\NewDocumentCommand{\ntbibsetup}{m}{%
  \@ifpackageloaded{biblatex}
      {\ClassError{novathesis}{Please load biblatex options earlier.}{}}
      {\PassOptionsToPackage{#1}{biblatex}}%
}

\input{\DIRCONFIG/2_biblatex}

% biblatex and imakeidx are deferred until after school configs are loaded
% so that school-specific options set via \ntbibsetup take full effect.
% imakeidx must be loaded before hyperref.
\NTAddToHook{afterloading/schoolconfig}{%
  \RequirePackage{biblatex}   % Modern bibliography engine (biber backend)
  \RequirePackage{imakeidx}   % Multiple-index support; must load before hyperref
}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% HYPERREF & INTERACTIVE ELEMENTS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\AtEndPreamble{%
  % ── hyperref options (must be registered before anyone loads hyperref) ──
  % This block runs before the \ifdocfinal/pdfx block so that when pdfx
  % loads hyperref itself (in PDF/A-2b mode) these options are already
  % registered via \PassOptionsToPackage and are merged in at load time.
  \PassOptionsToPackage{
    bookmarksnumbered=true,
    bookmarksdepth=3,
    breaklinks=true,
    colorlinks=true,
    hypertexnames=true,     % prevents duplicate PDF destinations from memoir's double caption rendering
    pdfdisplaydoctitle=true,
    unicode=true,
  }{hyperref}
  % ── PDF/A-2b archival output (single-pass) ────────────────────────
  % When docstatus=final and pdfa=true (the default), load pdfx[a-2b]
  % BEFORE hyperref so pdfx controls the PDF version and XMP metadata.
  %
  % LuaLaTeX fix: pdfx.sty line 72 reads \pdfminorversion BEFORE loading
  % luatex85 (line 323), which maps \pdfminorversion → \pdfvariable minorversion
  % (= 7).  Pre-loading luatex85 here ensures \pdfminorversion = 7 when pdfx
  % reads it, so \pdfx@minorversion = 7 = \pdfminorversion at the version check
  % (line 341) → no "Cannot change the \pdfminorversion" error.
  \ifdocfinal{%
    \iftoggle{/novathesis/pdfa}{%
      % Write XMP metadata file for pdfx (cover data available from 3_cover.tex)
      \newwrite\@nt@xmp@out
      \immediate\openout\@nt@xmp@out=\jobname.xmpdata
      \immediate\write\@nt@xmp@out{\string\Title{\GetDocTitle(\@LANG@MAIN,main,plain)}}%
      \immediate\write\@nt@xmp@out{\string\Author{\GetDocAuthor(name)}}%
      \immediate\write\@nt@xmp@out{\string\Language{\@LANG@MAIN}}%
      \immediate\closeout\@nt@xmp@out
      % Pre-load luatex85 before pdfx so the pdfminorversion check is correct
      \@ifpackageloaded{luatex85}{}{\RequirePackage{luatex85}}%
      \RequirePackage[a-2b]{pdfx}%    % sets PDF/A-2b and embeds XMP metadata
    }{}%
  }{}%
  % ── hyperref ──────────────────────────────────────────────────────
  \RequirePackage{hyperref}           % PDF hyperlinks, metadata & bookmarks
  \RequirePackage{fix-hyperref}       % Patches hyperref immediately after loading
  \RequirePackage{bookmark}           % Extends hyperref bookmarks

  % ── glossaries-extra (must be loaded after hyperref) ──────────────
  \PassOptionsToPackage{
    translate=babel,
    acronym,           % add acronyms listing
    symbols,           % free in record mode (no \write)
    record,            % bib2gls backend: entries come from .bib via the .aux
    % sanitizesort=false, % allow \gls inside sort keys
    % xindy={language=\@LANG@MAIN@LONG},
    nolong,
    nosuper,
    nolist,
    notree,
    nostyles,
  }{glossaries-extra}
  \RequirePackage{glossaries-extra}   % Glossaries, acronyms & symbols (extends glossaries)
  \RequirePackage{glossary-xltabular} % xltabular-based glossary layout style

  \setglossarystyle{xltabular}
  \setabbreviationstyle[acronym]{long-short}
  % Location-list prefix: one location vs several.  Deliberately free of '@'
  % so they survive being written to the .glstex and read back in document
  % context, and so users can redefine them in 0-Config/5_packages.tex.
  \newcommand*{\ntglslocprefixone}{\emph{(\small p.~}}%
  \newcommand*{\ntglslocprefixmany}{\emph{(\small pp.~}}%
  % NB: the "p."/"pp." prefix is NOT set with \GlsXtrEnablePreLocationTag --
  % that hook does not fire against location lists built by bib2gls, which
  % silently leaves every entry reading "(p. 1, 40)".  bib2gls has its own
  % mechanism: the loc-prefix resource option in \@loadglossaryfiles (see
  % nt-render-matter.sty), whose first value is used for a single location
  % and the second for several.  The closing parenthesis stays here.
  \renewcommand{\GlsXtrFormatLocationList}[1]{\emph{\small#1)}}
  \renewcommand{\glsnamefont}[1]{\textbf{#1}}
  \newcommand*{\glsplainhyperlink}[2]{%
    \begingroup
      \hypersetup{hidelinks}%
      \hyperlink{#1}{#2}%
    \endgroup
  }%

  % Ensure \printglossary inserts a PDF bookmark at the correct level
  \let\printglossaryORIG\printglossary
  \def\printglossary{%
    \bookmarksetupnext{level=1}%
    \printglossaryORIG%
  }

  \iftoggle{/novathesis/glossaries/list/reverse}
           {}
           {\setupglossaries{nonumberlist}}
  \AtBeginDocument{\@loadglossaryfiles}
}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% AI DISCLOSURE
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\AtEndPreamble{%
  % Upstream aidisclose package (bundled in StyFiles). autobib=false because
  % the thesis supplies the cite keys via StyFiles/fix-bib.bib; letting the
  % package auto-write its own aidisclose.bib would duplicate those keys.
  \RequirePackage[autobib=false,nocite=false]{aidisclose}  % AI disclosure watermark / statement
}
