% MIT thesis class

% !TEX encoding = UTF-8 Unicode
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%%  This file provides the mitthesis LaTeX class for formatting theses according to 
%%  MIT Libraries' requirements as of 2025.
%%
%%  This file's version and date:
	\def\versionno{1.22}
	\def\versiondate{2026/01/31\space}
%%
%%  Author: John H. Lienhard, V
%%          Department of Mechanical Engineering
%%          Massachusetts Institute of Technology
%%          Cambridge, MA 02139-4307 USA
%%
%%  This class is compatible with either pdfLaTeX or LuaLaTeX. 
%%
%%	Use an up-to-date LaTeX distribution: TeX Live 2023 or later is strongly recommended!
%%	All packages required by the class are in TeX Live and available from CTAN (https://ctan.org/). 
%%
%%
% =========================================================
%%
%% LICENSE:
%%
%% Copyright (c) 2026 John H. Lienhard
%%
%% Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 
%% associated documentation files (the "Software"), to deal in the Software without restriction, 
%% including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 
%% and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 
%% subject to the following conditions:
%%
%% The above copyright notice and this permission notice shall be included in all copies or 
%% substantial portions of the Software.
%%
%% The software is provided "as is", without warranty of any kind, express or implied, including but 
%% not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. 
%% In no event shall the authors or copyright holders be liable for any claim, damages or other liability, 
%% whether in an action of contract, tort or otherwise, arising from, out of or in connection with the 
%% software or the use or other dealings in the software.
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{mitthesis}[\versiondate MIT Thesis Template (JHL)]

\LoadClass[12pt,openright]{report}% [twoside] option can be issued in the .tex file; point size must be set here.

\newif\ifpdftex % redeclaration by another package will be ignored
\ExplSyntaxOn
	\str_const:Nn \ClassName {mitthesis}
	\prop_gput:Nnn \g_msg_module_type_prop { \ClassName } { Class }
	\sys_if_engine_pdftex:T  
		{ 
		  \pdftextrue
	   	  \msg_new:nnn { \ClassName } { notagpdftex } { Run~lualatex,~not~pdftex,\iow_newline: 
		  												when~tagging~is~used~in~\DocumentMetadata } 
		  \cs_if_exist:NT \tag_if_active:T % not in TeX Live 2021
			{
		     \tag_if_active:T { \msg_error:nn  { \ClassName } { notagpdftex } }
			}
		}
\ExplSyntaxOff


\providecommand\IfFormatAtLeastTF{\@ifl@t@r\fmtversion}% compare version to date; \If... added to latex 2020/10/01

\IfFormatAtLeastTF{2022/06/01}{\relax}{%
	\ClassError{\ClassName}{Your LaTeX format is dated \fmtversion.  Formats dated 2022-06-01 or later are necessary for this class. Older formats are not supported and will generate serious errors.}{UPDATE your LaTeX distribution. TeX Live is available for download at no charge: \string https://www.tug.org/texlive/.}%
}


%%%%%%%%%%%%%  Some compatibility for older latex distributions  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%% Dropping this backward compatibility 2025/10/24 (needed for formats older than 2022/06/01, i.e., TeX Live pre-2022)

%\providecommand\IfPackageAtLeastTF{\@ifpackagelater}%    compare version to date; \If... added to latex 2020/10/01
%\providecommand\IfPDFManagementActiveTF{\@secondoftwo}%  \If... added to latex 2021/07/23
%\providecommand\IfPackageLoadedTF{\@ifpackageloaded}%    \If... added to latex 2021/11/15
%\providecommand\ClassNoteNoLine[2]{\typeout{^^J Class Note #1: #2. ^^J}}%  log & terminal note... added to latex 2021/11/15

%% check whether pdfmanagement (\DocumentMetadata) has been loaded (if not, fall back to hyperxmp and bookmark packages after loading hyperref)
%\newif\ifmit@pdfmanagement
%\IfPDFManagementActiveTF{
%	\mit@pdfmanagementtrue 
%}{
%	\mit@pdfmanagementfalse
%	\ClassWarningNoLine{\ClassName}{pdfmanagement is not active. Will load hyperxmp and bookmark packages instead}
%}

%% Allow pre 2021/11/15 formats to see the graphicx alt key without causing an error
%\IfFormatAtLeastTF{2021/11/15}{
%	\relax
%}{ 
%	\AtBeginDocument{
%		\IfPackageLoadedTF{graphicx}{\define@key{Gin}{alt}{}}{\relax}
%	}
%}

%% Also, more than a dozen expl3 variant control sequences are generated for backward compatibility, mostly ca. 2023.


%%%%%%%%%%%%%% Options for the class %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\ExplSyntaxOn

\newif\ifmit@mydesign
\cs_new_protected:Npn \__mitthesis_gset_testdesign:n #1
	{
    	\mit@mydesigntrue
    	\tl_new:N       \g__mitthesis_testkey_tl
    	\tl_gset:Nn     \g__mitthesis_testkey_tl {#1}
    	\tl_if_empty:NT \g__mitthesis_testkey_tl { \tl_gset:Nn \g__mitthesis_testkey_tl {mydesign} } 
	}

\IfFormatAtLeastTF{2022/11/01}{%
    \DeclareKeys{
    	fontset  	  .store  = \mit@fontset ,
    	fontset  	  .usage  = load ,
    	lineno   	  .if     = mit@lineno ,
    	lineno 	 	  .usage  = load ,
    	mydesign 	  .code	  = \__mitthesis_gset_testdesign:n {#1} , 
    	mydesign 	  .usage  = load,
    } 
    \SetKeys[\ClassName]{fontset=defaultfonts}%
	\DeclareUnknownKeyHandler[\ClassName]{\relax}% suppress warning about unused keys
	\ProcessKeyOptions
}{% And more compatibility code for distributions pre-2022/11; this will be dropped eventually.     
    \RequirePackage{kvoptions}
    \SetupKeyvalOptions{
      family=\ClassName,
      prefix=mit@,
      setkeys=\kvsetkeys,
    }
    % set key [fontset] for font selection
    \DeclareStringOption[defaultfonts]{fontset}[]
    % set key [lineno] to load package lineno
    \DeclareBoolOption{lineno}
    % set key [mydesign] to input file mydesign.tex
    \define@key{\ClassName}{mydesign}[mydesign]
    	{ \__mitthesis_gset_testdesign:n {#1} }
    %
    \ProcessKeyvalOptions{\ClassName}
    %
    %% Turn off these keys now that we're done with them
    \NewDocumentCommand\mit@DisableOption{m}{%
      \DisableKeyvalOption[%
        action=ignore,%
        class=\ClassName%
      ]{#1}{\ClassName}%
    }
    \NewDocumentCommand\mit@DisableKeys{>{\SplitList{;}}m}{\ProcessList{#1}{\mit@DisableOption}}
    %
    \mit@DisableKeys{fontset;lineno;mydesign}%
    %
    % Suppress warnings about unused global options
    \DeclareOption*{}  
    \ProcessOptions \relax
}
\ExplSyntaxOff


%%%%%%%%%%%%%  Line numbering (class option)  %%%%%%%%%%%%%%%%%%%%%%%%%

\ifmit@lineno
    \RequirePackage[mathlines]{lineno} 
    \AtBeginDocument{\linenumbers}
\fi

%%% Enable dropping lineno option without trashing .aux file
\providecommand{\@LN@col}[1]{\relax}
\providecommand{\@LN}[2]{\relax}


%%%%%%%%%%%%%  Patch table of contents, list of figures, and list of tables  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% We'd like these sections to have pdf bookmarks and to have the two lists appear in the table of contents and have
% pdf bookmarks.  This is not automatic for \chapter*, which is the format of toc, lof, and lot.

\RequirePackage{etoolbox}% provides \patchcmd

\patchcmd{\tableofcontents}{\contentsname}{\pdfbookmark[0]{Table of Contents}{toc}\contentsname}{}{} % placement matters.

%% Code to accommodate latex tagging. Rework once LaTeX3 team have finalized tagging structures.
%% Current latex-lab places tags around \@schapter, which is harder to deal with here.

\ProvideDocumentCommand\MakeLinkTarget{ s O{} m }{}

\patchcmd{\listoffigures}{\chapter*{\listfigurename}}%
		{\chapter*{\MakeLinkTarget*{listoffigures}\listfigurename}\addcontentsline{toc}{frontmatter}{\listfigurename}}{}{}
\patchcmd{\listoftables}{\chapter*{\listtablename}}%
		{\chapter*{\MakeLinkTarget*{listoftables}\listtablename}\addcontentsline{toc}{frontmatter}{\listtablename}}{}{}
% removed \phantomsection, move \MakeLinkTarget* inside \chapter*, 2025/04/28. (was \chapter*{\phantomsection\listtablename}\MakeLinkTarget*{listoftables}...)

\NewCommandCopy\l@frontmatter\l@chapter
\NewCommandCopy\l@backmatter\l@chapter
\providecommand*{\toclevel@frontmatter}{0}% prevent warning, see hyperref manual Sec. 13.3
\providecommand*{\toclevel@backmatter}{0}

%% if you want different formatting for front/back matter, change here (cf. report.cls). 
\patchcmd{\l@frontmatter}{\bfseries}{\itshape}{}{}
\patchcmd{\l@frontmatter}{\nobreak\hfil}{\upshape\nobreak\hfil}{}{}
\patchcmd{\l@frontmatter}{1.0em}{3pt}{}{} 
\patchcmd{\l@backmatter}{\bfseries}{\itshape}{}{}
\patchcmd{\l@backmatter}{\nobreak\hfil}{\upshape\nobreak\hfil}{}{}


%%%%%%%%%%%%%  Geometry, mathtools, graphics, design, fonts, hyperrefs, bookmarks, footnotes %%%%%%%%%%%%%%%%%%%

\RequirePackage[letterpaper,top=1in,bottom=1in,left=1in,right=1in,marginparwidth=50pt,headsep=12pt,footskip=0.5in,heightrounded]{geometry} 
% 44\baselineskip = \textheight - \topskip = 650.0pt - 12pt with rounded height

\RequirePackage{mathtools}% loads and extends amsmath; must load before hyperref and unicode-math

% To free \eqref from the normal font (i.e., for use in section headings)
\renewcommand{\eqref}[1]{\textup{\hbox{\m@th{(\ignorespaces\ref{#1}\unskip\@@italiccorr)}}}}
%
% amsmath def:  \newcommand{\eqref}[1]{\textup{\tagform@{\ref{#1}}}}
%				\def\tagform@#1{\maketag@@@{(\ignorespaces#1\unskip\@@italiccorr)}}
%				\def\maketag@@@#1{\hbox{\m@th\normalfont#1}}

% To streamline switching from lualatex to pdftex when using sample chapter 1, which puts \psi (as \mitpsi) in a toc entry
\ifpdftex\providecommand\mitpsi{\psi}\fi

\RequirePackage{graphicx}


%%%%%%%%%%%%  Design options  %%%%%%%%%%%%%%%%%%%%%%%%%%%

% the packages in mydesign should come before babel (which may be loaded by fontset) and before hyperref

\ExplSyntaxOn

\msg_new:nnnn { \ClassName } { nodesignfile } 
	{ \g__mitthesis_testkey_tl .tex\iow_newline: cannot~be~not~found.~There~shall~no~design~be~loaded;~
	  and~error~messages~shall~be~multiplied~upon~thee.
	}{ 
	  Thou~hast~called~the~class~option~mydesign,~but~neither~\g__mitthesis_testkey_tl .tex\space
	  nor~mydesign.tex~can~be~found.~Thou~mayst~download~mydesign.tex~from\space
	  https://ctan.org/tex-archive/macros/latex/contrib/mitthesis/MIT-thesis-template. }
\ifmit@mydesign
	\IfFileExists{ \g__mitthesis_testkey_tl .tex }
		{ \input{  \g__mitthesis_testkey_tl .tex } }
		{ \msg_error:nn { \ClassName } { nodesignfile } }
\else
	\RequirePackage[dvipsnames,svgnames,x11names]{xcolor}
	%
	\AtBeginDocument{
		\hypersetup{
		linkcolor=Blue3,% color names from xcolor package
		citecolor=Blue3,
		urlcolor=violet,
		filecolor=red, 
		}
		\ifmit@lineno
			\renewcommand{\linenumberfont}{\sffamily\mdseries\tiny\color{violet}}% add \mdseries 2023/10/11
		\fi
	}
	% \RequirePackage{caption,subcaption}
	% Caption package can be loaded in mydesign.tex, if such features are really needed.
	% Replaced subcaption package with code that follows. 2026/01/24	
\fi


%%%%%% Captions and subcaptions %%%%%%%

\IfPackageLoadedTF{caption}{ % added 2026/01/16
    \tag_if_active:T
    {
    % 	Patch the caption package so we can validate as pdf 2.0/ua-2.
    %     See github discussion by Ulrike Fischer:
    % 	  	https://github.com/latex3/tagging-project/issues/720#issuecomment-2386568711
    %
    \RemoveFromHook{begindocument}[latex-lab-testphase-float]
    \socket_new_plug:nnn{tagsupport/parbox/before}{caption}
      {   
       \tagpdfparaOn % restart para tagging
       \tl_if_empty:NTF\@current@float@struct
        {     
         \tag_struct_begin:n{tag=Caption,firstkid}
        }
        {
         \tag_struct_begin:n{tag=Caption,parent=\@current@float@struct,firstkid}
        }
      }
    \socket_new_plug:nnn{tagsupport/parbox/after}{caption}
      {
       \tag_struct_end:   
      }
    \l@addto@macro\caption@beginex@hook % this is a hook in the caption package
      {
        \tagpdfparaOff % \leavevmode in parbox should not start paragraph structure
        \AssignSocketPlug{tagsupport/parbox/before}{caption}
        \AssignSocketPlug{tagsupport/parbox/after}{caption}
      }
	}
	% Address issue with LOT/LOF. see: https://github.com/latex3/tagging-project/issues/720#issuecomment-2388406105
    \AddToHook{begindocument/end}{
    		\renewcommand*\caption@anchor[1]{%
        	\ifmeasuring@ \else
           	\caption@raisedlink{\MakeLinkTarget*{#1}}%
        	\fi}%
    }
}{\relax}

%%  Use latex-lab hooks/sockets with recent latex version; useful WITHOUT caption package. Does not modify subcaptions as written.
%%  At present, these options do not address the evolving code for tagged longtable captions. 2026/01/28
%%  (Note that subcaption package loads caption package.)
%
\cs_new:Nn \__mitthesis_adjustcaptions: 
	{
%	\setlength\abovecaptionskip{5\p@} % If you desire some adjustments to this dimension.
%
%   The next two are used in mydesign, as examples of making captions or labels bold.  Leaving the code here for reference.
%
%	\NewSocketPlug{caption/label}{plug-A} % This strictly addresses the caption label, not caption text.
%		{{\bfseries  ##1:\space}}
%	\AssignSocketPlug{caption/label}{plug-A}
%	\AddToHook{cmd/@makecaption/before}{\bfseries\mathversion{bold}} % This boldfaces the entire caption, including math IFF this font has a bold version.
%
	\AddToHook{cmd/@makecaption/after}
		{ 
	       \str_if_eq:VnT \@captype { table } { \vskip 0.5\baselineskip } % Separate table caption from tabular below it.
		}
	}

\IfFormatAtLeastTF{2025/11/01}
	{
	\IfPackageLoadedTF{caption}
	{
	\tag_if_active:F { 
		\AddToHook{cmd/@makecaption/after}
			{
		    \str_if_eq:VnT \@captype { table } { \vskip 0.5\baselineskip }
			}
	  	} 
	}{  
	\__mitthesis_adjustcaptions:
	}
}{\relax}

% Subfigures and subcaptions without the subcaption package
\IfPackageLoadedTF{subcaption}
{
	\msg_new:nnn { \ClassName } { subcaptionloaded }
		{ Subcaption~package~has~been~loaded,~so~I~won't\iow_newline: load~mitthesis's~subfigure~or~subcaption~code. } 
	\msg_warning:nn { \ClassName } { subcaptionloaded }
}{
    \newcounter{SubFigure}[figure]
    \renewcommand{\theSubFigure}{
    	\number\numexpr\value{figure}+1\relax(\alph{SubFigure})% this styles the label/ref for a subcaption: Fig. 1(a)
	}
    \NewDocumentCommand\subcaption{m}
		{
		\vskip 5\p@
		\tl_set:Nn   \l_tmpb_tl  { \small ( \alph{SubFigure}) \space #1 } % If you want a different subcaption style, edit this.
		\hbox_set:Nn \l_tmpa_box { \tl_use:N \l_tmpb_tl }
		\dim_compare:nNnTF { \box_wd:N \l_tmpa_box } > { 0.9\hsize }
          {
            \skip_add:Nn \leftskip  {  0.05\hsize }
            \skip_add:Nn \rightskip {  0.05\hsize }      
            \l_tmpb_tl \par      
            \skip_add:Nn \leftskip  { -0.05\hsize }
            \skip_add:Nn \rightskip { -0.05\hsize }
          }{
            \global \@minipagefalse
            \hbox_to_wd:nn \hsize % this won't tag paragraph (it's in vmode) unless sockets are used manually
            { 
                \hfil
                \tag_if_active:T { \UseTaggingSocket { para/begin } }
                \l_tmpb_tl
                \tag_if_active:T { \UseTaggingSocket { para/end } }
                \hfil
            }
          }
        \vskip 5\p@
    }
% first arg (optional) is vertical alignment of subfigure's contents (default is top alignment). [cbt]
% second arg (mandatory) is width of this subfigure
% third  arg (mandatory) is the content of this subfigure 
\NewDocumentEnvironment{subfigure}{ O{t} m +b }
	{
	  \refstepcounter{SubFigure}
	  \begin{minipage}[#1]{#2}
		#3 
	}{
	  \end{minipage}
	  \ignorespacesafterend
	}
}

%%%%%%%%%%%%  Accommodations for tagpdf (if in use)  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%% In case tagging commands are undefined
\cs_if_exist:NF   \tag_struct_begin:n
	{ 
	  \cs_new:Npn \tag_struct_begin:n #1 { \scan_stop: } 
	  \cs_new:Nn  \tag_struct_end:   	 { \scan_stop: } 
	}
\cs_if_exist:NF   \tag_mc_begin:n
	{ 
	  \cs_new:Npn \tag_mc_begin:n    #1 { \scan_stop: } 
	  \cs_new:Nn  \tag_mc_end:       	{ \scan_stop: } 
	}
\cs_if_exist:NF   \tagpdfsetup
	{ 
	  \cs_new:Npn \tagpdfsetup	     #1 { \scan_stop: } 
	}
\cs_if_exist:NF   \UseTaggingSocket
	{
	  \cs_new:Npn \UseTaggingSocket	 #1 { \scan_stop: }
	}

% Can include some css to style the html-rendered thesis, 2025/10/15.
\tag_if_active:T { % 2025/04/26
    \msg_new:nnn    { \ClassName } { no_css_file } {I~can't~find~the~file~mitthesis-style.css.\iow_newline:
    This~optional~file~provides~css~style~if~the~tagged~pdf~is~rendered~into~html.~
    								You~can~ignore~this~warning~if~you~don't~want~styling.}
    \msg_new:nnn    { \ClassName } { css_file_loaded } {The~file~mitthesis-style.css~has~been~loaded.}
    \file_if_exist:nTF {mitthesis-style.css}
    	{
		\tagpdfsetup
			{
			css-list-add = { mitthesis-style.css } % attach this css to the pdf
			}
			\msg_note:nn { \ClassName } { css_file_loaded } 
			}{  
			\msg_note:nn { \ClassName } { no_css_file } 
			}
	% Fix longtable math for css, 2026/01/30. see https://github.com/latex3/tagging-project/issues/1192#issue-3865881705
	% Revise in the future, as table tagging will change.
}
\NewDocumentCommand\CiteNolink{m}{ \begin{NoHyper}\cite{#1}\end{NoHyper} }
% for use in optional arg of \caption[..]{..} to prevent nested link in lof/lot, which breaks tagging.
% included only for limited backward compatibility with TeX Live 2025. 2025/10/25. Will drop this in late 2026.

%%%  Custom tags for this class  %%%%%

\tagpdfsetup { role/user-NS = mitthesis }

\tagpdfsetup { role/new-tag = { Title_sig_block/Div } }
\tagpdfsetup { role/new-tag = { Author/Div } }
\tagpdfsetup { role/new-tag = { Degree/Div } }
\tagpdfsetup { role/new-tag = { Copyright/Div } }

\tagpdfsetup { role/new-tag = { Committee_page/Sect } }
\tagpdfsetup { role/new-tag = { Committee_name/Span  } } % NB: sits in presentation table cell
\tagpdfsetup { role/new-tag = { Committee_block_title/Span } } % Thesis Supervisor or Thesis Readers; sits in presentation table cell

\tagpdfsetup { role/new-tag = { Abstract_page/Sect } }
\tagpdfsetup { role/new-tag = { Abstract_title/Div } }
\tagpdfsetup { role/new-tag = { Abstract_text/Div  } }
\tagpdfsetup { role/new-tag = { Abstract_supervisor/Div  } }

\tagpdfsetup { role/new-tag = { Nomenclature_list/Div  } }
\tagpdfsetup { role/new-tag = { Nomenclature_entry_heading/Span  } }

\ExplSyntaxOff


%%%%%%%%%%%%  Font loading  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\ClassNoteNoLine{\ClassName}{Fontset key is \mit@fontset}
\IfFileExists{fontsets/\ClassName-\mit@fontset.tex}{% 2023/07/03
	\input{fontsets/\ClassName-\mit@fontset.tex}
}{%
	\ClassWarning{\ClassName}{Fontset file \ClassName-\mit@fontset.tex or subdirectory fontsets not found, will look for \mit@fontset.tex in your working directory}
	\IfFileExists{\mit@fontset.tex}{% 2023/08/30
		\input{\mit@fontset.tex}
		}{
    	\ClassWarning{\ClassName}{Fontset file \mit@fontset.tex not found, using default fonts. You may need to place the fontset file into your working directory}
    	\ifpdftex
        	\ClassNoteNoLine{\ClassName}{Loading Computer Modern Roman text and math fonts (default for pdftex)}
        	\RequirePackage[T1]{fontenc}
        	\RequirePackage{bm}	
        	% Patch headings to automatically use bold math with CMR fonts. Compare to report.cls. 
            % Predefined fontsets for which bold math exists: defaultfonts, fira-newtxsf, newtx, newtx-sans-text (all 4 in pdf only); + Lucida.
            % Those fontset files also include this code. 
        	\patchcmd{\section}{\normalfont}{\mathversion{bold}\normalfont}{}{}
        	\patchcmd{\subsection}{\normalfont}{\mathversion{bold}\normalfont}{}{}
        	\patchcmd{\subsubsection}{\normalfont}{\mathversion{bold}\normalfont}{}{}
        	\patchcmd{\paragraph}{\normalfont}{\mathversion{bold}\normalfont}{}{}
        	\patchcmd{\subparagraph}{\normalfont}{\mathversion{bold}\normalfont}{}{}
        \else
        	\ClassNoteNoLine{\ClassName}{Loading Latin Modern text and math fonts (default for unicode engines)}
            \RequirePackage[warnings-off={mathtools-colon,mathtools-overbracket}]{unicode-math}
            % suppress warnings about lack of integration between mathtools and unicode-math.
            % Unicode-math loads fontspec package, but default fonts are not set up by fontspec in the default case.
        \fi
       }
}

%%%%%%%%%%%%  Hyperref  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\RequirePackage[psdextra]{hyperref}
% use hypersetup to set details, in the main .tex file

\urlstyle{same} 		% changes font for \url to the current text font
\RequirePackage{doi} 	% creates macro for hyperlinking doi numbers

%% In case \DocumentMetadata was not loaded
\providecommand\hrefurl[2]{\href{#1}{#2}}

%% Dropping this backward compatibility 2025/10/24 (needed for formats older than 2022/06/01)
%% pdfmanagement loads bookmarks package internally
%\ifmit@pdfmanagement\else
%    \RequirePackage{hyperxmp}
%    \RequirePackage{bookmark}
%\fi

% the user can alter these choices in the preamble, or by 
% using \AtBeginDocument{ \hypersetup{..} } in mydesign.tex 
\hypersetup{
	colorlinks=true,
	pdfborder={0 0 0},
	bookmarksnumbered=true,
	bookmarksopen=true,
	bookmarksopenlevel=1,
	pdfpagelayout=SinglePage,
	pdfdisplaydoctitle=true,
	pdfstartview=Fit,
	pdfnewwindow=true,
%
	pdfcontactaddress={Massachusetts Institute of Technology, 77 Massachusetts Avenue},
	pdfcontactcity={Cambridge, MA},
	pdfcontactpostcode={02139-4307},
	pdfcontactcountry={USA},
	pdfcontacturl={https://dspace.mit.edu/handle/1721.1/7582},% DSPACE@MIT theses page
}
 		
%%%%%%%%%%%%  PDF bookmark strings  %%%%%%%%%%%%%%%%%%%%%%%

%%%     By early 2024, \pdfstring removes all robust commands from bookmarks, so that such commands 
%%%     don't cause errors; the following \pdfstringdisables serve to suppress warnings.

%% \bm may be useful in headings, but let's disable in the associated bookmarks
\pdfstringdefDisableCommands{%
    \def\bm#1#{\relax}%
}
%% Let's disable \( and \) in pdf bookmarks
\pdfstringdefDisableCommands{%
    \def\({\relax}%
    \def\){\relax}%
}
%%% Let's also make sure \NoCaseChange in section headings won't break pdf bookmarks
\pdfstringdefDisableCommands{%
    \let\NoCaseChange\relax%
}
%%% Let's just remove citations from pdf bookmarks
\pdfstringdefDisableCommands{%
    \def\cite{\@gobble}%
}
%%% Let's fix \eqref in pdf bookmarks
\pdfstringdefDisableCommands{%
    \def\eqref#1{(\ref{#1})}%
}
%%% Let's make sure footnotes in section headings don't break pdf bookmarks. (Note: \footnote, as redefined below, is protected)
% \patchcmd{\section}{\sectionmark}{\let\footnote\@gobble\sectionmark}{}{}% <== not needed unless you implement running headers
\pdfstringdefDisableCommands{%
  \def\footnote#1{}%
}

%%% Here's a more cumbersome removal of the warning for $ (math shift) in pdfbookmarks.
%%% Not implementing this by default, since novice authors may benefit from the warning. :-)
%%% 	see: https://tex.stackexchange.com/a/620360/119566
%\let\oldHyPsd@CatcodeWarning\HyPsd@CatcodeWarning
%\renewcommand{\HyPsd@CatcodeWarning}[1]{% 
%  \ifnum\pdfstrcmp{#1}{math shift}=0    % If 'math shift' is present, do nothing
%  \else                                 
%    \oldHyPsd@CatcodeWarning{#1}%       % else, keep usual warning.
%  \fi
%}


\ExplSyntaxOn
%\debug_on:n { all }

%%%%%%%%%%  Commas between successive footnotes %%%%%%%%%%

\cs_new:Npn   \__mitthesis_NoteComma:n { \peek_meaning:NT \footnote { \textsuperscript{ \mdseries, } } }
\cs_new_eq:NN \__mitthesis_savefootnote: \footnote
\cs_gset_protected:Npn \footnote #1    { \__mitthesis_savefootnote: {#1} \__mitthesis_NoteComma:n } 


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%  MACROS FOR HANDLING TITLE AND ABSTRACT PAGES  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\AtBeginDocument{ % in case microtype is not loaded
	\ProvideDocumentCommand\textls{s o m}{
		\bgroup
		#3
		\egroup
	}
	\ProvideDocumentCommand\lsstyle{}{\relax}
}

%%%%%%%%%%  Degree Date Module  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\tl_new:N \g__mitthesis_dd_month_tl	
\tl_new:N \g__mitthesis_dd_year_tl

\cs_generate_variant:Nn  \tl_gremove_all:Nn {No}
\cs_new_protected:Nn   \__mitthesis_gset_dd_dates:nn {
	\tl_gset:Nn        \g__mitthesis_dd_month_tl {#1}
	\tl_gset:Nn        \g__mitthesis_dd_year_tl  {#2}
	\tl_gremove_all:No \g__mitthesis_dd_month_tl { \space }
	\tl_gremove_all:No \g__mitthesis_dd_year_tl  { \space }
 	\str_case_e:nnF 
		{ \str_lowercase:f { \tl_to_str:N  \g__mitthesis_dd_month_tl } }
	 	{ {february}{} {may}{} {june}{} {september}{} }
		{ \msg_error:nnn { \ClassName } { wrong_month } {#1} } 
}
\msg_new:nnnn { \ClassName } { wrong_month } 
	{ The~degree~month~must~be~one~of~February,~May,~June,~or~September. } 
	{ MIT~does~not~use~#1~as~the~degree~month. }

\NewDocumentCommand\DegreeDate{mm}{ %   {month}{year}	
	\__mitthesis_gset_dd_dates:nn {#1} {#2}
	\cs_new:Npn \DegreeMonth { \text_titlecase_first:n { \text_lowercase:n \g__mitthesis_dd_month_tl } }
	\cs_new:Npn \DegreeYear  { \text_expand:n { \g__mitthesis_dd_year_tl  } } % edited 2024/06/24
}
\msg_new:nnnn { \ClassName } { no_degree_date } { Missing~degree~date! }{
			You~MUST~issue~the~\DegreeDate{month}{year}~command~between~\string\begin{document}~and~\string\maketitle. }
		
\NewDocumentCommand\ThesisDate{m}{
	\tl_if_exist:NTF \g_mitthesis_dd_thesisdate_tl 
		{ \g_mitthesis_dd_thesisdate_tl } { \__mitthesis_gset_dd_thesisdate:n {#1} }% will use only value given first
}

\cs_if_exist:NF  \tl_gset:Ne { \cs_generate_variant:Nn \tl_gset:Nn {Ne} } % not in TeX Live 2022.
\cs_if_exist:NF  \tl_set:Ne  { \cs_generate_variant:Nn \tl_set:Nn  {Ne} } % not in TeX Live 2022.
\cs_new_protected:Nn \__mitthesis_gset_dd_thesisdate:n {
	\tl_new:N        \g_mitthesis_dd_thesisdate_tl
	\tl_gset:Ne      \g_mitthesis_dd_thesisdate_tl { \tl_trim_spaces:n {#1} }
}

% If for some reason you don't want a warning when you supply the wrong month
\NewDocumentCommand\SuppressMonthError{}
  {
  	\msg_redirect_name:nnn { \ClassName } { wrong_month } { none }
  }

%%%%%%%%%%  End Degree Date Module  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%%%%%%%%%  Author Module  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\seq_new:N \g__mitthesis_author_name_seq
\seq_new:N \g__mitthesis_author_department_seq
\seq_new:N \g__mitthesis_author_prevdegree_seq
\seq_new:N \g__mitthesis_author_secondprevdegree_seq
\seq_new:N \g__mitthesis_author_thirdprevdegree_seq
\seq_new:N \g__mitthesis_author_fourthprevdegree_seq
\int_gzero_new:N \g__mitthesis_author_cnt_int

\NewDocumentCommand\Author{ mm O{} O{} O{} O{} }
 {
 	\tl_if_blank:nTF {#1} 
		{
		  \msg_error:nn { \ClassName } { blank_author }
		}{
		  \__mitthesis_gset_author_data:nnnnnn { #1 } { #2 } { #3 } { #4 } { #5 } { #6 }
		}
	\tl_if_blank:nT {#2} { \msg_error:nn {\ClassName} {blank_author_dep} }
 }
\msg_new:nnnn { \ClassName } { blank_author } 
				{ Missing~author~name, \iow_newline: check~for~blank~in~\Author~command. }
				{ You~MUST~provide~an~author~name~using~the~\Author{name}{department}~command. }
\msg_new:nnnn { \ClassName } { blank_author_dep } 
				{ Missing~author~department, \iow_newline: check~for~blank~in~\Author~command. }
				{ You~MUST~provide~the~author's~department~using~the~\Author{name}{department}~command. }

\cs_if_exist:NF \seq_gput_right:ce { \cs_generate_variant:Nn \seq_gput_right:Nn {ce} } % not def'd in 2023-06-30 latex3

\cs_new_protected:Nn \__mitthesis_gset_author_data:nnnnnn
 {
	\int_gincr:N \g__mitthesis_author_cnt_int
	\seq_gput_right:ce  { g__mitthesis_author_name_seq }        { \tl_trim_spaces:n {#1} } 
	\seq_gput_right:ce  { g__mitthesis_author_department_seq }  { \tl_trim_spaces:n {#2} }
	\seq_gput_right:ce  { g__mitthesis_author_prevdegree_seq }  { \tl_trim_spaces:n {#3} }
	\seq_gput_right:ce  { g__mitthesis_author_secondprevdegree_seq } { \tl_trim_spaces:n {#4} }
	\seq_gput_right:ce  { g__mitthesis_author_thirdprevdegree_seq  } { \tl_trim_spaces:n {#5} }
	\seq_gput_right:ce  { g__mitthesis_author_fourthprevdegree_seq } { \tl_trim_spaces:n {#6} }
 }

\NewExpandableDocumentCommand\CopyrightAuthor{}{
	\tl_if_exist:NTF \g__mitthesis_copyright_author_tl
		{ \g__mitthesis_copyright_author_tl }
		{ \__mitthesis_gset_copyright_author: \g__mitthesis_copyright_author_tl }
}

\cs_if_exist:NF \cs_gset:Npe      { \cs_generate_variant:Nn \cs_gset:Npn {Npe}      } % for backward compatibility
\cs_if_exist:NF \tl_gput_right:Ne { \cs_generate_variant:Nn \tl_gput_right:Nn {Ne}  } %   not in 2023-06-30 Latex3 

\cs_new_protected:Nn \__mitthesis_gset_copyright_author: {
	\tl_new:N       \g__mitthesis_copyright_author_tl
	\int_set:Nn 	\l_tmpa_int {1} % counts authors
    \tl_gset:Ne     \g__mitthesis_copyright_author_tl  { \seq_item:cn { g__mitthesis_author_name_seq } { \l_tmpa_int } }
	\int_incr:N     \l_tmpa_int
	\int_while_do:nNnn { \l_tmpa_int } < { \g__mitthesis_author_cnt_int }
		{
		  \tl_gput_right:Ne \g__mitthesis_copyright_author_tl 
		  	{ ,~\seq_item:cn { g__mitthesis_author_name_seq } { \l_tmpa_int } }
		  \int_incr:N \l_tmpa_int   
		}
	\int_compare:nNnT { \l_tmpa_int } = { \g__mitthesis_author_cnt_int } 
		{
        \int_compare:nNnTF { \l_tmpa_int } = { 2 }
        	{
        		\tl_gput_right:Ne \g__mitthesis_copyright_author_tl 
        		    { ~and~\seq_item:cn { g__mitthesis_author_name_seq } { \l_tmpa_int } } 
        	 }{
        		 \tl_gput_right:Ne \g__mitthesis_copyright_author_tl 
        		 { ,~and~\seq_item:cn { g__mitthesis_author_name_seq } { \l_tmpa_int } } % add comma 2025/10/08
        	 }
		}
	\tl_set:Nn \l_tmpa_tl { \tl_item:Nn \g__mitthesis_copyright_author_tl {-1} } % get last token
 	\str_case_e:nnT 
		{ \l_tmpa_tl  }
	 	{ {.}{} }
		{ \__mitthesis_copyright_remove_period:N \g__mitthesis_copyright_author_tl } % remove last token if it is a period 
	\__mitthesis_gset_author_pdfcopyright:
	\cs_gset:Npe \@author { \tl_use:N \g__mitthesis_copyright_author_tl }  % 2024/08/06
}
\cs_new_protected:Nn \__mitthesis_copyright_remove_period:N
	{
		\tl_gset:Ne #1 { \tl_range:Nnn #1 { 1 } { \tl_count:N #1 - 1 } }
	}
\cs_new_protected:Nn \__mitthesis_gset_author_pdfcopyright: {
	\tl_new:N    \g__mitthesis_pdfcopyright_author_tl
	\int_set:Nn  \l_tmpa_int {1} % counts authorno
    \tl_gset:Ne  \g__mitthesis_pdfcopyright_author_tl  
    	{ { \seq_item:cn { g__mitthesis_author_name_seq } { \l_tmpa_int } } }
	\int_until_do:nNnn { \l_tmpa_int } = { \g__mitthesis_author_cnt_int }
		{
			\int_incr:N \l_tmpa_int   
			\tl_gput_right:Ne \g__mitthesis_pdfcopyright_author_tl 
				{ ;\ { \seq_item:cn { g__mitthesis_author_name_seq } { \l_tmpa_int } } }
				% changed comma to semicolon for consistency with Dublin Core metadata format, 2024/08/30
		}
}

\tl_new:N   \g__mitthesis_author_namesize_tl
\tl_gset:Nn \g__mitthesis_author_namesize_tl { \large }
\cs_new:Nn  \__mitthesis_author_block: {
	\int_set:Nn \l_tmpa_int {1} % counts authorno
	\int_compare:nNnTF { \g__mitthesis_author_cnt_int } = {0} {
		\msg_error:nn { \ClassName } { no_author }
	}	
	{by\par
	\int_until_do:nNnn { \l_tmpa_int } = { \g__mitthesis_author_cnt_int } {
		{ 
			\leavevmode
			\tag_struct_begin:n { tag=Span }
	    	\tag_mc_begin:n { tag=Span }
			\g__mitthesis_author_namesize_tl \seq_item:cn { g__mitthesis_author_name_seq } { \l_tmpa_int }
			\tag_struct_end:
    		\tag_mc_end:
		} \par
		\tl_set:Ne \l_tmpa_tl { \seq_item:cn { g__mitthesis_author_prevdegree_seq } { \l_tmpa_int} }
		\tl_if_empty:NF \l_tmpa_tl { \normalsize \l_tmpa_tl . } % don't insert \linebreak or \par for empty items. 
																% add . as semantic break for html conversion (screen readers), 2026/01/18
		\tl_set:Ne \l_tmpa_tl { \seq_item:cn { g__mitthesis_author_secondprevdegree_seq } { \l_tmpa_int} } 
		\tl_if_empty:NF \l_tmpa_tl { \linebreak\normalsize \l_tmpa_tl . }
		\tl_set:Ne \l_tmpa_tl { \seq_item:cn { g__mitthesis_author_thirdprevdegree_seq } { \l_tmpa_int} } 
		\tl_if_empty:NF \l_tmpa_tl { \linebreak\normalsize \l_tmpa_tl . }
		\tl_set:Ne \l_tmpa_tl { \seq_item:cn { g__mitthesis_author_fourthprevdegree_seq } { \l_tmpa_int} } 
		\tl_if_empty:NF \l_tmpa_tl { \linebreak\normalsize \l_tmpa_tl . }
		\par and\par
		\int_incr:N \l_tmpa_int
	}
		{ 
			\leavevmode
			\tag_struct_begin:n { tag=Span }
	    	\tag_mc_begin:n { tag=Span }
			\g__mitthesis_author_namesize_tl \seq_item:cn { g__mitthesis_author_name_seq } { \l_tmpa_int } 
			\tag_struct_end:
    		\tag_mc_end:
		} \par
		\tl_set:Ne \l_tmpa_tl { \seq_item:cn { g__mitthesis_author_prevdegree_seq } { \l_tmpa_int} }
		\tl_if_empty:NF \l_tmpa_tl { \normalsize \l_tmpa_tl . } % no linebreak or par for empty items
		\tl_set:Ne \l_tmpa_tl { \seq_item:cn { g__mitthesis_author_secondprevdegree_seq } { \l_tmpa_int} } 
		\tl_if_empty:NF \l_tmpa_tl { \linebreak\normalsize \l_tmpa_tl . }
		\tl_set:Ne \l_tmpa_tl { \seq_item:cn { g__mitthesis_author_thirdprevdegree_seq }  { \l_tmpa_int} } 
		\tl_if_empty:NF \l_tmpa_tl { \linebreak\normalsize \l_tmpa_tl . }
		\tl_set:Ne \l_tmpa_tl { \seq_item:cn { g__mitthesis_author_fourthprevdegree_seq } { \l_tmpa_int} } 
		\tl_if_empty:NF \l_tmpa_tl { \linebreak\normalsize \l_tmpa_tl . }
    	\par 
    }
}
\NewDocumentCommand\AuthorNameSize{m}{
		\tl_gset:Nn \g__mitthesis_author_namesize_tl {#1}
}

\cs_new:Nn \__mitthesis_author_abstractblock: {
	\int_set:Nn \l_tmpa_int {1} % counts authorno
	\int_compare:nNnTF { \g__mitthesis_author_cnt_int } = {0} {
		\msg_error:nn { \ClassName } { no_author }
		}	
		{by\par
		\int_until_do:nNnn { \l_tmpa_int } = { \g__mitthesis_author_cnt_int } {
			\seq_item:cn { g__mitthesis_author_name_seq } { \l_tmpa_int }
			\par and\par
			\int_incr:N \l_tmpa_int
		}
		\seq_item:cn { g__mitthesis_author_name_seq } { \l_tmpa_int } 
    }
}
\msg_new:nnnn { \ClassName } { no_author }
		{ Missing~author!~You~must~issue \iow_newline: the~\Author{name}{department}~command. }{
		You~MUST~issue~the~\Author{name}{department}~command~after~\string\begin{document}~and~before~\string\maketitle. }


%%%%%%%%%%  End Author Module  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%%%%%%%%%  Supervisor Module  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\seq_new:N \g__mitthesis_supervisor_name_seq
\seq_new:N \g__mitthesis_supervisor_title_seq
\seq_new:N \g__mitthesis_supervisor_dept_seq
\int_gzero_new:N \g__mitthesis_supervisor_cnt_int

\NewDocumentCommand\Supervisor{mmo}{
	\tl_if_blank:nT {#1} { \msg_error:nn { \ClassName } { blank_supervisor }       }
	\tl_if_blank:nT {#2} { \msg_error:nn { \ClassName } { blank_supervisor_title } }
	\IfNoValueTF {#3} 
		{ 	\msg_note:nn { \ClassName } { no_supervisor_dept  } 
			\__mitthesis_gset_supervisor_data:nnn {#1} {#2}
				{ Department~argument~was~not~used~in~\Supervisor~command. }
		} 
		{ 	\tl_if_blank:nTF {#3}
				{ 	\msg_note:nn { \ClassName } { blank_supervisor_dept  } 
					\__mitthesis_gset_supervisor_data:nnn {#1} {#2} { Blank~department~in~\Supervisor~command. }
				}{
					\__mitthesis_gset_supervisor_data:nnn {#1} {#2} {#3}
				}
		}
}
\msg_new:nnnn { \ClassName } { blank_supervisor }
		{ Missing~supervisor~name,~check\iow_newline: for~blank~in~\Supervisor{name}{title}[department]~command. 
		}{
		  You~MUST~provide~the~supervisor's~name~using~the~\Supervisor{name}{title}[department]~command. 
		}
\msg_new:nnnn { \ClassName } { blank_supervisor_title }
		{ Missing~supervisor~title,~check\iow_newline: for~blank~in~\Supervisor{name}{title}[department]~command. 
		}{
		  You~MUST~provide~the~supervisor's~title~using~the~\Supervisor{name}{title}[department]~command. 
		}
\msg_new:nnnn { \ClassName } { blank_supervisor_dept }
		{ 
		  No~supervisor~department_provided,~check\iow_newline: for~blank~in~\Supervisor{name}{title}[department]~command.
		}{
		  The~supervisor's~department~was~blank~in~the~\Supervisor{name}{title}[department]~command.
		}
\msg_new:nnnn { \ClassName } { no_supervisor_dept }
	 	{ No~supervisor~department_provided~with\iow_newline: the~optional~third~argument~of\space
		  the~\Supervisor{name}{title}[department]~command.
		}{
		  The~supervisor's~department~is~used~only~in~the~optional~Thesis~Committee~page.
		}

\cs_new_protected:Nn \__mitthesis_gset_supervisor_data:nnn
 {
	\int_gincr:N \g__mitthesis_supervisor_cnt_int
	\seq_gput_right:ce  { g__mitthesis_supervisor_name_seq }  { \tl_trim_spaces:n {#1} } 
	\seq_gput_right:ce  { g__mitthesis_supervisor_title_seq } { \tl_trim_spaces:n {#2} }
	\seq_gput_right:ce  { g__mitthesis_supervisor_dept_seq }  { \tl_trim_spaces:n {#3} }
 }

\tl_new:N   \g__mitthesis_titlepg_sup_designation_tl
\tl_new:N   \g__mitthesis_abst_sup_designation_tl
\tl_gset:Nn \g__mitthesis_titlepg_sup_designation_tl { Thesis~Supervisor } 
\tl_gset:Nn \g__mitthesis_abst_sup_designation_tl  { Thesis~supervisor } % style per MIT Libraries

% If for some reason you need to change "Thesis Supervisor" to a different string (say, "Doctoral Advisor").
% Note: this construction removes leading and trailing spaces and changes text case of the string.
\NewDocumentCommand\SupervisorDesignation{ m } { 
		\tl_gset:Nn \g__mitthesis_titlepg_sup_designation_tl 
				{ \cs_if_exist:NTF \text_titlecase_all:n % not def'd until 2023/07/08
					{ \text_titlecase_all:n { \text_lowercase:n { \tl_trim_spaces:n {#1} } } }
					{ \tl_trim_spaces:n {#1} }
				}
		\tl_gset:Nn \g__mitthesis_abst_sup_designation_tl  
				{ \text_titlecase_first:n { \text_lowercase:n { \tl_trim_spaces:n {#1} } } }
		}
		
\cs_new:Nn \__mitthesis_supervisor_abstractblock: { % revised 2025/10/09, eliminate bug and use multiple tables; 2026/01/18, eliminate tables
	\int_set:Nn  \l_tmpa_int {1} % counts supervisors
	\setlength{\parindent}{0pt}
	\par\bigskip
	\int_compare:nNnTF { \g__mitthesis_supervisor_cnt_int } = {0} {
		\msg_error:nn { \ClassName } { no_supervisor }
		}	
		{
		\int_until_do:nNnn { \l_tmpa_int } = { \g__mitthesis_supervisor_cnt_int } {
			\tl_set:Ne \l_tmpa_tl  { \seq_item:cn { g__mitthesis_supervisor_title_seq } { \l_tmpa_int } }
			\regex_replace_all:nnN { \& \s* } { \c{phantom}{Title:\c{space}} } \l_tmpa_tl 
			\tag_struct_begin:n { tag=Abstract_supervisor, title=Abstract~supervisor}
    			\g__mitthesis_abst_sup_designation_tl  :\space 
    			\seq_item:cn { g__mitthesis_supervisor_name_seq } { \l_tmpa_int } \par
    			Title:\space \l_tmpa_tl
    			\int_gincr:N \l_tmpa_int
			\tag_struct_end:
			\skip_vertical:n {12pt}
			}
			\tl_set:Ne \l_tmpa_tl {\seq_item:cn { g__mitthesis_supervisor_title_seq } { \l_tmpa_int } }
			\regex_replace_all:nnN { \& \s* } { \c{phantom}{Title:\c{space}} } \l_tmpa_tl 
			\tag_struct_begin:n { tag=Abstract_supervisor, title=Abstract~supervisor}
			\g__mitthesis_abst_sup_designation_tl  :\space  
			\seq_item:cn { g__mitthesis_supervisor_name_seq } { \l_tmpa_int } \par
			Title:\space   \l_tmpa_tl 
			\tag_struct_end:
			\ignorespaces
    	}
}
\msg_new:nnnn { \ClassName } { no_supervisor }
		{ Missing~supervisor!~You~must~issue~the~\Supervisor{name}{title}~command. }{
		You~MUST~issue~the~\Supervisor{name}{title}~command~after~\string\begin{document}~and~before~\string\maketitle. }


%%%%%%%%%%  End Supervisor Module  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%%%%%%%%%  Acceptor Module  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\seq_new:N \g__mitthesis_acceptor_name_seq
\seq_new:N \g__mitthesis_acceptor_dept_seq
\seq_new:N \g__mitthesis_acceptor_title_seq
\int_gzero_new:N \g__mitthesis_acceptor_cnt_int

\bool_new:N \g__mitthesis_acceptor_title_bool
\bool_gset_false:N \g__mitthesis_acceptor_title_bool

\NewDocumentCommand\Acceptor{mmm}{
	\tl_if_blank:nTF {#1} {
		\msg_error:nn { \ClassName } { blank_acceptor }
		}{
		\__mitthesis_gset_acceptor_data:nnn {#1} {#2} {#3}
	}
	\tl_if_blank:nT  {#2} { \msg_error:nn { \ClassName } { blank_acceptor_dep } }
	\tl_if_blank:nTF {#3} {
		\bool_gset_true:N \g__mitthesis_acceptor_title_bool
		\msg_warning:nn { \ClassName } { blank_acceptor_title }}{}
}
\msg_new:nnnn { \ClassName } { blank_acceptor }
		{ Missing~acceptor~name,~check~for~blank~in~\Acceptor{name}{department}{title}~command. }{
			You~MUST~provide~the~acceptor's~name~using~the~\Acceptor{name}{department}{title}~command. }
\msg_new:nnnn { \ClassName } { blank_acceptor_dep }
		{ Missing~acceptor~department,~check~for~blank~in~\Acceptor{name}{department}{title}~command. }{
			You~MUST~provide~the~acceptor's~department~using~the~\Acceptor{name}{department}{title}~command. }
\msg_new:nnn { \ClassName } { blank_acceptor_title }
		{ Missing~acceptor~title~(blank~in~\Acceptor{name}{department}{title}~command).\space 
		  Perhaps~you~are~trying~to~save~vertical~space?\space  
		  You~can~put~the~acceptor~title~into~department~field~instead.\space 
		  For~consistency,~I~will~omit~titles~of~ALL~acceptors.
		}

\cs_new_protected:Nn \__mitthesis_gset_acceptor_data:nnn
 {
	\int_gincr:N \g__mitthesis_acceptor_cnt_int
	\seq_gput_right:ce  { g__mitthesis_acceptor_name_seq }  { \tl_trim_spaces:n {#1} } 
	\seq_gput_right:ce  { g__mitthesis_acceptor_dept_seq } 	{ \tl_trim_spaces:n {#2} }
	\seq_gput_right:ce  { g__mitthesis_acceptor_title_seq } { \tl_trim_spaces:n {#3} }
 }

%%%%%%%%%%  End Acceptor Module  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%%%%%%%%%  Degree Module  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% extensive edits 2024/06/25

\seq_new:N \g__mitthesis_degree_name_seq
\seq_new:N \g__mitthesis_degree_dept_seq
\int_gzero_new:N \g__mitthesis_degree_cnt_int
\int_gzero_new:N \g__mitthesis_dept_cnt_int

% #1 = degree ; #2 = department
\NewDocumentCommand\Degree{mm}
 {
    \int_compare:nNnTF { \g__mitthesis_dept_cnt_int } = {0} {
    	\tl_if_blank:nTF {#1} {
    		  \msg_error:nn { \ClassName } { no_degree_name }
    		}{
			  \__mitthesis_gset_degree_name:n { #1 }
			  \int_gincr:N \g__mitthesis_degree_cnt_int
    		}
    	\tl_if_blank:nTF {#2} {
    		  \msg_error:nn { \ClassName } { no_degree_dep }
    		}{
			  \__mitthesis_gset_degree_dept:n { #2 }
			  \int_gincr:N \g__mitthesis_dept_cnt_int
			}
    }{
    	\tl_if_blank:nTF {#1} {
    		  \msg_warning:nn { \ClassName } { blank_degree }
    		}{
			  \__mitthesis_gset_degree_name:n { #1 }
			  \int_gincr:N \g__mitthesis_degree_cnt_int
			}
    	\tl_if_blank:nTF {#2} {
    		  \msg_warning:nn { \ClassName } { blank_degree_dep }
    		}{
			  \int_gincr:N \g__mitthesis_dept_cnt_int 
			  \__mitthesis_gset_degree_dept:n { #2 }
    		}
    }
 }

\cs_new_protected:Nn \__mitthesis_gset_degree_name:n
 {
	\seq_gput_right:ce  { g__mitthesis_degree_name_seq }  { \tl_trim_spaces:n {#1} } 
 }
\cs_new_protected:Nn \__mitthesis_gset_degree_dept:n
 {
	\seq_gput_right:ce  { g__mitthesis_degree_dept_seq }  { \tl_trim_spaces:n {#1} }
 }
\msg_new:nnnn { \ClassName } { no_degree_name } 
			{ Missing~degree~name,~check~for\iow_newline: blank~in~\Degree~command. } 
			{ You~MUST~provide~at~least~one~degree~name~using~the~\Degree{name}{department}~command. }
\msg_new:nnnn { \ClassName } { no_degree_dep } 
			{ Missing~degree~department~for\iow_newline: Degree~command. }
			{ You~MUST~provide~at~least~one~department~name~using~the~\Degree{name}{department}~command. }
\msg_new:nnn { \ClassName } { blank_degree } 
			{ Missing~degree~name~in~second~\Degree~command.\iow_newline: 
			  Will~treat~this~as~two~departments~issuing~one~degree. }
\msg_new:nnn { \ClassName } { blank_degree_dep } 
			{ Missing~degree~department~in~second~\Degree~command.~Will~treat~as~one~department~issuing~two~degrees. }

\cs_if_exist:NF \cs_new:Ne { \cs_generate_variant:Nn \cs_new:Nn {Ne} } % not def'd in 2023-06-30 latex3
\cs_if_exist:NF \cs_set:Ne { \cs_generate_variant:Nn \cs_set:Nn {Ne} } % not def'd in 2023-06-30 latex3

\cs_new:Nn \__mitthesis_degree_block: { % edited 2025/10/08
	\int_compare:nNnT { \g__mitthesis_degree_cnt_int } = {0}
		{ 
		  \msg_fatal:nn { \ClassName } { no_degree }
		}	
	\int_set:Nn  \l_tmpa_int {1} % count degree name
	\int_set:Nn  \l_tmpb_int {1} % count degree department
	\tl_set:Ne   \l_tmpa_tl { \seq_item:cn { g__mitthesis_degree_dept_seq } { \l_tmpb_int } }
	{Submitted\ to\ the\ \l_tmpa_tl} 
	\int_until_do:nNnn { \l_tmpb_int } = { \g__mitthesis_dept_cnt_int } {
		\int_incr:N  \l_tmpb_int
		\tl_set:Ne   \l_tmpb_tl { \seq_item:cn { g__mitthesis_degree_dept_seq } { \l_tmpb_int } }
		\mbox {\ and}\linebreak
		\mbox {the\ \l_tmpb_tl }
	}
    \linebreak \mbox {in\ partial\ fulfillment\ of\ the\ requirements\ for\ the\ 
		\int_compare:nNnTF { \g__mitthesis_degree_cnt_int } > {1} {degrees} {degree}
	\ of}
	\par
	\int_until_do:nNnn { \l_tmpa_int } = { \g__mitthesis_degree_cnt_int } {
    	\textls[60]{ \text_uppercase:n { \seq_item:cn { g__mitthesis_degree_name_seq } { \l_tmpa_int } } }\par and\par
		\int_incr:N     \l_tmpa_int
		}
    \textls[60]{\text_uppercase:n { \seq_item:cn { g__mitthesis_degree_name_seq } { \l_tmpa_int } } }\par
}
\msg_new:nnnn { \ClassName } { no_degree }
		{ Missing~degree!~You~must\iow_newline: issue~the~\Degree{name}{department}~command. 
		}{
		  You~MUST~issue~the~\Degree{name}{department}~command~after~\string\begin{document}\space
		  and~before~\string\maketitle.~ You~do~want~the~degree,~don't~you?
		}


\cs_new:Nn \__mitthesis_degree_abstractblock: { % edited 2025/10/08
	\int_set:Nn  \l_tmpa_int {1}
	\int_set:Nn  \l_tmpb_int {1}
	\tl_set:Ne \l_tmpa_tl { \seq_item:cn { g__mitthesis_degree_dept_seq } { \l_tmpb_int } }
	{Submitted\ to\ the\ \l_tmpa_tl} 
	\int_until_do:nNnn { \l_tmpb_int } = { \g__mitthesis_dept_cnt_int } {
		\int_incr:N      \l_tmpb_int
		\tl_set:Ne \l_tmpb_tl { \seq_item:cn { g__mitthesis_degree_dept_seq } { \l_tmpb_int } }
		\mbox {\ and}\linebreak
		\mbox {the\ \l_tmpb_tl }
	}
    \linebreak \mbox{on\ \g_mitthesis_dd_thesisdate_tl\ in\ partial\ fulfillment\ of\ the\ requirements\ for\ the\ 
		\int_compare:nNnTF { \g__mitthesis_degree_cnt_int } > {1} { degrees } { degree }
	\ of}
	\skip_vertical:n { 6pt plus 2pt minus 2pt }
	\int_until_do:nNnn { \l_tmpa_int } = { \g__mitthesis_degree_cnt_int } {
    	\textls[60]{ \text_uppercase:n {\seq_item:cn { g__mitthesis_degree_name_seq } { \l_tmpa_int } } } \par and \par
		\int_incr:N     \l_tmpa_int
		}
    \textls[60]{ \text_uppercase:n {\seq_item:cn { g__mitthesis_degree_name_seq } { \l_tmpa_int } } }
    \skip_vertical:n { 6pt plus 2pt minus 2pt }
}

%%%%%%%%%%  End Degree Module  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%%%%%%%%%  Signature Module  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\NewDocumentCommand\SignatureBlockSize{m}{
	\__mitthesis_gset_signature_size:n {#1}
}

\tl_new:N \g__mitthesis_signature_size_tl
\cs_new_protected:Nn \__mitthesis_gset_signature_size:n 
  {
	\tl_gset:Nf \g__mitthesis_signature_size_tl { \tl_trim_spaces:n {#1} }
	\token_case_meaning:NnF \g__mitthesis_signature_size_tl
	{ 
		\normalsize {} \small {} \footnotesize{} \scriptsize{} \tiny{}
	} {
		\msg_error:nn { \ClassName } { weird_sigsize }
	}
  }
\msg_new:nnnn { \ClassName } { weird_sigsize }
		{ \SignatureBlockSize~expects~a~font-sizing~command,~such~as~\small,~\footnotesize,~etc.
		}{
		  You~used~a~weird~input~value~here.~If~you~did~so~deliberately,~try~continuing.
		}	

\cs_new:Nn \__mitthesis_signature_block: {
	\int_compare:nNnT { \g__mitthesis_supervisor_cnt_int } = {0} {
		\msg_error:nn { \ClassName } { no_supervisor } % this message is def'd in Abstract supervisor block
	}	
	\int_compare:nNnT { \g__mitthesis_acceptor_cnt_int } = {0} {
		\msg_error:nn { \ClassName } { no_acceptor }
	}	
	\tl_if_exist:NF \g_mitthesis_dd_thesisdate_tl { 
		\msg_error:nn { \ClassName } { no_thesis_date }
	}
	\int_gzero_new:N \g__signature_autno_int
	\int_gzero_new:N \g__signature_supno_int
	\int_gzero_new:N \g__signature_accno_int
    \g__mitthesis_signature_size_tl
    \dim_set:Nn \topsep {0pt}
    \dim_set:Nn \partopsep {0pt}
    %\begin{tabbing}
    %\hspace{1.35in} \= \hspace{1in} \kill 
    %%% replaced eight \> by &; eliminate tabbing, 2025/1/15
    \noindent
    { \tagpdfsetup{table/tagging=presentation}
        \begin{tabular}{@{}ll@{}}
    	\int_do_while:nNnn { \g__signature_autno_int } < { \g__mitthesis_author_cnt_int } {
    		\int_gincr:N  \g__signature_autno_int
			\tag_struct_begin:n { tag=Span }
    		\tag_mc_begin:n { tag=Span }
    		Authored\ by: 
		    \tag_mc_end:
		    \tag_struct_end:
			& \seq_item:cn { g__mitthesis_author_name_seq } { \g__signature_autno_int } \\  
    		& \seq_item:cn { g__mitthesis_author_department_seq } { \g__signature_autno_int } \\
    		& \g_mitthesis_dd_thesisdate_tl \\[1em]
    	}
    	\int_do_while:nNnn { \g__signature_supno_int } < { \g__mitthesis_supervisor_cnt_int } {
    		\int_gincr:N  \g__signature_supno_int
			\tag_struct_begin:n { tag=Span }
    		\tag_mc_begin:n { tag=Span }
    		Certified\ by: 
		    \tag_mc_end:
		    \tag_struct_end:
		    & \seq_item:cn { g__mitthesis_supervisor_name_seq } { \g__signature_supno_int } \\
    		& \seq_item:cn { g__mitthesis_supervisor_title_seq } { \g__signature_supno_int },\ 
    			\g__mitthesis_titlepg_sup_designation_tl \\[1em]
    	}
    	\int_compare:nNnF { \g__mitthesis_acceptor_cnt_int } = {0} {
        	\int_do_while:nNnn { \g__signature_accno_int } < { \g__mitthesis_acceptor_cnt_int } {
        		\int_gincr:N  \g__signature_accno_int
				\tag_struct_begin:n { tag=Span }
	    		\tag_mc_begin:n { tag=Span }
        		Accepted\ by: 
			    \tag_mc_end:
			    \tag_struct_end:
				& \seq_item:cn { g__mitthesis_acceptor_name_seq } { \g__signature_accno_int } \\
        		& \seq_item:cn { g__mitthesis_acceptor_dept_seq } { \g__signature_accno_int }
        			\bool_if:NF \g__mitthesis_acceptor_title_bool
        			{
        				\\
        				& \seq_item:cn { g__mitthesis_acceptor_title_seq } { \g__signature_accno_int }
        			}
    			\int_compare:nNnTF { \g__signature_accno_int } = { \g__mitthesis_acceptor_cnt_int } 
    			{ \\ }{ \\[1em] }
         	}
    	}
    	%\end{tabbing}
    	\end{tabular}
	}
}
\msg_new:nnnn { \ClassName } { no_acceptor }
		{ Missing~acceptor!You~must~issue~the~\Acceptor{name}{department}{title}~command.
		}{
		  You~MUST~issue~the~\Acceptor{name}{department}{title}~command~after~\string\begin{document}\space
		  and~before~\string\maketitle.
		}
\msg_new:nnnn { \ClassName } { no_thesis_date }
		{ Missing~thesis~date!~You~must~issue~the~\ThesisDate{Date~thesis~is~submitted}~command.
		}{
		  You~MUST~issue~the~\ThesisDate{Date~thesis~is~submitted}~command~after~\string\begin{document}\space
		  and~before~\string\maketitle.
		}

% If for some reason you don't want a warning when you omit \Acceptor
\NewDocumentCommand\SuppressAcceptorError{}
  {
  	\msg_redirect_name:nnn { \ClassName } { no_acceptor } { none }
  }

%%%%%%%%%%  End Signature Module  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%%%%%%%%%  Copyright Module  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Directly add the xmp property that shows work is copyrighted. See l3pdfmeta.pdf. 
% This is not automatic with \DocumentMetadata. "True" must be capitalized.
%
\cs_if_exist:NT \pdfmeta_xmp_add:n { \pdfmeta_xmp_add:n { <xmpRights:Marked>True</xmpRights:Marked> } }

\tl_new:N \g__mitthesis_copyright_ccname_tl
\tl_new:N \g__mitthesis_copyright_cclicense_tl
\tl_new:N \g__mitthesis_copyright_license_tl
\tl_new:N \g__mitthesis_copyright_pdfrights_tl
\tl_new:N \g__mitthesis_copyright_crwords_tl
\tl_new:N \g__mitthesis_copyright_mitpermlast_tl

\tl_new:N \g__mitthesis_copyright_mitpermission_tl
\tl_gset:Nn \g__mitthesis_copyright_mitpermlast_tl 
	{
	  to\ MIT\ a\ nonexclusive,\ worldwide,\ irrevocable,\ royalty-free\ license\ to\ exercise\ 
	  any\ and\ all\ rights\ under\ copyright,\ including\ to\ reproduce,\ preserve,\ distribute\ 
	  and\ publicly\ display\ copies\ of\ the\ thesis,\ or\ release\ the\  thesis\ under\ an\ 
	  open-access\ license.
	}

\bool_new:N \g__mitthesis_cclicense_bool
\bool_gset_false:N \g__mitthesis_cclicense_bool

\NewDocumentCommand\CClicense{mm}{
	\__mitthesis_gset_copyright_licensedata:nn {#1} {#2}
}
\cs_new_protected:Nn \__mitthesis_gset_copyright_licensedata:nn 
  {
	\tl_gset:Nf \g__mitthesis_copyright_cclicense_tl { \hrefurl{ \tl_trim_spaces:n {#2} }{ \tl_trim_spaces:n {#1} } } % #1 - text, #2 - url  
	\tl_gset:Ne \g__mitthesis_copyright_ccname_tl        { \tl_trim_spaces:n {#1} } 
	\bool_gset_true:N \g__mitthesis_cclicense_bool
	\cs_if_exist:NT \pdfmeta_xmp_add:n {
			\pdfmeta_xmp_add:n { <xmpRights:WebStatement>#2</xmpRights:WebStatement> }
	}
	\cs_if_exist:NTF \msg_note:nnn % command was added to expl3 2021/05/18
	  {
		\msg_note:nnn { \ClassName } { cclicense} {#1}
	  }
	  {
		\msg_log:nnn  { \ClassName } { cclicense} {#1}
	  } 
  }
\msg_new:nnn { \ClassName } { cclicense } { Using~Creative~Commons~License~#1. }


%%%%%%%%%%  End Copyright Module  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%%%%%%%%%  Reader module  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\seq_new:N \g__mitthesis_reader_name_seq
\seq_new:N \g__mitthesis_reader_title_seq
\seq_new:N \g__mitthesis_reader_department_seq
\int_gzero_new:N \g__mitthesis_readercnt_int

\NewDocumentCommand\Reader{mmm}{
	\tl_if_blank:nTF {#1} {
		\msg_error:nn { \ClassName } { blank_reader }
		}{
		\__mitthesis_gset_reader_data:nnn {#1} {#2} {#3}
	}
	\tl_if_blank:nT {#2} {  \msg_error:nn { \ClassName } { blank_reader_title } }
	\tl_if_blank:nT {#3} {  \msg_error:nn { \ClassName } { blank_reader_dep   } }
}
\msg_new:nnnn { \ClassName } { blank_reader }
		{ Missing~reader~name,~check~for~blank~in~\Reader{name}{title}{department}~command. }{
			You~MUST~provide~the~reader's~name~using~the~\Reader{name}{title}{department}~command. }
\msg_new:nnnn { \ClassName } { blank_reader_title }
		{ Missing~reader~title,~check~for~blank~in~\Reader{name}{department}{title}~command. }{
			You~MUST~provide~the~reader's~title~using~the~\Reader{name}{title}{department}~command. }
\msg_new:nnnn { \ClassName } { blank_reader_dep }
		{ Missing~reader~department,~check~for~blank~in~\Reader{name}{title}{department}~command. }{
			You~MUST~provide~the~reader's~department~using~the~\Reader{name}{title}{department}~command. }

\cs_new_protected:Nn \__mitthesis_gset_reader_data:nnn
 {
	\int_gincr:N \g__mitthesis_readercnt_int
	\seq_gput_right:ce  { g__mitthesis_reader_name_seq  }      { \tl_trim_spaces:n {#1} } 
	\seq_gput_right:ce  { g__mitthesis_reader_title_seq }      { \tl_trim_spaces:n {#2} }
	\seq_gput_right:ce  { g__mitthesis_reader_department_seq } { \tl_trim_spaces:n {#3} }
 }

%%%%%%%%%%  End reader module  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%%%%%%%%%  Title page Module  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\RenewDocumentCommand\title{m}
	{
		\__mitthesis_gset_title:n { #1 }
		\cs_gset:Npe \@title { \tl_use:N \g_mitthesis_title_tl } % 2024/08/06
		\hypersetup{
			pdftitle={ { \g_mitthesis_title_tl } }, % extra braces protect commas that may be in title tl.
		}
	}

\tl_new:N \g_mitthesis_title_tl

\cs_new_protected:Nn \__mitthesis_gset_title:n
	{
		\tl_gset:Nn \g_mitthesis_title_tl { \tl_trim_spaces:n {#1} }
	}

\tl_new:N \g_titlepage_institution_name_tl
\tl_gset:Nn \g_titlepage_institution_name_tl { Massachusetts\ Institute\ of\ Technology } 
\cs_new_protected:Npn \Institution #1 { \tl_gset:Nn \g_titlepage_institution_name_tl { \tl_trim_spaces:n #1 } }


%%%%%%% Adjust vertical skips between the major blocks of the title page

\bool_new:N \g__mitthesis_title_squashglue_bool
\cs_new_protected:Nn \__mitthesis_titlepage_bottomskip: {
	\if_bool:N \g__mitthesis_title_squashglue_bool 
		{ 	\skip_vertical:n { 0pt plus 1filll  } }
	\else:
		{   \skip_vertical:n { 0pt plus 12fill } }
	\fi:
}
\NewDocumentCommand\Squash{}{ \bool_gset_true:N \g__mitthesis_title_squashglue_bool } % Squashes all glue from bottom upward

\bool_new:N \g__mitthesis_title_tighten_bool
\cs_new_protected:Nn \__mitthesis_titlepage_blockskip:nn {
	\if_bool:N \g__mitthesis_title_tighten_bool 
		{ 	\skip_vertical:n { 6pt plus #2fill    } }
	\else:
		{   \skip_vertical:n { #1pt plus #2fill } }
	\fi:
}
\NewDocumentCommand\Tighten{}{ \bool_gset_true:N \g__mitthesis_title_tighten_bool } % Reduces 12pt and 18pt skips to 6pt

%%%%%%%%%%%%

\RenewDocumentCommand\maketitle{s}{
	\cs_if_exist:NF \DegreeMonth { \msg_error:nn { \ClassName } { no_degree_date } } % msg def'd in degree-date section
%	
	\bool_if:NTF \g__mitthesis_cclicense_bool { 
		\tl_gset:Nn \g__mitthesis_copyright_license_tl 
			{ This\ work\ is\ licensed\ under\ a\ \mbox{ \g__mitthesis_copyright_cclicense_tl }\ license.\par
			  \g__mitthesis_copyright_mitpermission_tl 
			}
		\tl_gset:Nn \g__mitthesis_copyright_pdfrights_tl 	 
			{ This\ work\ is\ licensed\ under\ a\ \g__mitthesis_copyright_ccname_tl\ license.\space 
			  \g__mitthesis_copyright_mitpermission_tl
			}
	}{
		\tl_gset:Nn \g__mitthesis_copyright_license_tl 
			{ All\ rights\ reserved. \par\g__mitthesis_copyright_mitpermission_tl }
		\tl_gset:Nn \g__mitthesis_copyright_pdfrights_tl 	 
			{ All\ rights\ reserved.\space \g__mitthesis_copyright_mitpermission_tl }
   }
   \int_compare:nNnTF { \g__mitthesis_author_cnt_int } > {1} 
   		{   
			\tl_gset:Nn \g__mitthesis_copyright_crwords_tl { The\ authors\ hereby\ grant } 
		}
		{
			\tl_gset:Nn \g__mitthesis_copyright_crwords_tl { The\ author\ hereby\ grants } 
		}
    \IfBooleanTF {#1}{
	    \tl_gset:Nn \g__mitthesis_copyright_mitpermission_tl { \scan_stop: }
    }{
	    \tl_gset:Nn \g__mitthesis_copyright_mitpermission_tl 
	    	{ \g__mitthesis_copyright_crwords_tl\ \g__mitthesis_copyright_mitpermlast_tl }
    }
%
	\clearpage
	\thispagestyle{empty}
	\tag_struct_begin:n { tag=Sect, title=Titlepage }
	\vbox_to_ht:nn { \vsize } % to prevent signature block from breaking across page
		{
			{ \centering
                \setlength{\parskip}{7.5pt plus 1pt minus 1pt} % edited all vertical space on this page 2023/10/25
                \setlength{\parindent}{0pt}\pdfbookmark[0]{Title\ Page}{titlepage}
                {
					\tag_struct_begin:n { tag=Title, title=Title }
					\leavevmode
					\tag_struct_begin:n { tag=Strong }
                    \tag_mc_begin:n { tag=Strong }
                    \Large\textbf{ \g_mitthesis_title_tl }
                    \par
                    \tag_mc_end:
                    \tag_struct_end:
                    \tag_struct_end:
                }
    			\__mitthesis_titlepage_blockskip:nn {12}{1.5}
				\tag_struct_begin:n { tag=Author, title=Author }
                \__mitthesis_author_block:
    			\tag_struct_end:
				\__mitthesis_titlepage_blockskip:nn {12}{1.5}
                \tag_struct_begin:n { tag=Degree, title=Degree } 
                \__mitthesis_degree_block:
                at~the\par
                \textls[60]{ \text_uppercase:n { \g_titlepage_institution_name_tl } } \par
                \DegreeMonth\ \DegreeYear\par
                \tag_struct_end:
    			\__mitthesis_titlepage_blockskip:nn {12}{2}
				\tag_struct_begin:n { tag=Copyright, title=Copyright }
                \copyright\space\DegreeYear\space\CopyrightAuthor\@.\c_space_token \g__mitthesis_copyright_license_tl % \@. in case name ends with III, IV, V,...
				\par % required to center \g_copyrightlicense_tl text.
				\tag_struct_end:
			}
			\__mitthesis_titlepage_blockskip:nn {18}{2}
    		\tag_struct_begin:n { tag=Title_sig_block, title=Signatures }
            \__mitthesis_signature_block:
			\tag_struct_end:
			\__mitthesis_titlepage_bottomskip:
		}
		\tag_struct_end: % end section
		\hypersetup{
    		pdfcopyright={ Copyright\ \DegreeYear\ by\ \CopyrightAuthor.\space \g__mitthesis_copyright_pdfrights_tl },
    		pdfauthor={ \g__mitthesis_pdfcopyright_author_tl },
    		pdfcaptionwriter = { \g__mitthesis_pdfcopyright_author_tl },
    	}
	\cleardoublepage
	\int_compare:nNnF { \g__mitthesis_readercnt_int } = {0} { \__mitthesis_committee_block: }
}

%%%%%%%%%%  End title page module  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%%%%%%%%%  Thesis committee members page module  %%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Presentation tables are used on this page for rendering the tagged file into html with consistent alignments.
%

% select something other than "Thesis Reader"
\tl_new:N   \g__mitthesis_reader_name_tl
\tl_gset:Nn \g__mitthesis_reader_name_tl { Thesis~Reader } 
\NewDocumentCommand\ThesisReaderName{ m } { 
		\tl_gset:Nn \g__mitthesis_reader_name_tl 
				{ \cs_if_exist:NTF \text_titlecase_all:n % not def'd until 2023/07/08
					{ \text_titlecase_all:n { \text_lowercase:n { \tl_trim_spaces:n {#1} } } }
					{ \tl_trim_spaces:n {#1} }
				}
		}
% use plural "Supervisors" if more than one supervisor
\cs_new_protected:Nn \__mitthesis_gset_supervisor_plurals: {
    \int_compare:nNnT { \g__mitthesis_supervisor_cnt_int } > {1} 
       	{   
    		\tl_gput_right:Nn \g__mitthesis_titlepg_sup_designation_tl { s } 
    	}
    \int_compare:nNnT { \g__mitthesis_readercnt_int } > {1} 
       	{   
    		\tl_gput_right:Nn \g__mitthesis_reader_name_tl { s } 
    	}
}

% selection something other than "THESIS COMMITTEE"
\tl_new:N   \g__mitthesis_committee_name_tl
\tl_gset:Nn \g__mitthesis_committee_name_tl { THESIS~COMMITTEE } 
\NewDocumentCommand\ThesisCommitteeName{ m } { 
		\tl_gset:Nn \g__mitthesis_committee_name_tl 
				{ \cs_if_exist:NTF \text_uppercase:n % not def'd until 2023/07/08
					{ \text_uppercase:n { \tl_trim_spaces:n {#1} } }
					{ \MakeUpperCase{ \tl_trim_spaces:n {#1} } }
				}
		}

% reduce white space around title ("THESIS COMMITTEE"), e.g., if too many committee members
\bool_new:N \g__mitthesis_short_cmtitle_bool
\cs_new_protected:Nn \__mitthesis_cmtitle_blockskip: {
	\if_bool:N \g__mitthesis_short_cmtitle_bool 
		{ 	\skip_vertical:n { 32pt } }
	\else:
		{   \skip_vertical:n { 56pt } }
	\fi:
}
\NewDocumentCommand\CMPShortenTop{}{ \bool_gset_true:N \g__mitthesis_short_cmtitle_bool } % Reduces 56pt skips to 32pt

% styling of text in headings
\cs_new:Nn  \__mitthesis_CMstyle:n    { { \bfseries  \Large\lsstyle #1 } } 
\cs_new:Nn  \__mitthesis_CMsubstyle:n { { \normalfont\scshape\large\lsstyle #1 } }


% split title list at "\\ &", convert "\&" to "and", \emph each item in the sequence, output emphasized items each separated by "\\ &".  
\regex_new:N   \g__mitthesis_split_lines_regex
\regex_gset:Nn \g__mitthesis_split_lines_regex   { \\\\ \s* \& }
\regex_new:N   \g__mitthesis_fix_ampersand_regex
\regex_gset:Nn \g__mitthesis_fix_ampersand_regex { \\& }
\seq_new:N     \g__mitthesis_titles_seq

\cs_if_exist:NF \str_set:Ne      { \cs_generate_variant:Nn \str_set:Nn {Ne} } 		% not def'd 2023 TeX Live
\cs_if_exist:NF \regex_split:NVN { \cs_generate_variant:Nn \regex_split:NnN {NVN} } % not def'd 2023 TeX Live
\cs_if_exist:NF \tl_to_str:e     { \cs_generate_variant:Nn \tl_to_str:n {e} } 		% not def'd 2023 TeX Live

\cs_new_protected:Nn  \__mitthesis_assemble_CMtitle_list:n 
  {
    \str_set:Ne \l_tmpa_str { \tl_to_str:e {#1} }
	\regex_split:NVN \g__mitthesis_split_lines_regex \l_tmpa_str \g__mitthesis_titles_seq
    \seq_map_inline:Nn \g__mitthesis_titles_seq
      {
		\regex_replace_all:NnN \g__mitthesis_fix_ampersand_regex { and } \g__mitthesis_titles_seq 
		% replaces "\&" by "and"; the string "\&" would otherwise be typeset verbatim.
	  }
	\seq_set_map:NNn \l_tmpa_seq \g__mitthesis_titles_seq { \emph { ##1 } }
	\seq_use:Nnnn    \l_tmpa_seq { \\ & } { \\ & } { \\ & }
  }


% layout thesis committee members page
\cs_if_exist:NF \str_gset:Ne { \cs_generate_variant:Nn \str_gset:Nn {Ne} }   		 % not def'd 2023 TeX Live
\cs_if_exist:NF \text_titlecase_all:n {\cs_new:Npn \text_titlecase_all:n #1 { #1 } } % not def'd 2023 TeX Live
\cs_if_exist:NF \text_lowercase_all:n {\cs_new:Npn \text_lowercase_all:n #1 { #1 } } % not def'd 2023 TeX Live

\cs_new_protected:Nn \__mitthesis_committee_block: {
	\int_gzero_new:N \g__mitthesis_committee_supno_int
	\int_gzero_new:N \g__mitthesis_committee_readerno_int
	
	\__mitthesis_gset_supervisor_plurals:
    \str_new:N   \g__mitthesis_committee_name_str
    \str_gset:Ne \g__mitthesis_committee_name_str 
    	{
		  \text_titlecase_all:n { \text_lowercase:n { \g__mitthesis_committee_name_tl } }
		}

	\vbox_to_ht:nn { \vsize } % to prevent committee page splitting into two pages
		{ 
		\tag_struct_begin:n { tag=Committee_page, title=Committee~page }
        	\leavevmode   
			\hbox:n {} 
        	\__mitthesis_cmtitle_blockskip:
			{ % to contain \raggedleft
        	\raggedleft	 
            \tagpdfsetup{ table/tagging=presentation }
        	\begin{tabular*}{\textwidth}{@{}l@{\extracolsep{\fill}}r@{}}
             	&
				\tag_struct_begin:n { tag=Committee_name, title=Committee~name }
                \tag_struct_begin:n { tag = Strong }
                \tag_mc_begin:n { tag=Strong  }                
            	\__mitthesis_CMstyle:n { \g__mitthesis_committee_name_tl }
            	\tag_mc_end:
                \tag_struct_end:
                \tag_struct_end:
                \pdfbookmark[0]{ \g__mitthesis_committee_name_str }{ thesiscommittee }
        	\end{tabular*}
        	\__mitthesis_cmtitle_blockskip:
	
        	\begin{tabular*}{\textwidth}{@{}l@{\extracolsep{\fill}}r@{}}
    			&
				\tag_struct_begin:n { tag=Committee_block_title, title=Thesis~Readers }
				\tag_mc_begin:n { tag=Committee_block_title }
				\__mitthesis_CMsubstyle:n { \g__mitthesis_titlepg_sup_designation_tl }
				\tag_mc_end:
                \tag_struct_end:
        	\end{tabular*}
        	\skip_vertical:n {12pt} 
        	\int_do_while:nNnn { \g__mitthesis_committee_supno_int } < { \g__mitthesis_supervisor_cnt_int } {
             	\int_gincr:N  \g__mitthesis_committee_supno_int
                \begin{tabular*}{\textwidth}{@{}l@{\extracolsep{\fill}}r@{}}
        			&
                	\tag_struct_begin:n { tag = Strong }
                	\tag_mc_begin:n { tag=Strong }
        			\textbf{ \seq_item:cn { g__mitthesis_supervisor_name_seq } { \g__mitthesis_committee_supno_int } }
        			\tag_mc_end:
        			\tag_struct_end:
        			\\      
        			& \__mitthesis_assemble_CMtitle_list:n { \seq_item:cn { g__mitthesis_supervisor_title_seq }
						{ \g__mitthesis_committee_supno_int } } \\ 
					& \__mitthesis_assemble_CMtitle_list:n { \seq_item:cn { g__mitthesis_supervisor_dept_seq }
						{ \g__mitthesis_committee_supno_int } } 
        		\end{tabular*}
        		\skip_vertical:n {14pt}
        	}
        	\skip_vertical:n {32pt}
	
        	\begin{tabular*}{\textwidth}{@{}l@{\extracolsep{\fill}}r@{}}
        		&
				\tag_struct_begin:n { tag=Committee_block_title, title=Thesis~Readers }
				\tag_mc_begin:n { tag=Committee_block_title }
				\__mitthesis_CMsubstyle:n { \g__mitthesis_reader_name_tl }
				\tag_mc_end:
            	\tag_struct_end:
	       	\end{tabular*}
        	\skip_vertical:n {12pt}
        		
        	\int_compare:nNnF { \g__mitthesis_readercnt_int } = {0} {
            	\int_do_while:nNnn { \g__mitthesis_committee_readerno_int } < { \g__mitthesis_readercnt_int } {
        			\int_gincr:N  \g__mitthesis_committee_readerno_int
                  	\begin{tabular*}{\textwidth}{@{}l@{\extracolsep{\fill}}r@{}}
        				&
                		\tag_struct_begin:n { tag=Strong }
        				\tag_mc_begin:n { tag=Strong }
        				\textbf{ \raggedleft 
							\seq_item:cn { g__mitthesis_reader_name_seq } { \g__mitthesis_committee_readerno_int } }
        	    		\tag_mc_end:
                        \tag_struct_end:
                        \\
                	    & \__mitthesis_assemble_CMtitle_list:n { \seq_item:cn { g__mitthesis_reader_title_seq }
	    					{ \g__mitthesis_committee_readerno_int } } \\
                        & \__mitthesis_assemble_CMtitle_list:n { \seq_item:cn { g__mitthesis_reader_department_seq }
                        	{ \g__mitthesis_committee_readerno_int } }
        		   \end{tabular*}
        		\skip_vertical:n {14pt}
        		}
        	}
    	\tag_struct_end:
		}
		\skip_vertical:n { 0pt plus 16fill }
		}
	\cleardoublepage\ignorespacesafterend
}

%%%%%%%%%%  End thesis committee members page module  %%%%%%%%%%%%%%%%%%%%%%%%


%%%%%%%%%%  Abstract page module  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% to change abstract name  (e.g., to "Summary"), follow either approach in your preamble:
%
%	\RenewExpandableDocumentCommand\abstractname{}{Summary}
%	\renewcommand\abstractname{Summary}

\RenewDocumentEnvironment{abstract}{+b}{
	\cleardoublepage % use this (rather than \newpage) in case committee members page is present
    \tag_struct_begin:n { tag=Abstract_page, title=Abstract~page }
    { \centering
    	\tag_struct_begin:n { tag=Abstract_title, title=Abstract~title }
        \pdfbookmark[0]{Abstract}{abstract}
        \leavevmode
		\tag_struct_begin:n { tag=Strong }
        \tag_mc_begin:n { tag=Strong }            
        {\large { \textbf{ \g_mitthesis_title_tl } }
        \par}
        \tag_mc_end:
        \tag_struct_end:
        \tag_struct_end:
        \setlength{\parskip}{0.5\baselineskip plus 2pt minus 2pt}
        \__mitthesis_author_abstractblock:
        \par
        \__mitthesis_degree_abstractblock:
	}
    \skip_vertical:n {2\baselineskip}
    \noindent
    \tag_struct_begin:n { tag=Strong }
    \tag_mc_begin:n { tag=Strong }
	\textbf{ \text_uppercase:n { \abstractname } }
	\tag_mc_end:
    \tag_struct_end:
	\skip_vertical:n { 0.5em }
    \tag_struct_begin:n { tag=Abstract_text, title-o=\abstractname }
	#1
	\par\tag_struct_end:
	\tl_if_blank:nT {#1} { MISSING\ ABSTRACT!  \msg_error:nn { \ClassName } { missing_abstract } }
}{
    \__mitthesis_supervisor_abstractblock:
	\tag_struct_end: % end section
	\cleardoublepage\ignorespacesafterend
}
\msg_new:nnnn { \ClassName } { missing_abstract } { Missing~Abstract!! } 
	{ No~file~was~input~for~the~abstract.~You~need~to~do~\string\input{abstract.tex}. }

%%%%%%%%%%  End abstract page module  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%\debug_off:n {all}
\ExplSyntaxOff

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%% End title and abstract page codes  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%%%%%%%%%  A nomenclature environment  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\providecommand{\nomname}{Nomenclature}  
\newlength\nomenwidth
\newlength\savitemsep

% nomenclature entries
\NewDocumentCommand\entry{m m}{%
    \item[#1\hfill]#2%
    \@itempenalty=-\@lowpenalty
}
% nomenclature subheadings 
\ExplSyntaxOn
\NewDocumentCommand\EntryHeading{m}{%
	\itemsep3\p@ plus 1\p@ minus 1\p@
    \goodbreak
    \item[\tag_struct_begin:n { tag=Nomenclature_entry_heading } \emph{#1}\tag_struct_end: \hfill]\mbox{}% add mbox for tagged pdf 2023/10/11; 2025/09/23 replace \itshape by \emph for css
    \setlength{\itemsep}{\savitemsep}\@itempenalty=10000 % increased to 10000, 2025/04/20
}
%
%   Increase first optional argument to > 2em if wide entries cause undesired misalignment of columns. 
%   Second optional argument can be used to rename the environment, e.g., to List of Symbols.
%   Third optional argument selects section-level or chapter-level style for the nomenclature list.
%   Fourth option argument selects the style of the toc entry (by default, same as #3); the values
%		frontmatter or backmatter can be used when nomenclature is located with front or back matter. 2025/01/17
\NewDocumentEnvironment{nomenclature}{O{2em} O{\nomname} O{section} O{#3}}{%
    \setlength\columnsep{2em}% 
    \setlength{\nomenwidth}{#1}%
    \MakeLinkTarget*{nomenclature}\csname #3\endcsname *{#2}\addcontentsline{toc}{#4}{#2}%
    \raggedright
    \tag_struct_begin:n { tag=Nomenclature_list }
    \begin{list}{}{%
         \setlength{\itemsep}{0pt}%
         \setlength{\parsep}{\itemsep}%
         \setlength{\labelsep}{1em}%
         \setlength{\labelwidth}{\nomenwidth}%
         \setlength{\leftmargin}{\labelwidth}%
         \addtolength{\leftmargin}{\labelsep}%
		 \setlength{\savitemsep}{\itemsep}%
    }%
}{	\end{list}
	\tag_struct_end:
	\ignorespacesafterend
 }

%	The *-version, nomenclature*, sets the nomenclature in a two-column format.
%   The user must load the multicol package!
%	The loading is done *inside* the environment and *before* the list starts so that:
%	i) the nomenclature heading is not in two-column; ii) the list margins are correct.
%
\NewDocumentEnvironment{nomenclature*}{ O{2em} O{\nomname} O{section} O{#3} }{%
    \setlength\columnsep{2em}% 
    \setlength{\nomenwidth}{#1}%
    \MakeLinkTarget*{nomenclature}\csname #3\endcsname *{#2}\addcontentsline{toc}{#4}{#2}%
    \vspace{-\multicolsep}% don't to add to the vertical space already provided by the heading
    \tag_struct_begin:n { tag=Nomenclature_list }
	\begin{multicols}{2}%
    \raggedright
    \begin{list}{}{%
         \setlength{\itemsep}{0pt}%
         \setlength{\parsep}{\itemsep}%
         \setlength{\labelsep}{1em}%
         \setlength{\labelwidth}{\nomenwidth}%
         \setlength{\leftmargin}{\labelwidth}%
         \addtolength{\leftmargin}{\labelsep}%
		 \setlength{\savitemsep}{\itemsep}%
    }%
}{
	\end{list}
	\end{multicols}
	\tag_struct_end:
	\ignorespacesafterend
 }
\ExplSyntaxOff

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\endinput
%%
%% End of file `mitthesis.cls'.
