%% rbt-mathnotes.sty
%% Copyright 2021 Rebecca B. Turner.
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
% of this license or (at your option) any later version.
% The latest version of this license is in
%   http://www.latex-project.org/lppl.txt
% and version 1.3 or later is part of all distributions of LaTeX
% version 2005/12/01 or later.
%
% This work has the LPPL maintenance status `maintained'.
% 
% The Current Maintainer of this work is Rebecca B. Turner.
%
% This work consists of the files:
%     README.md
%     rbt-mathnotes.tex
%     rbt-mathnotes.sty
%     rbt-mathnotes.cls
%     rbt-mathnotes-util.sty
%     rbt-mathnotes-messages.sty
%     rbt-mathnotes-hw.cls
%     rbt-mathnotes-formula-sheet.cls
%     examples/cheat-sheet.tex
%     examples/multivar.tex
%     examples/topology-hw-1.tex
% and the derived files:
%     rbt-mathnotes.pdf
%     examples/cheat-sheet.pdf
%     examples/multivar.pdf
%     examples/topology-hw-1.pdf

\NeedsTeXFormat{LaTeX2e}
\RequirePackage{expl3}
\ProvidesExplPackage{rbt-mathnotes}{2021/11/29}{1.0.2}{Styles for
  mathematical note taking.}
\errorcontextlines 20
% Module 'mn'

% Load some utility packages.
\RequirePackage{xparse}  % Better command declarations.
\RequirePackage{xkeyval}  % Better keyval parsing.
% {{{ Package options
\RequirePackage{kvoptions}  % More flexible package options.
\RequirePackage{rbt-mathnotes-util}

\SetupKeyvalOptions
  {
    family = mn__package_options ,
  }

\mn__option_new[init = true]{fonts}
\mn__option_new[init = true]{stix}
\mn__option_new[init = true]{symbols}
\mn__option_new[init = true]{maketitle}
\mn__option_new[init = true]{titles}
\mn__option_new[init = true]{xcolor}
\mn__option_new[init = true]{theorems}
\mn__option_new[init = true]{enumitem}
\mn__option_new{listings}
\mn__option_new{knowledge}
\mn__option_new{index}
\mn__option_new{footnotes}
\mn__option_new{figures}
\mn__option_new{tabu}
\mn__option_new{kindle}

\mn__process_options:n { mn__package_options } % }}}

\RequirePackage{rbt-mathnotes-messages}

% {{{ Load fonts.
% Check if we can load fontspec; this is taken from fontspec.sty.
\bool_new:N  \c__mn_fontspec_bool
\bool_set:Nn \c__mn_fontspec_bool
  {
    \sys_if_engine_xetex_p: || \sys_if_engine_luatex_p:
  }

% NOTE: The order these packages are loaded in is very important.
% - mathtools has to be loaded before these or overbrackets and such get
%   messed up
% - unicode-math overwrites a bunch of commands, so should be loaded after
%   amsmath and others
% - amsmath should be loaded after stix2 (not sure why, but the stix2
%   documentation specifies this) -- however, if we can use fontspec, we
%   just load the stix2 fonts without the stix2 package itself, so we load
%   amsmath before unicode-math (and the stix2 fonts)
\RequirePackage{mathtools}
\bool_if:NTF \g__mn_fonts_bool
  {
    \bool_if:NTF \c__mn_fontspec_bool
      {
        \RequirePackage{amsmath}[2013/01/14]
        % unicode-math makes equations copy/pastable in PDF output.
        % Note that unicode-math encapsulates the functionality of fontspec.
        \RequirePackage[
          warnings-off={mathtools-colon,mathtools-overbracket}
        ]{unicode-math}
        \bool_if:NT \g__mn_stix_bool
          {
            \setmainfont
              [
                UprightFont    = *-Regular ,
                ItalicFont     = *-Italic ,
                BoldFont       = *-Bold ,
                BoldItalicFont = *-BoldItalic ,
                Extension      = .otf ,
              ]
              { STIX2Text }

            \setmathfont
              [
                StylisticSet =
                  {
                    1 , % better caligraphic forms
                    8 , % upright integrals
                  } ,
                Extension = .otf ,
              ]
              { STIX2Math }
          }
      }
      {
        % Otherwise, load non-XeTeX fallbacks.
        \bool_if:NT \g__mn_stix_bool
          {
            \RequirePackage[upint]{stix2}
          }
        \RequirePackage{amsmath}[2013/01/14]
      }
  }
  {
    % No fonts
    \RequirePackage{amsmath}[2013/01/14]
  } % }}}

\bool_if:NT \g__mn_symbols_bool % {{{ Define math symbol commands
  {
    % Logical not
    \mn__if_package_loaded:nTF { unicode-math }
      { \DeclareDocumentCommand \lnot {} { \char "AC } } % 0xAC = ��
      { \mathchardef \Not = "1218 }

    % Blackboard bold set symbols
    \NewDocumentCommand \Rational {}{\mathbb{Q}}
    \ProvideDocumentCommand \Rat {}{\Rational}
    \ProvideDocumentCommand \Q {}{\Rational}

    % \NewDocumentCommand \Irrational {}{\mathbb{I}}
    % \ProvideDocumentCommand \Irrat {}{\Irrational}
    % \ProvideDocumentCommand \I {}{\Irrational}

    \NewDocumentCommand \Natural {}{\mathbb{N}}
    \ProvideDocumentCommand \Nat {}{\Natural}
    \ProvideDocumentCommand \N {}{\Natural}

    \NewDocumentCommand \Integer {}{\mathbb{Z}}
    \ProvideDocumentCommand \Int {}{\Integer}
    \ProvideDocumentCommand \Z {}{\Integer}

    \NewDocumentCommand \Complex {}{\mathbb{C}}
    \ProvideDocumentCommand \Comp {}{\Complex}
    % Renew \C to mean \Complex in math-mode; normally, \C just gives an
    % error in math-mode.
    % ...if \C isn't defined, just define it normally.
    \AtBeginDocument
      {
        \cs_if_free:NTF \C
          { \NewDocumentCommand }
          {
            \cs_set_eq:NN \mn__C_old \C
            \RenewDocumentCommand
          }
        \C {}{
          \mode_if_math:TF
            { \Complex } % Complex set
            { \mn__C_old } % Copyright sign
        }
      }

    \NewDocumentCommand \Real {}{\mathbb{R}}
    \ProvideDocumentCommand \R {}{\Real}

    % Using the Weierstrass p here is probably a bit controversial, but I like
    % it. I'm open to change, though...
    \ProvideDocumentCommand \powerset {}{\wp}

    \RenewDocumentCommand \vec {m}{\mathbf{#1}}

    % Operator synonyms.
    % Set intersect.
    \ProvideDocumentCommand \intersection {}{\cap}
    \ProvideDocumentCommand \inter {}{\cap}
    \ProvideDocumentCommand \bigintersection {}{\bigcap}
    \ProvideDocumentCommand \biginter {}{\bigcap}

    % Set union.
    \ProvideDocumentCommand \union {}{\cup}
    \ProvideDocumentCommand \bigunion {}{\bigcup}
    % Disjoint union.
    \ProvideDocumentCommand \disjointunion {}{\sqcup}
    \ProvideDocumentCommand \disunion {}{\sqcup}

    % Divisiblity.
    \ProvideDocumentCommand \divisible {}{\mid}
    \ProvideDocumentCommand \div {}{\mid}
    % Negation.
    \ProvideDocumentCommand \notdivisible {}{\nmid}
    \ProvideDocumentCommand \ndivisible {}{\nmid}
    \ProvideDocumentCommand \notdiv {}{\nmid}
    \ProvideDocumentCommand \ndiv {}{\nmid}

    % Wrappers around floor and ceil.
    \ProvideDocumentCommand \floor {m}{\lfloor #1\rfloor}
    \ProvideDocumentCommand \ceil {m}{\lceil #1\rceil}

    % The default empty set symbol is very ugly. Use \varnothing instead,
    % which is less ugly.
    \AtBeginDocument{\RenewDocumentCommand \emptyset {}{\varnothing}}
    \ProvideDocumentCommand \es {}{\emptyset}

    % Function composition. The notation g \after f helps internalize the
    % order of operations. :)
    \ProvideDocumentCommand \after {}{\circ}

    % Cross product.
    \ProvideDocumentCommand \cross {}{\times}

    % Operators.
    % Function image.
    \cs_if_free:NT \img
      { \DeclareMathOperator \img {img} }
    % Function pre-image.
    \cs_if_free:NT \pre
      { \DeclareMathOperator \pre {pre} }
    % Function stabilizer.
    \cs_if_free:NT \Stab
      { \DeclareMathOperator \Stab {Stab} }
    % Set of a function's fixed points.
    \cs_if_free:NT \FixPt
      { \DeclareMathOperator \FixPt {FixPt} }
    % Identity function
    \cs_if_free:NT \id
      { \DeclareMathOperator \id {id} }

    % Injective function.
    \ProvideDocumentCommand \injection {}{\hookrightarrow}
    \ProvideDocumentCommand \inj {}{\hookrightarrow}
    % Surjective function.
    \ProvideDocumentCommand \surjection {}{\twoheadrightarrow}
    \ProvideDocumentCommand \surj {}{\twoheadrightarrow}
    % Bijective function.
    \ProvideDocumentCommand \bijection {}{\twoheadrightarrowtail}
    \ProvideDocumentCommand \bijective {}{\twoheadrightarrowtail}
    \ProvideDocumentCommand \bij {}{\twoheadrightarrowtail}
    % Function restriction.
    \cs_if_free:NT \restriction
      { \DeclareMathOperator \restriction {|} }
    \ProvideDocumentCommand \restr {}{\restriction}

    % d/dx
    \ProvideDocumentCommand \dd { O{} m }{\frac{d#1}{d#2}}
    \ProvideDocumentCommand \pd { O{} m }{\frac{\partial#1}{\partial#2}}
    \ProvideDocumentCommand \gradient {}{\nabla}
    \ProvideDocumentCommand \grad {}{\nabla}
    \cs_if_free:NT \curl
      { \DeclareMathOperator \curl {curl} }
    \cs_if_free:NT \dive
      { \DeclareMathOperator \dive {div} }
  } % }}}

% Gives this an equation a number in an amsmath starred environment.
\ProvideDocumentCommand \numberthis { } % {{{
  {
    \tag { \theequation }
    \refstepcounter { equation }
  } % }}}

% Gives this equation a number and label in an amsmath starred environment.
\ProvideDocumentCommand \labelthis { m } % {{{
  {
    \numberthis
    \IfValueT { #1 }
      { \label { #1 } }
  } % }}}

\bool_if:NT \g__mn_enumitem_bool
  { \RequirePackage{enumitem} }

\bool_if:NT \g__mn_listings_bool
  { \RequirePackage{listings} }

\bool_if:NT \g__mn_xcolor_bool % {{{ Load xcolor and define MN colors
  {
    \PassOptionsToPackage { rgb } { xcolor }
    \RequirePackage { xcolor }
    \providecolorset { HTML }
      % Prefix/postfix of all color names
      { } { }
      {
        \use_none:n
        ; MNthmtitle  , 0F0066
        ; MNthmbg     , EBFEFF
        ; MNthmline   , 4836B3
        ; MNextitle   , 692219
        ; MNexbg      , FFF0EB
        ; MNexline    , CC7468
        ; MNdefntitle , 00540B
        ; MNdefnline  , 196924
        ; MNdefnbg    , EBFFED
        ; MNnotetitle , 6B0019
        ; MNnoteline  , CC3F60
        ; MNnotebg    , FFF5F7

        ; MNsecnum , 8015A1

        ; MNlink , 113DB8
      }
  } % }}}

\bool_if:NT \g__mn_listings_bool % {{{ Better default styles
  {
    \RequirePackage { xcolor }
    \lstset
      {
        % Use a monospace font for code listings.
        basicstyle        = \ttfamily ,
        language          = Mathematica ,
        % Tab size of 4, but you should probably use spaces.
        tabsize           = 4 ,
        % Keywords in blue.
        keywordstyle      = \bfseries\ttfamily\color[rgb]{0,.3,.7} ,
        % Comments in green.
        commentstyle      = \color[rgb]{0.133,0.545,0.133} ,
        % Strings in orange.
        stringstyle       = \color[rgb]{0.75,0.49,0.07} ,
        % The default listings characters are too widely-spaced.
        % 0.55em/character makes things look a lot better.
        basewidth         = 0.55em ,
        % Wrap lines if they're too long, and wrap at whitespace.
        breaklines ,
        breakatwhitespace = true ,
      }
  } % }}}

% Creates an acronym-command.
% \newacronym[<\command>]{<text>} defines \command to be \textsc{text}.
% \newacronym{<text>} defines \text to be \textsc{text}.
\ProvideDocumentCommand \newacronym { o m } % {{{
  {
    \group_begin:
      % If we have #1, then #1 is the cs we're going to define; #1 is a cs.
      % Otherwise, we define \#2.
      \IfValueTF { #1 }
        { \cs_set:Npn \mn__acronym_cs: { \cs_to_str:N #1 } }
        { \cs_set:Npn \mn__acronym_cs: { #2 } }

      % Ensure that the cs is undefined.
      \cs_if_exist:cT { \mn__acronym_cs: }
        {
          \msg_error:nnxx
            { mathnotes }
            { acronym already defined }
            { \exp_not:c { \mn__acronym_cs: } }
            { #2 }
        }

      % Finally, define the acronym command.
      \cs_new:cpn { \mn__acronym_cs: }
        { \textsc { #2 } }
    \group_end:
  } % }}}

% \newacronyms takes a comma-separated list as its argument and defines them
% all as acronyms.
\ProvideDocumentCommand \newacronyms { m }
  { \clist_map_function:nN { #1 } \newacronym }

% {{{ Package configuration string values; \mathnotes command
\keys_define:nn { mn__main }
  {
    date   .value_required:n = true ,
    date   .code:n           = \date{#1} ,
    author .value_required:n = true ,
    author .code:n           = \author{#1} ,
    title  .value_required:n = true ,
    title  .code:n           = \title{#1} ,

    generate~thanks .value_required:n = false ,
    generate~thanks .bool_set:N = \g__mn_should_make_thanks ,
    generate~thanks .default:n = true ,
    generate~thanks .initial:n = true ,
  }

\cs_set:Npn \mn__key_new:n #1
  {
    \keys_define:nn { mn__main }
      {
        #1 .value_required:n = true ,
        #1 .tl_gset:c = g__mn_#1_tl ,
        #1 .initial:x = ,
      }
  }

\cs_set:Npn \mn__keys_new:n #1 { \clist_map_function:nN { #1 } \mn__key_new:n }

\mn__keys_new:n
  {
    instructor, course, name, email, institution, semester,
  }

\NewDocumentCommand \mathnotes { m }
  {
    \keys_set:nn { mn__main } { #1 }
  }
% }}}

\bool_if:NT \g__mn_maketitle_bool % {{{ \author, \title, \maketitle, \thanks, etc.
  {
    \bool_new:N \g__mn_author_set
    \cs_set:Npn \author #1
      {
        \bool_gset_true:N \g__mn_author_set
        \cs_gset:Npn \@author { #1 }
      }

    \bool_new:N \g__mn_title_set
    \cs_set:Npn \title #1
      {
        \bool_gset_true:N \g__mn_title_set
        \cs_gset:Npn \@title { #1 }
      }

    \prg_new_conditional:Npnn \mn__if_should_make_thanks: % {{{
      { T, }
      {
        \bool_if:NTF \g__mn_should_make_thanks
          {
            \bool_lazy_all:nTF
              {
                { \tl_if_empty_p:N \g__mn_email_tl }
                { \tl_if_empty_p:N \g__mn_course_tl }
                { \tl_if_empty_p:N \g__mn_instructor_tl }
                { \tl_if_empty_p:N \g__mn_institution_tl }
                { \tl_if_empty_p:N \g__mn_semester_tl }
              }
              { \prg_return_false: }
              { \prg_return_true: }
          }
          { \prg_return_false: }
      } % }}}

    \cs_set:Npn \mn__make_thanks_text % {{{
      {
        \tl_if_empty:NF \g__mn_email_tl
          {
            \email { \tl_use:N { \g__mn_email_tl } }
            \bool_lazy_all:nF
              {
                { \tl_if_empty_p:N \g__mn_course_tl }
                { \tl_if_empty_p:N \g__mn_instructor_tl }
                { \tl_if_empty_p:N \g__mn_institution_tl }
                { \tl_if_empty_p:N \g__mn_semester_tl }
              }
              { ;~ }
          }
        \tl_if_empty:NF \g__mn_course_tl
          {
            \tl_use:N \g__mn_course_tl
            \bool_lazy_all:nF
              {
                { \tl_if_empty_p:N \g__mn_instructor_tl }
                { \tl_if_empty_p:N \g__mn_institution_tl }
                { \tl_if_empty_p:N \g__mn_semester_tl }
              }
              { ~ }
          }
        \tl_if_empty:NF \g__mn_instructor_tl
          {
            \bool_lazy_all:nTF
              {
                { \tl_if_empty_p:N \g__mn_email_tl }
                { \tl_if_empty_p:N \g__mn_course_tl }
              }
              { Taught~by~ }
              { taught~by~ }
            \tl_use:N \g__mn_instructor_tl
          }
        \tl_if_empty:NF \g__mn_institution_tl
          {
            \bool_lazy_all:nTF
              {
                { \tl_if_empty_p:N \g__mn_email_tl }
                { \tl_if_empty_p:N \g__mn_course_tl }
                { \tl_if_empty_p:N \g__mn_instructor_tl }
              }
              { At~ }
              { ~at~ }
            \tl_use:N \g__mn_institution_tl
          }
        \tl_if_empty:NF \g__mn_semester_tl
          {
            \bool_lazy_all:nF
              {
                { \tl_if_empty_p:N \g__mn_email_tl }
                { \tl_if_empty_p:N \g__mn_course_tl }
                { \tl_if_empty_p:N \g__mn_instructor_tl }
                { \tl_if_empty_p:N \g__mn_institution_tl }
              }
              { ,~ }
            \tl_use:N \g__mn_semester_tl
          }
        .
      } % }}}

    \cs_set:Npn \@author % {{{
      {
        % If the author hasn't been set, we provide this (complicated, PITA)
        % default; however, if we don't have any information to put in it, we
        % still give a warning.
        \tl_if_eq:NNTF \g__mn_name_tl \c_novalue_tl
          {
            \msg_warning:nn { mathnotes } { no name }
          }
          {
            \tl_use:N \g__mn_name_tl
            % Do we have any information to put in a \thanks?
            \mn__if_should_make_thanks:T
              {
                \thanks { \mn__make_thanks_text }
              }
          }
      } % }}}

    % {{{ \@maketitle and \maketitle
    \skip_const:Nn \g__mn_maketitle_after_title { 1em }
    \skip_const:Nn \g__mn_maketitle_after_author { 0.5em }
    \skip_const:Nn \g__mn_maketitle_after { 1.5em }

    \RenewDocumentCommand \@maketitle {}
      {
        \begin{center}
          \let \footnote \thanks

          % Set the title, if it exists.
          \bool_if:NT \g__mn_title_set
            {
              \group_begin:
              \HUGE
              \bfseries
              \@title
              \par
              \group_end:
            }
          \skip_vertical:N \g__mn_maketitle_after_title

          % Set the author.
          \group_begin:
          \LARGE
          \lineskip 0.5em
          \begin{tabular}[t]{c}
            \@author
          \end{tabular}
          \par
          \group_end:
          \skip_vertical:N \g__mn_maketitle_after_author

          % Set the date.
          \large
          \@date

        \end{center}
        \par
        \skip_vertical:N \g__mn_maketitle_after
      }

    \RenewDocumentCommand \maketitle {}
      {
        \par
        \group_begin:
          \cs_set:Npn \thefootnote
            {
              \@fnsymbol
              \c@footnote
            }
          \cs_set:Npn \@makefnmark
            {
              \rlap
                {
                  \@textsuperscript { \normalfont \@thefnmark }
                }
            }
          \cs_set:Npn \@makefntext ##1
            {
              \parindent 1em
              \noindent
              \hbox_to_wd:nn
                { 1.8em }
                {
                  \hss
                  \@textsuperscript { \normalfont \@thefnmark }
                }
              ##1
            }
          \legacy_if:nTF { @twocolumn }
            {
              \if_int_compare:w \col@number = \@ne
                \@maketitle
              \else:
                \twocolumn [ \@maketitle ]
              \fi:
            }
            {
              \newpage
              \global\@topnum\z@
              \@maketitle
            }
          \thispagestyle{empty}
          \@thanks
        \group_end:
        \setcounter{footnote}{0}
        \cs_set:Npn \thanks ##1 { }
        % NOTE: we don't erase the definitions of \@title, etc.
      }
    % }}} \@maketitle and \maketitle
  } % }}}

\bool_if:NT \g__mn_kindle_bool % {{{
  {
    \keys_set:nn { mn__main }
      {
        generate~thanks = false ,
      }
    \skip_gset:Nn \g__mn_maketitle_after_title { 0em }
    \skip_gset:Nn \g__mn_maketitle_after_author { 0em }
    \skip_gset:Nn \g__mn_maketitle_after { 0em }
    \@ifclassloaded { memoir }
      {
        \pagestyle { empty }

        \setstocksize{12.2cm}{9cm}
        \settrimmedsize{12.2cm}{9cm}{*}
        \settypeblocksize{12.2cm}{9cm}{*}

        \setlrmargins{0cm}{*}{*}
        \setulmargins{0cm}{*}{*}

        \setlength{\headheight}{0cm}
        \setlength{\headsep}{0cm}
        \setlength{\footskip}{0cm}

        \checkandfixthelayout
      }
      {
          \msg_error:nnx
            { mathnotes }
            { requires memoir class }
            { kindle }
      }
  } % }}}

% e.g. `\exp:w \mn__color:n { MNnotetitle }`
\cs_set:Npn \mn__color:n #1 % {{{
  {
    \bool_if:NTF \g__mn_xcolor_bool
      {
        \exp_end:
        \color{#1}
      }
      {
        \exp_end:
      }
  } % }}}

\bool_if:NT \g__mn_theorems_bool % {{{ mdtheorem setup
  {
    \RequirePackage[thmmarks, amsmath, amsthm]{ntheorem}

    \RequirePackage{mdframed}

    \mdfdefinestyle { theorem }
      {
        linewidth = 1.5pt ,
      }

    \bool_if:NT \g__mn_xcolor_bool
      {
        \mdfapptodefinestyle { theorem }
          {
            frametitlefont = \normalfont\bfseries\color{MNthmtitle} ,
            linecolor = MNthmline ,
            backgroundcolor = MNthmbg ,
          }
      }

    \mdfdefinestyle { minor-theorem }
      {
        style = theorem ,
        linewidth = 0.75pt ,
      }

    \mdfdefinestyle { example }
      {
        theoremtitlefont = \normalfont ,
      }

    \bool_if:NT \g__mn_xcolor_bool
      {
        \mdfapptodefinestyle { example }
          {
            frametitlefont = \normalfont\bfseries\color{MNextitle} ,
            linecolor = MNexline ,
            backgroundcolor = MNexbg ,
          }
      }

    \mdfdefinestyle { definition }
      {
      }

    \bool_if:NT \g__mn_xcolor_bool
      {
        \mdfapptodefinestyle { definition }
          {
            frametitlefont = \normalfont\bfseries\color{MNdefntitle} ,
            linecolor = MNdefnline ,
            backgroundcolor = MNdefnbg ,
          }
      }

    \mdfdefinestyle { note }
      {
        topline = false ,
        rightline = false ,
        bottomline = false ,
        linewidth = 2pt ,
      }

    \bool_if:NT \g__mn_xcolor_bool
      {
        \mdfapptodefinestyle { note }
          {
            frametitlefont = \normalfont\bfseries\color{MNnotetitle} ,
            linecolor = MNnoteline ,
            backgroundcolor = MNnotebg ,
          }
      }

    \mdfdefinestyle { example }
      {
        theoremtitlefont = \normalfont ,
      }

    \bool_if:NT \g__mn_xcolor_bool
      {
        \mdfapptodefinestyle { example }
          {
            frametitlefont = \normalfont\bfseries\color{MNextitle} ,
            linecolor = MNexline ,
            backgroundcolor = MNexbg ,
          }
      }

    \mdtheorem
      [ style = theorem ]
      { thm }
      { Theorem }
    % \newtheorem{shortthm}[thm]{Theorem}
    \mdtheorem
      [ style = minor-theorem ]
      { lem }
      { Lemma }
    \mdtheorem
      [ style = minor-theorem ]
      { cor }
      { Corollary }
    \mdtheorem
      [ style = minor-theorem ]
      { prop }
      { Proposition }

    % \theoremstyle{definition}
    \mdtheorem
      [ style = definition ]
      { defn }
      { Definition }
    \mdtheorem
      [ style = definition ]
      { notation }
      { Notation }

    % \theoremstyle{remark}
    \mdtheorem
      [ style = example ]
      { ex }
      { Example }

    \skip_new:N \mn__note_title_after_skip
    \skip_set:Nn \mn__note_title_after_skip { 1em plus 0.25em minus 0.75em }
    \cs_set:Npn \mn__note_title:n #1
      {
        \textbf
          {
            \exp:w \mn__color:n { MNnotetitle }
            #1
          }
        \skip_horizontal:N \mn__note_title_after_skip
      }

    \newmdenv
      [
        style = note ,
        startinnercode = \mn__note_title:n { Note: } ,
      ]
      { note }

    \newmdenv
      [
        style = note ,
        startinnercode = \mn__note_title:n { Remark: } ,
      ]
      { remark }

    \newmdenv
      [
        style = note ,
        startinnercode = \mn__note_title:n { Hint: } ,
      ]
      { hint }

    \newmdenv
      [
        style = note ,
        startinnercode = \mn__note_title:n { Abuse of notation: } ,
      ]
      { abuse-of-notation }

    % % reset for future defn.s
    % \theoremstyle{plain}
  } % }}}

\NewDocumentCommand \TODO { o } % {{{
  {
    \framebox
      {
        \textbf{ TODO \IfValueT { #1 } { :~} }
        \IfValueT { #1 } { #1 }
      }
  } % }}}

% \bool_if:NT \g__mn_titles_bool % {{{
  % {
    % \RequirePackage{titlesec}
    % % \titleformat { \command } [ shape ] { format } { label } { sep } { before-code } [ after-code ]
    % % before-code can be a command
    % \titleformat { \chapter }
      % [ block ]
      % { \bfseries \HUGE }
      % { { \exp:w \mn__color:n {MNsecnum} \thechapter} }
      % { 20pt }
      % { }
      % [ ]

    % \titleformat { \section }
      % [ hang ]
      % { \bfseries \LARGE }
      % { { \exp:w \mn__color:n {MNsecnum} \thesection} }
      % { 16pt }
      % { }
      % [ ]

    % \titleformat { \subsection }
      % [ hang ]
      % { \bfseries \Large }
      % { { \exp:w \mn__color:n {MNsecnum} \thesubsection} }
      % { 16pt }
      % { }
      % [ ]

    % % \titlespacing* { \command } { left } { before } { after } [ right ]
    % \titlespacing* { \chapter }       { 0em } { 0em } { 2em } [ 0em ]
    % \titlespacing* { \section }       { 0em } { 2em } { 0.5em } [ 0em ]
    % \titlespacing* { \subsection }    { 0em } { 1em } { 0em } [ 0em ]
    % \titlespacing* { \subsubsection } { 0em } { 1em } { 0em } [ 0em ]
  % } % }}}

\bool_if:NT \g__mn_xcolor_bool % {{{
  {
    \RequirePackage[hidelinks]{hyperref}
    \hypersetup
      {
        colorlinks = true ,
        allcolors = MNlink ,
      }
  } % }}}

\bool_if:NT \g__mn_index_bool
  {
    \bool_set_true:N \g__mn_knowledge_bool
  }

\bool_if:NTF \g__mn_knowledge_bool % {{{
  {
    \bool_if:NT \g__mn_xcolor_bool
      {
        \PassOptionsToPackage{xcolor}{knowledge}
        \providecolorset { HTML }
          % Prefix/postfix of all color names
          { } { }
          {
            \use_none:n
            ; MNunknown     , DE0B0F
            ; MNunknowncont , AD483E
            ; MNintro       , 051338
          }
      }
    \RequirePackage[quotation, notion, makeidx]{knowledge}

    % Disable the redefined \label command; this fixes some documents.
    \KnowledgeConfigureBooleanOption[\knowledge_configuration_label_autoscope_bool]{patch~label}

    % {{{ Patch in the automatic-AP feature
    \bool_new:N \g__mn_noAP_bool
    \NewDocumentCommand \noAP { }
      { \bool_gset_true:N \g__mn_noAP_bool }
    \cs_set:Npn \mn__maybe_AP:N #1
      {
        \bool_if:NTF \g__mn_noAP_bool
          { \bool_gset_false:N \g__mn_noAP_bool }
          { #1 }
      }

    \RequirePackage{etoolbox}
    \pretocmd { \intro }
      { \mn__maybe_AP:N \AP }
      { } { }

    \bool_new:N \l__mn_using_itemAP
    \cs_set:Npn \mn__use_itemAP:
      {
        \bool_if:NF \l__mn_using_itemAP
          {
            \let \mn__item_orig: \item
            \bool_set_true:N \l__mn_using_itemAP
            \RenewDocumentCommand \item { o }
              {
                \IfNoValueTF { ##1 }
                  {
                    \mn__item_orig:
                    \mn__maybe_AP:N \AP
                  }
                  {
                    \mn__item_orig:
                      [
                        \mn__maybe_AP:N \knowledge_itemAP:
                        % NOTE: this isn't expandable, which fucks up
                        % everything.
                        \cs_set_eq:NN \AP \prg_do_nothing:
                        ##1
                      ]
                  }
              }
          }
      }
    \apptocmd { \enumerate }   { \mn__use_itemAP: } { } { }
    \apptocmd { \itemize }     { \mn__use_itemAP: } { } { }
    \apptocmd { \description } { \mn__use_itemAP: } { } { }
    % }}}

    % {{{ Make some better styles.
    \knowledgeconfigure
      {
        visible~anchor~points = false
      }
    \cs_set:Npn \mn__knowledgestyles:nn #1#2
      {
        \clist_map_inline:nn { #1 }
          { \knowledgestyle* { ##1 } { #2 } }
      }
    % List of default styles
    % notion, intro notion
    % intro, intro unknown, intro unknown cont
    % kl unknown, kl unknown cont
    \bool_if:NTF \g__mn_xcolor_bool
      {
        \mn__knowledgestyles:nn
          { notion , intro~notion }
          {
            color = MNlink ,
          }
        \mn__knowledgestyles:nn
          { intro , intro~notion , intro~unknown, intro~unknown~cont , }
          {
            boldface ,
            color = MNintro ,
          }
        \mn__knowledgestyles:nn
          { intro~unknown , intro~unknown~cont , kl~unknown , kl~unknown~cont , }
          {
            underline = false ,
            color     = MNunknown ,
          }
        \mn__knowledgestyles:nn
          { intro~unknown~cont , kl~unknown~cont , }
          {
            color = MNunknowncont ,
          }
      }
      {
        % These blank definitions are important for erasing some very poorly
        % typeset decisions.
        \mn__knowledgestyles:nn
          { notion , intro~notion }
          {
          }
        \mn__knowledgestyles:nn
          { intro , intro~notion , intro~unknown, intro~unknown~cont , }
          {
            boldface ,
          }
        \mn__knowledgestyles:nn
          { intro~unknown , intro~unknown~cont , kl~unknown , kl~unknown~cont , }
          {
          }
        \mn__knowledgestyles:nn
          { intro~unknown~cont , kl~unknown~cont , }
          {
          }
      }
    % }}}
  }
  {
    % If we don't load the knowledge package, provide a *similar* interface
    % to make writing commands that *optionally* use the knowledge interface
    % easier.
    \ProvideDocumentCommand \itemAP { O{} } { \item[#1] }
    \ProvideDocumentCommand \AP { } { }
    \ProvideDocumentCommand \phantomintro { d() m } { }
    \ProvideDocumentCommand \nointro { m } { }
    \ProvideDocumentCommand \reintro { s o m } { #3 }
    \ProvideDocumentCommand \intro { d() o d() m } { #4 }
    \ProvideDocumentCommand \kl { d() o d() m } { #4 }
  } % }}}

\bool_if:NT \g__mn_index_bool
  {
    \makeindex
  }

% The \emailstyle command gives the style of an email; by default, we
% initialize it to \texttt.
\ProvideDocumentCommand \emailstyle { m } { \texttt{#1} }
% The \email command typesets an email; if the user has loaded the
% hyperref package, we can add a link as well.
\mn__if_package_loaded:nTF { hyperref } % {{{
  {
    \ProvideDocumentCommand \email { m }
          { \href{mailto:#1}{\emailstyle{#1}} }
  }
  {
    \ProvideDocumentCommand \email { m }
          { \emailstyle{#1} }
  } % }}}

\bool_if:NT \g__mn_tabu_bool % {{{
  {
    \RequirePackage{multirow}
    \RequirePackage{booktabs}
    \RequirePackage{longtable}
    \RequirePackage{tabu}
    \ProvideExpandableDocumentCommand \Th { O{l} m }
      {
        \multicolumn
          { 1 } % For 1 column...
          { #1 } % ...with column-spec #1...
          { \textbf{#2} } % Typeset #2 in bold.
      }
  } % }}}

\bool_if:NT \g__mn_figures_bool % {{{
  {
    % figure captions
    \RequirePackage{graphicx}
    \RequirePackage{caption}
    \captionsetup
      {
        format = hang,
        font   = { sf, footnotesize },
        margin = 1in
      }
  } % }}}

% {{{ Footnotes
\bool_if:NT \g__mn_footnotes_bool
  {
    \PassOptionsToPackage{bottom, hang}{footmisc}
    \RequirePackage{footmisc}
  }
\setlength { \footnotesep } { \baselineskip }
% }}}

% Document style.
\setlength { \parindent } { 0em }
\setlength { \parskip }   { 1em }
% {{{ Set \parskip=0 around \tableofcontents
\RequirePackage{etoolbox}
\pretocmd { \tableofcontents }
  {
    \group_begin:
    \setlength{\parskip}{0pt}
  }
  { } { }
\apptocmd { \tableofcontents }
  { \group_end: }
  { } { }
% }}}

% This has to be hooked so that it doesn't break the other bools undefined
% with it first.
\AtEndOfPackage { \cs_undefine:N \mn__legacy_bool_undefine:n }