texlive[68881] Master/texmf-dist: thermodynamics (17nov23)

commits+karl at tug.org commits+karl at tug.org
Fri Nov 17 23:02:57 CET 2023


Revision: 68881
          https://tug.org/svn/texlive?view=revision&revision=68881
Author:   karl
Date:     2023-11-17 23:02:57 +0100 (Fri, 17 Nov 2023)
Log Message:
-----------
thermodynamics (17nov23)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/thermodynamics/README.md
    trunk/Master/texmf-dist/doc/latex/thermodynamics/thermodynamics-examples.tex
    trunk/Master/texmf-dist/doc/latex/thermodynamics/thermodynamics.pdf
    trunk/Master/texmf-dist/source/latex/thermodynamics/thermodynamics.dtx
    trunk/Master/texmf-dist/source/latex/thermodynamics/thermodynamics.ins
    trunk/Master/texmf-dist/tex/latex/thermodynamics/thermodynamics.sty

Modified: trunk/Master/texmf-dist/doc/latex/thermodynamics/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/thermodynamics/README.md	2023-11-17 22:02:41 UTC (rev 68880)
+++ trunk/Master/texmf-dist/doc/latex/thermodynamics/README.md	2023-11-17 22:02:57 UTC (rev 68881)
@@ -4,13 +4,13 @@
 Thermodynamics texts (textbooks, articles, and so forth) are typically filled
 with underlined and overlined symbols, partial derivatives surrounded by
 delimiters and containing subscripts, sums over multiple components, and a
-myriad of symbols, including superscript and subscript modifiers. This package
-provides a robust, flexible set of macros to define notation for symbols,
-partial derivatives, sums, and products frequently encountered in mixture
-thermodynamics. Changing one's notes from one textbook to another or from one
-notation style to another can be achieved relatively easily by changing package
-options, without any changes to the user's code (other than perhaps adjusting
-line breaks).
+myriad of symbols, including superscript and subscript modifiers. This
+package provides a robust, flexible set of macros to define notation for
+symbols, partial derivatives, sums, and products frequently encountered in
+mixture thermodynamics. Changing one's notes from one textbook to another or
+from one notation style to another can be achieved relatively easily by
+changing package options, without any changes to the user's code (other than
+perhaps adjusting line breaks).
 
 Installation
 ------------
@@ -18,8 +18,10 @@
 The package is suppled in `dtx` format with an accompanying `ins` file to
 install the package. Run `latex thermodynamics.ins` to extract the package;
 instructions for building the documentation are included in the `ins` file.
+Note that the package itself (`sty` file) is required to typeset the
+documentation.
 
-This package requires the `amstext` package.
+This package requires the `amstext` and `expl3` packages.
 
 Typesetting the documentation requires several other packages:
  - `geometry`

Modified: trunk/Master/texmf-dist/doc/latex/thermodynamics/thermodynamics-examples.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/thermodynamics/thermodynamics-examples.tex	2023-11-17 22:02:41 UTC (rev 68880)
+++ trunk/Master/texmf-dist/doc/latex/thermodynamics/thermodynamics-examples.tex	2023-11-17 22:02:57 UTC (rev 68881)
@@ -8,7 +8,7 @@
 %% 
 %% This is a generated file.
 %% 
-%% Copyright (C) 2017-2018 by Karl D. Hammond
+%% Copyright (C) 2022-2023 by Karl D. Hammond
 %% 
 %% Karl D. Hammond,
 %% Department of Chemical Engineering
@@ -22,6 +22,7 @@
 %%   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.
+%%^^A            = C_i \gammamol_i \Henrymol_i
 \documentclass{article}
 \usepackage[margin=1in]{geometry}
 \usepackage{amsmath,amssymb}
@@ -30,6 +31,7 @@
 \author{Karl D. Hammond}
 \date{}
 \begin{document}
+\NewThermodynamicProperty{B}{B}
 \maketitle\noindent
 The combined laws:
 \begin{align*}
@@ -65,6 +67,33 @@
     = -\Partial*{\St}{\Nt_i}{T,P,\allNsbut{i}}
     = -\Spm_i
 \end{gather*}
+Temporary changes of derivative delimiters:
+\begin{gather*}
+  \begin{thermobrackets}
+    \Partial*{\Vt}{T}{P,\allNs}
+  \end{thermobrackets}
+  \begin{thermobar}
+    = \PartialMixSecond*{\Gt}{T}{P}{\allNs}
+  \end{thermobar}
+  \begin{thermomolesrange}
+    = \PartialMixSecond*{\Gt}{P}{T}{\allNs}
+  \end{thermomolesrange}
+  \begin{thermobraces}
+      = -\Partial*{\St}{P}{T,\allNs}
+    \begin{thermoNOsubscripts}
+      \begin{thermomolesrange}
+        = -\Partial{\St}{P}{T,\allNs}
+      \end{thermomolesrange}
+    \end{thermoNOsubscripts}
+  \end{thermobraces}
+\end{gather*}
+Inline derivatives:
+\begin{gather*}
+  \mu_i = \Partialinline{\Gt}{\Nt_i}{T,P,\allNsbut{i}}
+        = \Partialinline{\Ft}{\Nt_i}{T,\Vt,\allNsbut{i}}
+        = \Partialinline{\Ht}{\Nt_i}{\St,P,\allNsbut{i}}
+        = \Partialinline{\Ut}{\Nt_i}{\St,\Vt,\allNsbut{i}}
+\end{gather*}
 The heat capacities:
 \begin{gather*}
   \cV = T \Partial*{\Sm}{T}{\Vm,\allXs} = \Partial*{\Um}{T}{\Vm,\allXs}
@@ -137,7 +166,7 @@
   \\
   a_i = \frac{\fmix_i}{\fstd_i}
       = x_i \gamma_i
-                \exp\left(\frac{1}{RT} \int_{\Pstd}^P \Vm_i(T,p) dp\right)
+                \exp\left(\frac{1}{RT} \int_{\Pstd}^P \Vm_i(T,p)\,dp\right)
       \approx x_i \gamma_i
   \\
   \begin{split}
@@ -146,9 +175,9 @@
            = x_i \gammarat_i \Henryrat_i
            = C_i \gammamol_i \Henrymol_i
            = x_i \gamma_i \fsat_i
-                 \exp\left(\frac{1}{RT} \int_{\Psat_i}^P \Vm_i(T,p) dp\right)
+                 \exp\left(\frac{1}{RT} \int_{\Psat_i}^P \Vm_i(T,p)\,dp\right)
        \\ &= x_i \gamma_i \Psat_i \phisat_i
-                \exp\left(\frac{1}{RT} \int_{\Psat_i}^P \Vm_i(T,p) dp\right)
+                \exp\left(\frac{1}{RT} \int_{\Psat_i}^P \Vm_i(T,p)\,dp\right)
           \approx x_i \gamma_i \Psat_i
   \end{split}
 \end{gather*}
@@ -206,6 +235,19 @@
   \SE &= \Sm - \Sm^\IS &
   \VRpm_k &= \Vpm_k - \Vpm_k^\IGM
 \end{align*}
+Jacobians:
+\begin{gather*}
+  \Jacobian{\St,\Vt}{T,P} = \Jacobiandet{\St,\Vt}{T,P} \\
+  \Jacobian{f,g,h}{x,y,z} = \Jacobiandet[\displaystyle]{f,g,h}{x,y,z} \\
+  \Jacobian{h_1,\dots,h_k}{z_1,\dots,z_k} =
+      \Jacobiandet{h_1,\dots,h_k}{z_1,\dots,z_k} \\
+  \cP = T\Partial{\Sm}{T}{P}
+      = T\Jacobian{\Sm,P}{T,P}
+      = -T\Jacobian{\Sm,P}{T,\Vm} \Jacobian{T,\Vm}{T,P}
+      = -T\Jacobian{P,\Sm}{\Vm,\Sm} \Jacobian{\Vm,\Sm}{T,\Vm}
+          \Jacobian{T,\Vm}{T,P}
+      = \gamma \cV
+\end{gather*}
 \end{document}
 \endinput
 %%

Modified: trunk/Master/texmf-dist/doc/latex/thermodynamics/thermodynamics.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/source/latex/thermodynamics/thermodynamics.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/thermodynamics/thermodynamics.dtx	2023-11-17 22:02:41 UTC (rev 68880)
+++ trunk/Master/texmf-dist/source/latex/thermodynamics/thermodynamics.dtx	2023-11-17 22:02:57 UTC (rev 68881)
@@ -1,5 +1,5 @@
 % \iffalse meta-comment
-% File: thermodynamics.dtx Copyright (C) 2021 Karl D. Hammond
+% File: thermodynamics.dtx Copyright (C) 2022-2023 Karl D. Hammond
 %
 % Karl D. Hammond
 % Chemical Engineering Program
@@ -15,7 +15,7 @@
 % version 2005/12/01 or later.
 %
 % This work has the LPPL maintenance status `maintained'.
-% 
+%
 % The Current Maintainer of this work is K. D. Hammond.
 %
 % This work consists of the files thermodynamics.dtx and thermodynamics.ins
@@ -24,33 +24,47 @@
 % \fi
 %
 % \iffalse
+%^^A FIXME: need correct date of release once you update this
+%^^X\GetIdInfo $Id: thermodynamics.dtx 2.00 2023/11/16 Karl D. Hammond <hammondkd at missouri.edu> $
+%^^X    {thermodynamics notation}
 %<*driver>
+%^^X\ProvidesFile{\ExplFileName}
 \ProvidesFile{thermodynamics.dtx}
 %</driver>
 %
 %<package>\NeedsTeXFormat{LaTeX2e}
+%<package>\RequirePackage{expl3}
 %<package>\ProvidesPackage{thermodynamics}
 %<*package>
-    [2022/04/29 v1.00 thermodynamics package]
+    [2023/11/16 v2.00 thermodynamics notation]
 %</package>
-%
+%^^X    {\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
 %<*driver>
 \documentclass[11pt,letterpaper]{ltxdoc}
-\usepackage[margin=1in,left=1.85in]{geometry}
+%^^X\bool_set_false:N \l__codedoc_allow_indexing_bool
+\usepackage[margin=0.80in,left=2.05in]{geometry}
 \usepackage[T1]{fontenc}
-\usepackage[full]{textcomp}
+\usepackage{textcomp}
 \usepackage{amsmath}
 \usepackage{pxfonts}
 \usepackage{array}
 \usepackage{booktabs}
 \usepackage{footmisc}
-\usepackage[labelfont=bf,labelsep=period]{caption}
-%\EnableCrossrefs
-%\CodelineIndex
+\usepackage[labelfont=bf,labelsep=period,font=small]{caption}
+\GetFileInfo{thermodynamics.dtx}
+\usepackage{thermodynamics}[\filedate\space\fileversion]
+\DisableCrossrefs
+\CodelineIndex
 \PageIndex
 \CodelineNumbered
 \RecordChanges
-%\OnlyDescription
+%^^X Preparing to use l3doc.cls, but it's not quite mature yet....
+%^^A\DisableDocumentation
+%^^A\DisableImplementation
+%^^X\ExplSyntaxOff
+\let\tn\cs
+\let\env\texttt
+\let\pkg\textsf
 \begin{document}
   \DocInput{thermodynamics.dtx}
 \end{document}
@@ -57,7 +71,7 @@
 %</driver>
 % \fi
 %
-% \CheckSum{2286}
+% \CheckSum{2387}
 %
 % \CharacterTable
 % {Upper-case   \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
@@ -76,12 +90,28 @@
 %  Right brace     \}      Tilde           \~}
 %
 % \changes{v1.00}{2022/04/29}{Initial public release}
+% \changes{v2.00}{2023/11/16}{Revision to use \LaTeX3
+%       (\pkg{expl3}/\pkg{xparse}) syntax layer}
 %
+% \newcommand*{\setmarginparsize}[1]
+% {\bgroup
+% \RenewExpandableDocumentCommand{\MacroFont}{}{\fontencoding\encodingdefault
+%    \fontfamily\ttdefault
+%    \fontseries\mddefault
+%    \fontshape\shapedefault
+%    #1}
+% }
+% \newcommand*{\restoremarginparsize}{\egroup}
+%
 % \GetFileInfo{thermodynamics.dtx}
-%
+%^^X \title{The \textsf{thermodynamics} package\thanks{This document
+%^^X   corresponds to \textsf{thermodynamics}~\ExplFileVersion,
+%^^X   dated \ExplFileDate.}}
 % \title{The \textsf{thermodynamics} package\thanks{This document
-%   corresponds to \textsf{thermodynamics}~\fileversion, dated \filedate.}}
+%   corresponds to \textsf{thermodynamics}~\fileversion,
+%   dated \filedate.}}
 % \author{Karl D. Hammond \\ \texttt{hammondkd at missouri.edu}}
+%^^X \date{\ExplFileDate}
 % \date{\filedate}
 % \maketitle
 %
@@ -97,48 +127,21 @@
 % options.
 % \end{abstract}
 %
-% \newcommand*{\thermounderline}[1]{%
-%   \mkern2mu\underline{\mkern-2mu #1\mkern-3mu}\mkern3mu%
-% }
-% \newcommand*{\thermooverline}[1]{%
-%   \mkern2mu\overline{\mkern-2mu #1\mkern-2mu}\mkern2mu%
-% }
-% \newcommand*{\Partial}[3]{\ensuremath{\left(\frac{\partial #1}{\partial #2}\right)_{#3}}}
-% \newcommand*{\Ut}{\mkern1mu\underline{\mkern-1mu U\mkern-4mu}\mkern4mu}
-% \newcommand*{\Upm}[2][]{\mkern2mu\overline{\mkern-2mu U_{#2}^{#1}\mkern-2mu}\mkern2mu}
-% \newcommand*{\Ht}{\mkern1mu\underline{\mkern-1mu H\mkern-4mu}\mkern4mu}
-% \newcommand*{\Hm}{H}
-% \newcommand*{\Hpm}[2][]{\mkern2mu\overline{\mkern-2mu H_{#2}^{#1}\mkern-1mu}\mkern1mu}
-% \newcommand*{\Ft}{\mkern1mu\underline{\mkern-1mu A\mkern-4mu}\mkern4mu}
-% \newcommand*{\Gt}{\mkern1mu\underline{\mkern-1mu G\mkern-4mu}\mkern4mu}
-% \newcommand*{\Gpm}[2][]{\mkern2mu\overline{\mkern-2mu G_{#2}^{#1}\mkern-1mu}\mkern1mu}
-% \newcommand*{\Spm}[2][]{\mkern2mu\overline{\mkern-2mu S_{#2}^{#1}\mkern-1mu}\mkern1mu}
-% \newcommand*{\Vpm}[2][]{\mkern1mu\overline{\mkern-1mu V_{\mkern-2mu #2}^{#1}\mkern-2mu}\mkern2mu}
-% \newcommand*{\St}{\mkern1mu\underline{\mkern-1mu S\mkern-3mu}\mkern3mu}
-% \newcommand*{\Vt}{\mkern3mu\underline{\mkern-3mu V\mkern-4mu}\mkern4mu}
-% \newcommand*{\Lt}{\mkern1mu\underline{\mkern-1mu \Omega\mkern-4mu}\mkern4mu}
-% \newcommand*{\cPpm}[2][]{\mkern2mu\overline{\mkern-2mu C_{P,#2}^{#1}\mkern-1mu}\mkern1mu}
-% 
-% \newcommand*{\Nt}{n}
-% \newcommand*{\allNs}{\vec\Nt}
-% \newcommand*{\allNsbut}[2][j]{\Nt_{#1\neq #2}}
-% \newcommand*{\allXs}{\vec x}
-%
+%^^X \begin{documentation}
 % \section{Introduction}
 % The purpose of this package is to simplify the typesetting of equations in
-% thermodynamics, specifically chemical engineering thermodynamics, which are
+% thermodynamics, particularly chemical engineering thermodynamics, which are
 % often cumbersome to enter. For example, consider the following equation:
 % \begin{equation}
-%   d\Ut = \Partial{\Ut}{\St}{\Vt,\allNs} \mkern-10mu d\St
-%         + \Partial{\Ut}{\Vt}{\St,\allNs} \mkern-10mu d\Vt
-% + \sum_{i=1}^C \Partial{\Ut}{\Nt_i}{\St,\Vt,\allNsbut{i}}
-% \mkern-10mu d\Nt_i.
+%   d\Ut = \Partial*{\Ut}{\St}{\Vt,\allNs} \,d\St
+%         + \Partial*{\Ut}{\Vt}{\St,\allNs} \,d\Vt
+%         + \sumall_i \Partial*{\Ut}{\Nt_i}{\St,\Vt,\allNsbut{i}} d\Nt_i.
 %   \label{eq:chain-rule-U}
 % \end{equation}
 % This equation is pretty basic, and equations like it occur all the time in
 % thermodynamics. Without this package, you might typeset it like this:
 % \begin{verbatim}
-%  d\underline{U} =
+% \[ d\underline{U} =
 %    \left(\frac{\partial\underline{U}}
 %               {\partial\underline{S}}\right)_{\underline{V},\vec{n}}
 %    d\underline{S}
@@ -147,7 +150,7 @@
 %    d\underline{V}
 %  + \sum_{i=1}^C \left(\frac{\partial\underline{U}}
 %       {\partial n_i}\right)_{\underline{S},\underline{V},n_{j\neq i}}
-%    dn_i.
+%    dn_i. \]
 %\end{verbatim}
 % This is a lot of code, and even then the output is slightly clunky:
 % \[ d\underline{U} =
@@ -162,15 +165,19 @@
 %     dn_i.
 % \]
 % It is also frustratingly difficult to change one's notes or handouts from one
-% textbook that uses, say, $n_1$ to denotes moles of component 1 to another
+% textbook that uses, say, $n_1$ to denote moles of component 1 to another
 % textbook that uses $N_1$ for the same quantity, or perhaps denotes the
 % total internal energy as $U$ or $U^t$ rather than $\Ut$.
 % For example, if you wanted it to be
-% \[
-%   dU = \Partial{U}{S}{V,N_1,\dotsc,N_n} \mkern-15mu dS
-%      + \Partial{U}{V}{S,N_1,\dotsc,N_n} \mkern-15mu dV
-% + \sum_{i=1}^n \Partial{U}{N_i}{S,V,N_1,\dotsc,[N_i],\dotsc,N_n}
-% \mkern-20mu dN_i
+% \[\begin{thermomolesrange}
+%   \begin{thermoextensiveplain}
+%   \RenewExpandableDocumentCommand{\Nt}{}{N}
+%   \RenewExpandableDocumentCommand{\ncomponents}{}{\mathcal{C}}
+%   d\Ut = \Partial*{\Ut}{\St}{\Vt,\allNs} \,d\St
+%         + \Partial*{\Ut}{\Vt}{\St,\allNs} \,d\Vt
+%         + \sumall_i \Partial*{\Ut}{\Nt_i}{\St,\Vt,\allNsbut{i}} d\Nt_i.
+%   \end{thermoextensiveplain}
+%   \end{thermomolesrange}
 % \]
 % without changing any of your code---to update it across all handouts, exams,
 % and homework sets after changing textbooks, say---you would be out of luck
@@ -193,43 +200,36 @@
 %
 % The package handles second derivatives, too. For example,
 % \begin{verbatim}
-%  \Partial*{\Hm}{T}{P} = T\Partial*{\Sm}{T}{P}
-%                       = -T\PartialSecond*{\Gm}{T}{P} = \cP
+%  \[ \Partial*{\Hm}{T}{P} = T\Partial*{\Sm}{T}{P}
+%                          = -T\PartialSecond*{\Gm}{T}{P} = \cP \]
 %\end{verbatim}
 % renders (using the default options)
-% \[ \left(\frac{\partial H}{\partial T}\right)_P \mkern-8mu
-%     = T\left(\frac{\partial S}{\partial T}\right)_P \mkern-8mu
-%     = -T\left(\frac{\partial^2 G}{\partial T^2}\right)_P \mkern-8mu
-%     = C_P \]
+%  \[ \Partial*{\Hm}{T}{P} = T\Partial*{\Sm}{T}{P}
+%                          = -T\PartialSecond*{\Gm}{T}{P} = \cP. \]
 % Similarly, macros are defined for mixed second partial derivatives that allow
 % things like
 % \begin{verbatim}
-%  \Partial*{\Gpm_i}{P}{T,\allNs}
+%  \[ \Partial*{\Gpm_i}{P}{T,\allNs}
 %    = \PartialMixSecond*{\Gt}{P}{\Nt_i}{T,\allNsbut{i}}
 %    = \PartialMixSecond*{\Gt}{\Nt_i}{P}{T,\allNsbut{i}}
-%    = \Partial*{Vt}{\Nt_i}{T,P,\allNsbut{i}} = \Vpm_i
+%    = \Partial*{\Vt}{\Nt_i}{T,P,\allNsbut{i}} = \Vpm_i \],
 %\end{verbatim}
 % which renders
-% \[ \left(\frac{\partial \Gpm{i}}{\partial P}\right)_{T,\allNs}
-%   \mkern-15mu%
-%    = \left(\frac{\partial^2 \Gt}{\partial P\partial n_i}\right)_{T,\allNsbut{i}}
-%   \mkern-15mu%
-%    = \left(\frac{\partial^2 \Gt}{\partial n_i\partial P}\right)_{T,\allNsbut{i}}
-%   \mkern-15mu%
-%    = \left(\frac{\partial \Vt}{\partial n_i}\right)_{T,P,\allNsbut{i}}
-%   \mkern-15mu%
-%    = \Vpm{i}
+% \[ \Partial*{\Gpm_i}{P}{T,\allNs}
+%   = \PartialMixSecond*{\Gt}{P}{\Nt_i}{T,\allNsbut{i}}
+%   = \PartialMixSecond*{\Gt}{\Nt_i}{P}{T,\allNsbut{i}}
+%   = \Partial*{\Vt}{\Nt_i}{T,P,\allNsbut{i}} = \Vpm_i
 % \]
 % using the defaults.
 %
-% ^^A-------------------------------------------------------------------------
+%^^A-------------------------------------------------------------------------
 %
 % \section{Using the Package} \label{sec:using}
 % There are three categories of macros defined in this package: macros
 % that produce symbols (or groups of them), macros that typeset derivatives,
 % and macros that are used internally that the user need not know about.
-% There are also several environments that allow the user to switch locally
-% between different delimiters on partial derivatives.
+% There are also several environments that allow the user to change notation
+% temporarily.
 %
 % \subsection{Predefined Symbols}
 % The macros used to produce symbols fall into five categories: extensive
@@ -255,10 +255,10 @@
 % How these symbols are rendered can be customized by package options. As long
 % as the user consistently uses \cs{Ut} to render the total internal energy,
 % \cs{Um} to render the molar internal energy, and so forth, switching notation
-% from, say, $\thermounderline{U}$ to $U^t$ for extensive properties is trivial.
+% from, say, $\Ut$ to $U^t$ for extensive properties is trivial.
 %
-% ^^A \DescribeMacro{\cP}
-% ^^A \DescribeMacro{\cV}
+% \DescribeMacro{\cP}
+% \DescribeMacro{\cV}
 % \DescribeMacro{\cPt}
 % \DescribeMacro{\cVt}
 % \DescribeMacro{\cPs}
@@ -268,31 +268,28 @@
 % The heat capacities (see Table~\ref{table:conveniences}) are generally
 % assumed to be molar (e.g., \cs{cP} is interpreted to be the molar heat
 % capacity). To get the specific heat capacities, the macros \cs{cPs} and
-% \cs{cVs} are provided, which by default render as $\hat C_P$ and $\hat C_V$,
+% \cs{cVs} are provided, which by default render as $\cPs$ and $\cVs$,
 % respectively. There are also extensive versions, so \cs{cPt} and \cs{cVt}
-% will render as $\thermounderline{C}_P$ and $\thermounderline{C}_V,$
+% will render as $\cPt$ and $\cVt,$
 % respectively.  Note that \cs{cP} and friends require you to surround
-% \cs{text} with brackets if the portion with \cs{text} in it is not the last
-% argument.  For example, \verb"\cP_i^\text{A}" will work as expected, but
-% \verb"\cP^\text{A}_i" will not: you need to use \verb"\cP^{\text{A}}_i".
-% Using \verb"\cP^\IG_i" will work as expected.
+% \cs{text} with brackets.  For example, \verb"\cP_i^\text{A}" will not work,
+% nor will \verb"\cP^\text{A}_i"; you need to use \verb"\cP_i^{\text{A}}" and
+% \verb"\cP^{\text{A}}_i". Using \verb"\cP^\IG_i" will work as expected.
 %
 % You can also get partial molar heat capacities via \cs{cPpm} and \cs{cVpm},
 % though the latter's mathematical definition is a bit hard to wrap one's head
 % around:
 % \begin{verbatim}
-%   \[ \cVpm_i = \Partial{\cVt}{\Nt_i}{T,P,\allNsbut{i}}
+%   \[ \cVpm_i = \Partial*{\cVt}{\Nt_i}{T,P,\allNsbut{i}}
 %              = \frac{\partial}{\partial\Nt_i}
 %                \left[ -T\PartialSecond{\Ft}{T}{\Vt,\allNs}
 %                \right]_{T,P,\allNsbut{i}} \]
 %\end{verbatim}
 % yields
-% \[ \thermooverline{C_{V,i}}
-%   = \left(\frac{\partial\thermounderline{C}_V}
-%                {\partial\Nt_i}\right)_{T,P,\allNsbut{i}}
+%   \[ \cVpm{i} = \Partial*{\cVt}{\Nt_i}{T,P,\allNsbut{i}}
 %               = \frac{\partial}{\partial\Nt_i}
-%         \left[ -T\left(\frac{\partial^2\Ft}{\partial T^2}\right)_{\Vt,\allNs}
-%         \right]_{T,P,\allNsbut{i}} \]
+%                 \left[ -T\PartialSecond{\Ft}{T}{\Vt,\allNs}
+%                 \right]_{T,P,\allNsbut{i}}. \]
 %
 % \begin{table}
 %   \caption{Commands defined in this package to represent extensive
@@ -300,80 +297,152 @@
 %       These macros should be used even if the symbol the user
 %       wishes to use does not match the command used (e.g., \cs{Ft}
 %       for total Helmholtz free energy even if it ends up being set as
-%       $\thermounderline{A}$)\@.
+%       $\Ft$)\@.
 %   }
 %   \label{table:symbols}
-%   \SpecialUsageIndex{\Qt}\relax
-%   \SpecialUsageIndex{\Qm}\relax
-%   \SpecialUsageIndex{\Qs}\relax
-%   \SpecialUsageIndex{\Wt}\relax
-%   \SpecialUsageIndex{\Wm}\relax
-%   \SpecialUsageIndex{\Ws}\relax
-%   \SpecialUsageIndex{\Et}\relax
-%   \SpecialUsageIndex{\Em}\relax
-%   \SpecialUsageIndex{\Es}\relax
-%   \SpecialUsageIndex{\Epm}\relax
-%   \SpecialUsageIndex{\Ut}\relax
-%   \SpecialUsageIndex{\Um}\relax
-%   \SpecialUsageIndex{\Us}\relax
-%   \SpecialUsageIndex{\Upm}\relax
-%   \SpecialUsageIndex{\Ht}\relax
-%   \SpecialUsageIndex{\Hm}\relax
-%   \SpecialUsageIndex{\Hs}\relax
-%   \SpecialUsageIndex{\Hpm}\relax
-%   \SpecialUsageIndex{\St}\relax
-%   \SpecialUsageIndex{\Sm}\relax
-%   \SpecialUsageIndex{\Ss}\relax
-%   \SpecialUsageIndex{\Spm}\relax
-%   \SpecialUsageIndex{\Ft}\relax
-%   \SpecialUsageIndex{\Fm}\relax
-%   \SpecialUsageIndex{\Fs}\relax
-%   \SpecialUsageIndex{\Fpm}\relax
-%   \SpecialUsageIndex{\Gt}\relax
-%   \SpecialUsageIndex{\Gm}\relax
-%   \SpecialUsageIndex{\Gs}\relax
-%   \SpecialUsageIndex{\Gpm}\relax
-%   \SpecialUsageIndex{\At}\relax
-%   \SpecialUsageIndex{\Am}\relax
-%   \SpecialUsageIndex{\As}\relax
-%   \SpecialUsageIndex{\Apm}\relax
-%   \SpecialUsageIndex{\Nt}\relax
-%   \SpecialUsageIndex{\Lt}\relax
-%   \SpecialUsageIndex{\Lm}\relax
-%   \SpecialUsageIndex{\Ls}\relax
-%   \SpecialUsageIndex{\Lpm}\relax
-%   \SpecialUsageIndex{\Bt}\relax
-%   \SpecialUsageIndex{\Bm}\relax
-%   \SpecialUsageIndex{\Bs}\relax
-%   \SpecialUsageIndex{\Bpm}\relax
-%   \SpecialUsageIndex{\Mt}\relax
-%   \SpecialUsageIndex{\Mm}\relax
-%   \SpecialUsageIndex{\Ms}\relax
-%   \SpecialUsageIndex{\Mpm}\relax
+%^^A TODO The \leavevmode macro here is to prevent whitespace from building
+%^^A      up due to a bug in old versions of hypdoc. It should be harmless to
+%^^A      leave it in there, but consider removing it at some point.
+%   \leavevmode
+%   \SpecialMacroIndex{\Qt}\relax
+%   \SpecialMacroIndex{\Qm}\relax
+%   \SpecialMacroIndex{\Qs}\relax
+%   \SpecialMacroIndex{\Wt}\relax
+%   \SpecialMacroIndex{\Wm}\relax
+%   \SpecialMacroIndex{\Ws}\relax
+%   \SpecialMacroIndex{\Et}\relax
+%   \SpecialMacroIndex{\Em}\relax
+%   \SpecialMacroIndex{\Es}\relax
+%   \SpecialMacroIndex{\Epm}\relax
+%   \SpecialMacroIndex{\EEt}\relax
+%   \SpecialMacroIndex{\EE}\relax
+%   \SpecialMacroIndex{\EEs}\relax
+%   \SpecialMacroIndex{\EEpm}\relax
+%   \SpecialMacroIndex{\ERt}\relax
+%   \SpecialMacroIndex{\ER}\relax
+%   \SpecialMacroIndex{\ERs}\relax
+%   \SpecialMacroIndex{\ERpm}\relax
+%   \SpecialMacroIndex{\Ut}\relax
+%   \SpecialMacroIndex{\Um}\relax
+%   \SpecialMacroIndex{\Us}\relax
+%   \SpecialMacroIndex{\Upm}\relax
+%   \SpecialMacroIndex{\UEt}\relax
+%   \SpecialMacroIndex{\UE}\relax
+%   \SpecialMacroIndex{\UEs}\relax
+%   \SpecialMacroIndex{\UEpm}\relax
+%   \SpecialMacroIndex{\URt}\relax
+%   \SpecialMacroIndex{\UR}\relax
+%   \SpecialMacroIndex{\URs}\relax
+%   \SpecialMacroIndex{\URpm}\relax
+%   \SpecialMacroIndex{\Ht}\relax
+%   \SpecialMacroIndex{\Hm}\relax
+%   \SpecialMacroIndex{\Hs}\relax
+%   \SpecialMacroIndex{\Hpm}\relax
+%   \SpecialMacroIndex{\HEt}\relax
+%   \SpecialMacroIndex{\HE}\relax
+%   \SpecialMacroIndex{\HEs}\relax
+%   \SpecialMacroIndex{\HEpm}\relax
+%   \SpecialMacroIndex{\HRt}\relax
+%   \SpecialMacroIndex{\HR}\relax
+%   \SpecialMacroIndex{\HRs}\relax
+%   \SpecialMacroIndex{\HRpm}\relax
+%   \SpecialMacroIndex{\St}\relax
+%   \SpecialMacroIndex{\Sm}\relax
+%   \SpecialMacroIndex{\Ss}\relax
+%   \SpecialMacroIndex{\Spm}\relax
+%   \SpecialMacroIndex{\SEt}\relax
+%   \SpecialMacroIndex{\SE}\relax
+%   \SpecialMacroIndex{\SEs}\relax
+%   \SpecialMacroIndex{\SEpm}\relax
+%   \SpecialMacroIndex{\SRt}\relax
+%   \SpecialMacroIndex{\SR}\relax
+%   \SpecialMacroIndex{\SRs}\relax
+%   \SpecialMacroIndex{\SRpm}\relax
+%   \SpecialMacroIndex{\Ft}\relax
+%   \SpecialMacroIndex{\Fm}\relax
+%   \SpecialMacroIndex{\Fs}\relax
+%   \SpecialMacroIndex{\Fpm}\relax
+%   \SpecialMacroIndex{\FEt}\relax
+%   \SpecialMacroIndex{\FE}\relax
+%   \SpecialMacroIndex{\FEs}\relax
+%   \SpecialMacroIndex{\FEpm}\relax
+%   \SpecialMacroIndex{\FRt}\relax
+%   \SpecialMacroIndex{\FR}\relax
+%   \SpecialMacroIndex{\FRs}\relax
+%   \SpecialMacroIndex{\FRpm}\relax
+%   \SpecialMacroIndex{\Gt}\relax
+%   \SpecialMacroIndex{\Gm}\relax
+%   \SpecialMacroIndex{\Gs}\relax
+%   \SpecialMacroIndex{\Gpm}\relax
+%   \SpecialMacroIndex{\GEt}\relax
+%   \SpecialMacroIndex{\GE}\relax
+%   \SpecialMacroIndex{\GEs}\relax
+%   \SpecialMacroIndex{\GEpm}\relax
+%   \SpecialMacroIndex{\GRt}\relax
+%   \SpecialMacroIndex{\GR}\relax
+%   \SpecialMacroIndex{\GRs}\relax
+%   \SpecialMacroIndex{\GRpm}\relax
+%   \SpecialMacroIndex{\At}\relax
+%   \SpecialMacroIndex{\Am}\relax
+%   \SpecialMacroIndex{\As}\relax
+%   \SpecialMacroIndex{\Apm}\relax
+%   \SpecialMacroIndex{\Nt}\relax
+%   \SpecialMacroIndex{\Lt}\relax
+%   \SpecialMacroIndex{\Lm}\relax
+%   \SpecialMacroIndex{\Ls}\relax
+%   \SpecialMacroIndex{\Lpm}\relax
+%   \SpecialMacroIndex{\LEt}\relax
+%   \SpecialMacroIndex{\LE}\relax
+%   \SpecialMacroIndex{\LEs}\relax
+%   \SpecialMacroIndex{\LEpm}\relax
+%   \SpecialMacroIndex{\LRt}\relax
+%   \SpecialMacroIndex{\LR}\relax
+%   \SpecialMacroIndex{\LRs}\relax
+%   \SpecialMacroIndex{\LRpm}\relax
 %   \centering
-%   \begin{minipage}{4.12in}\renewcommand*{\footnoterule}{\vskip-1ex}%
-%   \centering\small
-%   \begin{tabular}{l l l l l}
+%   \begin{minipage}{\linewidth}\renewcommand*{\footnoterule}{\vskip-1.75ex}%
+%   \centering\scriptsize\setlength{\tabcolsep}{0.05in}
+%   \begin{tabular}{l l l l l l l l l l l l l}
 %   \toprule
-%     Property & Total & Molar & Specific & Partial Molar \\
+%     & & & & & \multicolumn{4}{c}{Excess}
+%       & \multicolumn{4}{c}{Residual (Departure)} \\
+%   \cmidrule(r{0.5ex}){6-9}
+%   \cmidrule(l{0.5ex}){10-13}
+%     Property & Total & Molar & Specific & \parbox[b]{0.45in}{Partial Molar}
+%     & T & M & S & PM & T & M & S & PM \\
 %   \midrule
-%     Heat            & \cs{Qt} & \cs{Qm} & \cs{Qs} & N/A \\
-%     Work            & \cs{Wt} & \cs{Wm} & \cs{Ws} & N/A \\
-%     Total energy    & \cs{Et} & \cs{Em} & \cs{Es} & \cs{Epm} \\
-%     Internal energy & \cs{Ut} & \cs{Um} & \cs{Us} & \cs{Upm} \\
-%     Enthalpy        & \cs{Ht} & \cs{Hm} & \cs{Hs} & \cs{Hpm} \\
-%     Entropy         & \cs{St} & \cs{Sm} & \cs{Ss} & \cs{Spm} \\
-%     Volume          & \cs{Vt} & \cs{Vm} & \cs{Vs} & \cs{Vpm} \\
-%     Helmholtz free energy & \cs{Ft} & \cs{Fm} & \cs{Fs} & \cs{Fpm} \\
-%     Gibbs free energy & \cs{Gt} & \cs{Gm} & \cs{Gs} & \cs{Gpm} \\
+%     Heat            & \cs{Qt}  & \cs{Qm} & \cs{Qs}  & \\
+%     Work            & \cs{Wt}  & \cs{Wm} & \cs{Ws}  & \\
+%     Total energy    & \cs{Et}  & \cs{Em} & \cs{Es}  & \cs{Epm}
+%                     & \cs{EEt} & \cs{EE} & \cs{EEs} & \cs{EEpm}
+%                     & \cs{ERt} & \cs{ER} & \cs{ERs} & \cs{ERpm} \\
+%     Internal energy & \cs{Ut} & \cs{Um} & \cs{Us} & \cs{Upm}
+%                     & \cs{UEt} & \cs{UE} & \cs{UEs} & \cs{UEpm}
+%                     & \cs{URt} & \cs{UR} & \cs{URs} & \cs{URpm} \\
+%     Enthalpy        & \cs{Ht} & \cs{Hm} & \cs{Hs} & \cs{Hpm}
+%                     & \cs{HEt} & \cs{HE} & \cs{HEs} & \cs{HEpm}
+%                     & \cs{HRt} & \cs{HR} & \cs{HRs} & \cs{HRpm} \\
+%     Entropy         & \cs{St} & \cs{Sm} & \cs{Ss} & \cs{Spm}
+%                     & \cs{SEt} & \cs{SE} & \cs{SEs} & \cs{SEpm} 
+%                     & \cs{SRt} & \cs{SR} & \cs{SRs} & \cs{SRpm} \\
+%     Volume          & \cs{Vt} & \cs{Vm} & \cs{Vs} & \cs{Vpm}
+%                     & \cs{VEt} & \cs{VE} & \cs{VEs} & \cs{VEpm}
+%                     & \cs{VRt} & \cs{VR} & \cs{VRs} & \cs{VRpm} \\
+%     Helmholtz free energy & \cs{Ft} & \cs{Fm} & \cs{Fs} & \cs{Fpm}
+%                     & \cs{FEt} & \cs{FE} & \cs{FEs} & \cs{FEpm}
+%                     & \cs{FRt} & \cs{FR} & \cs{FRs} & \cs{FRpm} \\
+%     Gibbs free energy & \cs{Gt} & \cs{Gm} & \cs{Gs} & \cs{Gpm}
+%                     & \cs{GEt} & \cs{GE} & \cs{GEs} & \cs{GEpm}
+%                     & \cs{GRt} & \cs{GR} & \cs{GRs} & \cs{GRpm} \\
 %     Surface area    & \cs{At} & \cs{Am} & \cs{As} & \cs{Apm} \\
 %     Grand potential\footnote{The grand potential,
-%       $\Lt(T,\Vt,\vec{\mu}\mkern1mu) = \Ut - T\St - \sum_i^C \mu_i \Nt_i,$
+%       $\begin{thermomolesrange}\Lt(T,\Vt,\allmus)\end{thermomolesrange}
+%           = \Ut - T\St - \sumall_i \mu_i \Nt_i,$
 %       is also called the Landau free energy by some authors.}
-%                  & \cs{Lt} & \cs{Lm} & \cs{Ls} & \cs{Lpm} \\
-%     Moles           & \cs{Nt} & N/A & N/A & N/A \\
-%     $B$ (generic property) & \cs{Bt} & \cs{Bm} & \cs{Bs} & \cs{Bpm} \\
-%     $M$ (generic property) & \cs{Mt} & \cs{Mm} & \cs{Ms} & \cs{Mpm} \\
+%                     & \cs{Lt} & \cs{Lm} & \cs{Ls} & \cs{Lpm}
+%                     & \cs{LEt} & \cs{LE} & \cs{LEs} & \cs{LEpm}
+%                     & \cs{LRt} & \cs{LR} & \cs{LRs} & \cs{LRpm} \\
+%     Moles           & \cs{Nt} & \\
 %   \bottomrule
 %   \end{tabular}
 %   \end{minipage}
@@ -383,46 +452,52 @@
 %   \caption{Convenience macros and their default symbols.
 %       These are generally ``smart'': for example,
 %       \texttt{\textbackslash cP\_i} renders as $C_{P,i}$, as expected, and
-%       \texttt{\textbackslash cP\_i\^{}\textbackslash circ} renders as
+%       \texttt{\textbackslash cP\_i\^{}\textbackslash std} renders as
 %       $C_{P,i}^\circ$, also as expected. You can also reverse it:
-%       \texttt{\textbackslash cP\^{}\textbackslash circ\_i} becomes
+%       \texttt{\textbackslash cP\^{}\textbackslash std\_i} becomes
 %       $C^\circ_{P,i}$.}
 %   \label{table:conveniences}
-%   \SpecialUsageIndex{\cP}\relax
-%   \SpecialUsageIndex{\cV}\relax
-%   \SpecialUsageIndex{\kappaT}\relax
-%   \SpecialUsageIndex{\kappaS}\relax
-%   \SpecialUsageIndex{\alphaP}\relax
-%   \SpecialUsageIndex{\alphaS}\relax
-%   \SpecialUsageIndex{\heatcapacitysymbol}\relax
-%   \SpecialUsageIndex{\compressibilitysymbol}\relax
-%   \SpecialUsageIndex{\expansivitysymbol}\relax
-%   \SpecialUsageIndex{\fpure}\relax
-%   \SpecialUsageIndex{\fmix}\relax
-%   \SpecialUsageIndex{\fsat}\relax
-%   \SpecialUsageIndex{\phipure}\relax
-%   \SpecialUsageIndex{\phimix}\relax
-%   \SpecialUsageIndex{\phisat}\relax
-%   \SpecialUsageIndex{\Psat}\relax
-%   \SpecialUsageIndex{\Pvap}\relax
-%   \SpecialUsageIndex{\sat}\relax
-%   \SpecialUsageIndex{\Henryrat}\relax
-%   \SpecialUsageIndex{\Henrymol}\relax
-%   \SpecialUsageIndex{\gammarat}\relax
-%   \SpecialUsageIndex{\gammamol}\relax
-%   \SpecialUsageIndex{\Deltamix}\relax
-%   \SpecialUsageIndex{\Deltarxn}\relax
-%   \SpecialUsageIndex{\Deltavap}\relax
-%   \SpecialUsageIndex{\Deltasub}\relax
-%   \SpecialUsageIndex{\Deltafus}\relax
-%   \SpecialUsageIndex{\mixing}\relax
-%   \SpecialUsageIndex{\reaction}\relax
-%   \SpecialUsageIndex{\fusion}\relax
-%   \SpecialUsageIndex{\vaporization}\relax
-%   \SpecialUsageIndex{\sublimation}\relax
+%^^A TODO The \leavevmode macro here is to prevent whitespace from building
+%^^A      up due to a bug in old versions of hypdoc. It should be harmless to
+%^^A      leave it in there, but consider removing it at some point.
+%   \leavevmode
+%   \SpecialMacroIndex{\cP}\relax
+%   \SpecialMacroIndex{\cV}\relax
+%   \SpecialMacroIndex{\kappaT}\relax
+%   \SpecialMacroIndex{\kappaS}\relax
+%   \SpecialMacroIndex{\alphaP}\relax
+%   \SpecialMacroIndex{\alphaS}\relax
+%   \SpecialMacroIndex{\muJT}\relax
+%   \SpecialMacroIndex{\heatcapacitysymbol}\relax
+%   \SpecialMacroIndex{\compressibilitysymbol}\relax
+%   \SpecialMacroIndex{\expansivitysymbol}\relax
+%   \SpecialMacroIndex{\amix}\relax
+%   \SpecialMacroIndex{\fpure}\relax
+%   \SpecialMacroIndex{\fmix}\relax
+%   \SpecialMacroIndex{\fsat}\relax
+%   \SpecialMacroIndex{\phipure}\relax
+%   \SpecialMacroIndex{\phimix}\relax
+%   \SpecialMacroIndex{\phisat}\relax
+%   \SpecialMacroIndex{\Psat}\relax
+%   \SpecialMacroIndex{\Pvap}\relax
+%   \SpecialMacroIndex{\sat}\relax
+%   \SpecialMacroIndex{\Henryrat}\relax
+%   \SpecialMacroIndex{\Henrymol}\relax
+%   \SpecialMacroIndex{\gammarat}\relax
+%   \SpecialMacroIndex{\gammamol}\relax
+%   \SpecialMacroIndex{\Deltamix}\relax
+%   \SpecialMacroIndex{\Deltarxn}\relax
+%   \SpecialMacroIndex{\Deltavap}\relax
+%   \SpecialMacroIndex{\Deltasub}\relax
+%   \SpecialMacroIndex{\Deltafus}\relax
+%   \SpecialMacroIndex{\mixing}\relax
+%   \SpecialMacroIndex{\reaction}\relax
+%   \SpecialMacroIndex{\fusion}\relax
+%   \SpecialMacroIndex{\vaporization}\relax
+%   \SpecialMacroIndex{\sublimation}\relax
 %   \begin{minipage}{\linewidth}
 %   \small
-%   \addtolength{\tabcolsep}{-2pt}\relax
+%   \addtolength{\tabcolsep}{-2.75pt}\relax
 %   \addtolength{\extrarowheight}{0.75ex}\relax
 %   \renewcommand*{\footnoterule}{\vskip-1.5ex}\relax
 %   \begin{tabular}{l l l l l}
@@ -430,76 +505,78 @@
 %   \\[-1.5\normalbaselineskip]
 %     Name & Macro & Sym. & Definition & Base Symbol Macro \\
 %   \midrule
-%     Isobaric heat capacity & \verb"\cP"\footnote{\relax
+%     Isobaric heat capacity & \cmd\cP\footnote{\relax
 %         Extensive and specific (per-unit-mass) versions are available
-%         as \texttt{\textbackslash cPt} and \texttt{\textbackslash cPs},
-%         respectively, with similar macros for the isochoric heat capacity.
-%         \label{fn:cP}}
-%     & $C_P$ & $\displaystyle T\left(\frac{\partial S}{\partial T}\right)_P$
-%     & \verb"\heatcapacitysymbol" \\[2.0ex]
-%     Isochoric heat capacity & \verb"\cV"\footref{fn:cP} & $C_V$
-%     & $\displaystyle T\left(\frac{\partial S}{\partial T}\right)_V$
-%     & \verb"\heatcapacitysymbol" \\[2.0ex]
-%     Isothermal compressibility & \verb"\kappaT" & $\kappa_T$ &
-% \(\displaystyle -\frac{1}{V} \left(\frac{\partial V}{\partial P}\right)_T \)
-%       & \verb"\compressibilitysymbol" \\[2.0ex]
-%     Isentropic compressibility & \verb"\kappaS" & $\kappa_S$ &
-% \(\displaystyle -\frac{1}{V} \left(\frac{\partial V}{\partial P}\right)_S\)
-%       & \verb"\compressibilitysymbol" \\[2.0ex]
-%     Isobaric expansivity & \verb"\alphaP" & $\alpha_P$ &
-% \(\displaystyle \frac{1}{V} \left(\frac{\partial V}{\partial T}\right)_P\)
-%       & \verb"\expansivitysymbol" \\[2.0ex]
-%     Isentropic expansivity & \verb"\alphaS" & $\alpha_S$ &
-% \(\displaystyle \frac{1}{V} \left(\frac{\partial V}{\partial T}\right)_S\)
-%       & \verb"\expansivitysymbol" \\[2.0ex]
-%     Pure fugacity & \verb"\fpure" & $f$ & $\phi P$ \\
-%     Mixture fugacity & \verb"\fmix" & $\hat f$ & $\hat f_i = x_i\hat\phi_i P$ \\[0.5ex]
-%     Saturation fugacity & \verb"\fsat" & $f^\text{sat}$
-%       & $\phi^\text{sat} P^\text{sat}$ & \cs{sat} \\
-%     Pure fugacity coeff.\ & \verb"\phipure" & $\phi$ &
-%       \multicolumn{2}{l}{\( \phi_i
-%         = \exp\left(\frac{1}{RT}\int_0^P V_i(T,p)
+%         as \cs{cPt} and \cmd\cPs, respectively, with similar macros for the
+%         isochoric heat capacity.\label{fn:cP}}
+%     & \(cP\) & \(\displaystyle T\Partial{\Sm}{T}{P}\)
+%     & \cmd\heatcapacitysymbol \\[2.0ex]
+%     Isochoric heat capacity & \verb"\cV"\footref{fn:cP} & \(\cV\)
+%     & \(\displaystyle T\Partial{\Sm}{T}{\Vm}\)
+%     & \cmd\heatcapacitysymbol \\[2.0ex]
+%     Isothermal compressibility & \cmd\kappaT & $\kappaT$
+%       & \(\displaystyle -\frac{1}{\Vm} \Partial{\Vm}{P}{T} \)
+%       & \cmd\compressibilitysymbol \\[2.0ex]
+%     Isentropic compressibility & \cmd\kappaS & $\kappaS$
+%       & \(\displaystyle -\frac{1}{\Vm} \Partial{\Vm}{P}{\Sm}\)
+%       & \cmd\compressibilitysymbol \\[2.0ex]
+%     Isobaric expansivity & \cmd\alphaP & $\alphaP$
+%       & \(\displaystyle \frac{1}{\Vm} \Partial{\Vm}{T}{P}\)
+%       & \cmd\expansivitysymbol \\[2.0ex]
+%     Isentropic expansivity & \cmd\alphaS & $\alphaS$
+%       & \(\displaystyle \frac{1}{\Vm} \Partial{\Vm}{T}{\Sm}\)
+%       & \cmd\expansivitysymbol \\[2.0ex]
+%     Joule--Thomson coeff. & \cmd\muJT & $\muJT$
+%       & \(\displaystyle \Partial{T}{P}{\Hm}\) & \cmd\JTsymbol \\
+%     Pure fugacity & \cmd\fpure & $f$ & $\phi P$ \\
+%     Mixture fugacity & \cmd\fmix & $\fmix$
+%       & $\fmix_i = x_i\phimix_i P$ \\[0.5ex]
+%     Saturation fugacity & \cmd\fsat & $\fsat$
+%       & $\phisat \Psat$ & \cmd\sat \\
+%     Pure fugacity coefficient & \cmd\phipure & $\phipure$ &
+%       \multicolumn{2}{l}{\( \phipure_i
+%         = \exp\left(\frac{1}{RT}\int_0^P \Vm_i(T,p)
 %               - \frac{RT}{p}\,dp\right) \)} \\
-%     Mixture fugacity coeff.\ & \verb"\phimix" & $\hat\phi$
-%       & \multicolumn{2}{l}{\( \hat\phi_i
+%     Mixture fugacity coeff.\ & \cmd\phimix & $\phimix$
+%       & \multicolumn{2}{l}{\( \phimix_i
 %          = \exp\left(\frac{1}{RT}\int_0^P \Vpm{i}(T,p,\allXs)
 %                - \frac{RT}{p}\,dp\right) \)} \\
-%     Henry's constant (rational) & \verb"\Henryrat" & $h$
+%     Henry's constant (rational) & \cmd\Henryrat & $\Henryrat$
 %       & $\gamma_i^\infty f_i$ \\
-%     Henry's constant (molal) & \verb"\Henrymol" & $\mathcal{H}$ 
+%     Henry's constant (molal) & \cmd\Henrymol & $\Henrymol$ 
 %       & $M_s \gamma_i^\infty f_i$ \\
-%     Rational activity coeff.\ & \verb"\gammarat" & $\gamma^\ast$
+%     Rational activity coeff.\ & \cmd\gammarat & $\gammarat$
 %       & $\gamma/\gamma^\infty$ \\
-%     Molal activity coeff.\ & \verb"\gammamol" & $\gamma^\square$
+%     Molal activity coeff.\ & \cmd\gammamol & $\gammamol$
 %       & $x_s \gamma/\gamma^\infty$ \\
-%     Saturation fugacity coeff.\ & \verb"\phisat" & $\phi^\text{sat}$
-%       & $\phi(T,P^\text{sat})$ & \cs{sat} \\
-%     Saturation pressure & \verb"\Psat" & $P^\text{sat}$ && \cs{sat} \\
-%     Vapor pressure & \verb"\Pvap" & \multicolumn{3}{l}{Currently a synonym
+%     Saturation fugacity coeff.\ & \cmd\phisat & $\phisat$
+%       & $\phipure(T,\Psat)$ & \cmd\sat \\
+%     Saturation pressure & \cmd\Psat & $\Psat$ && \cmd\sat \\
+%     Vapor pressure & \cmd\Pvap & \multicolumn{3}{l}{Currently a synonym
 %       for \cs{Psat}\footnote{If you want \cs{Pvap} to produce $P^\text{vap}$
-%       instead of $P^\text{sat}$, you should redefine the \cs{sat} macro.}} \\
-%     Standard state & \verb"\std"\footnote{Typical usage would be
+%       instead of $\Psat$, you should redefine the \cs{sat} macro.}} \\
+%     Standard state & \cmd\std\footnote{Typical usage would be
 %       \texttt{\$\cs{mu}\_i = \cs{mu}\textasciicircum\cs{std}\_i
 %         + RT \cs{log} a\_i\$},
-%       yielding $\mu_i = \mu_i^\circ + RT \log a_i$.} & $\circ$ \\
-%     Standard pressure & \verb"\Pstd" & $P^\circ$ & & \cs{std} \\
-%     Standard fugacity & \verb"\fstd" & $f^\circ$ & $f(T,P^\circ)$ & \cs{std}
+%       yielding $\mu_i = \mu_i^\std + RT \log a_i$.} & $\std$ \\
+%     Standard pressure & \cmd\Pstd & $\Pstd$ & & \cs{std} \\
+%     Standard fugacity & \cmd\fstd & $\fstd$ & $\fpure(T,\Pstd)$ & \cs{std}
 %     \\
-%     Change on mixing & \verb"\Deltamix"\footnote{The usual usage would be
+%     Change on mixing & \cmd\Deltamix\footnote{The usual usage would be
 %         something like
 %         \texttt{\$\cs{Deltamix}\cs{Vm}\textasciicircum\cs{IGM} = 0\$}.\relax
 %       \label{fn:Deltausage}}
 %       & $\Delta M$\textsubscript{mix}
-%       & $M - \sum_i x_i M_i$ & \verb"\mixing" \\
-%     Change on reaction & \verb"\Deltarxn"\footref{fn:Deltausage}
-%       & $\Delta M_\text{rxn}$
-%       & $\sum_i \nu_i M_i$ & \verb"\reaction" \\
-%     Change on melting & \verb"\Deltafus"\footref{fn:Deltausage}
-%       & $\Delta M^\text{fus}$ & $M^L - M^S$ & \verb"\fusion" \\
-%     Change on boiling & \verb"\Deltavap"\footref{fn:Deltausage}
-%       & $\Delta M^\text{vap}$ & $M^V - M^L$ & \verb"\vaporization" \\
-%     Change on subliming & \verb"\Deltasub"\footref{fn:Deltausage}
-%       & $\Delta M^\text{sub}$ & $M^V - M^S$ & \verb"\sublimation" \\
+%       & $M - \sumall_i x_i M_i$ & \cmd\mixing \\
+%     Change on reaction & \cmd\Deltarxn\footref{fn:Deltausage}
+%       & $\Deltarxn M$
+%       & $\sumall_i \nu_i M_i$ & \cmd\reaction \\
+%     Change on melting & \cmd\Deltafus\footref{fn:Deltausage}
+%       & $\Deltafus M$ & $M^L - M^S$ & \cmd\fusion \\
+%     Change on boiling & \cmd\Deltavap\footref{fn:Deltausage}
+%       & $\Deltavap M$ & $M^V - M^L$ & \cmd\vaporization \\
+%     Change on subliming & \cmd\Deltasub\footref{fn:Deltausage}
+%       & $\Deltasub M$ & $M^V - M^S$ & \cmd\sublimation \\
 %   \bottomrule
 %   \end{tabular}
 %   \end{minipage}
@@ -507,19 +584,19 @@
 %
 % \subsection{Partial Molar Properties}
 % \DescribeMacro{\Upm}
-% \DescribeMacro{\Hpm}
-% Partial molar quantities are typically defined with the suffix \verb"pm".
+% \DescribeMacro{\Vpm}
+% Partial molar quantities are defined with the suffix \verb"pm".
 % For example, \cs{Upm} refers to the partial molar internal energy. There
 % are two options for how to enter partial molar quantities: as commands or
 % as super/subscripts. For example,
 % \begin{verbatim}
-%  \[ \Upm{i} \quad \Upm[\IG]{i} \quad \Hpm_i \quad \Hpm^\IG_i \]
+%  \[ \Upm{i} \quad \Upm[\IG]{i} \quad \Vpm_i \quad \Vpm^\IG_i \]
 %\end{verbatim}
 % will typeset as
-%  \[ \Upm{i} \quad \Upm[\text{IG}]{i} \quad \Hpm{i} \quad \Hpm[\text{IG}]{i}\]
-% There are also partial molar heat capacities available via \cs{cPpm} and
-% \cs{cVpm}.
-% \textbf{Important}: The \cs{text} command defined by the \verb"amstext"
+% \[ \Upm{i} \quad \Upm[\text{IG}]{i} \quad \Vpm{i} \quad \Vpm^{\text{IG}}_i.\]
+% There are also partial molar heat capacities available via the macros
+%  \cs{cPpm} and \cs{cVpm}.
+% \textbf{Important}: The \tn{text} command defined by the \pkg{amstext}
 % package is usually robust enough that something like \verb"\Um^\text{L}" will
 % work as expected, without additional braces. This does \emph{not} work for
 % partial molar properties; for example, \verb"\Hpm^\text{L}_i" will produce an
@@ -530,15 +607,63 @@
 % New partial molar properties can be defined for any ``simple'' symbol using
 % the \cs{partialmolar} macro. ``Simple'' means it has no subscripts or
 % superscripts. For example, the macro for the partial molar Gibbs free energy
-% is defined via the macro
+% is effectively defined via the macro
 % \DescribeMacro{\Gpm}
 % \begin{verbatim}
-%   \newcommand*{\Gpm}{\partialmolar{\Gibbs at symbol}}
+%   \NewDocumentCommand{\Gpm}{}{\partialmolar{G}}.
 %\end{verbatim}
 % A list of pre-defined macros for total, molar, specific, and partial molar
 % quantities commonly used in thermodynamics is included in
 % Table~\ref{table:symbols}.
 %
+% \subsection{Defining New Properties}
+% \DescribeMacro{\NewExtensiveProperty}
+% Users can create new properties using a family of commands. Typically, a
+% user would want to define at least the total, molar, and specific properties,
+% which can be accomplished by the \cs{NewExtensiveProperty} command.
+% For example,
+% \begin{verbatim}
+%  \NewExtensiveProperty{J}{K}
+%\end{verbatim}
+% \NewExtensiveProperty{J}{K}\relax
+% would define the commands \cs{Jt}, \cs{Jm}, and \cs{Js}, which would produce
+% (using the default package options) the symbols $\Jt$, $K$, and $\hat{K}$,
+% respectively.
+%
+% \DescribeMacro{\NewPartialMolarProperty}%
+% Partial molar properties can be created either with the \cs{partialmolar}
+% macro directly as described above or with \cs{NewPartialMolarProperty}, which
+% has the same argument style as \cs{NewExtensiveProperty}.
+%
+% \DescribeMacro{\NewExcessProperty}%
+% \DescribeMacro{\NewResidualProperty}%
+% Similarly, one can define commands for the total, molar, and specific excess
+% properties using \cs{NewExcessProperty} in a similar manner, and similar
+% commands for the residual properties with \cs{NewResidualProperty}.
+%
+% \setmarginparsize{\footnotesize}
+% \DescribeMacro{\NewThermodynamicProperty}\relax
+% \restoremarginparsize
+% \NewThermodynamicProperty{B}{B}\relax
+% \NewExtensiveProperty{M}{M}\relax
+% It is common that a user wants the total, molar, specific, and partial molar
+% commands for a new symbol, as well as excess and residual (departure)
+% properties for each case.  Users can define such properties---common examples
+% are $\Bt$ and $\Mt$ to represent uncommon or arbitrary properties---by using
+% \cs{NewThermodynamicProperty}, which calls all four of the aforementioned
+% declarations on the same command/\allowbreak{}symbol combinations. For
+% example,
+% \begin{verbatim}
+%  \NewThermodynamicProperty{B}{B}
+%\end{verbatim}
+% defines the commands \cs{Bt}, \cs{Bm}, \cs{Bs}, and \cs{Bpm}, which define
+% the total, molar, specific, and partial molar properties, respectively.
+% It also defines \cs{BEt}, \cs{BE}, \cs{BEs}, and \cs{BEpm} for the
+% corresponding excess properties, and \cs{BRt}, \cs{BR}, \cs{BRs}, and
+% \cs{BRpm} for residual (departure) properties. These produce, respectively,
+% $\Bt, \Bm, \Bs, \Bpm{i}, \BEt, \BE, \BEs, \BEpm{i}, \BRt, \BR, \BRs,$ and
+% $\BRpm{i}$ using the defaults.
+%
 % \subsection{Other Predefined Symbols and Modifiers}
 % There are a number of predefined symbols and modifiers.
 % While these symbols could be defined or used without these macros, such use
@@ -562,12 +687,20 @@
 % \cs{expansivitysymbol}, which is done automatically by some of the
 % package options that create notation specific to a particular textbook.
 %
+% \subsubsection{Joule--Thomson Coefficients}
+% \changes{v2.00}{2023/11/16}{Added \cs{muJT} to represent Joule--Thomson
+%   coefficients (which have different notation across textbooks).}
+% \DescribeMacro{\muJT}
+% The Joule--Thomson coefficient is produced with \cs{muJT}, which be default
+% is rendered $\muJT$. Some books call this coefficient $\alpha_H$; this is
+% handled automatically for books of which the package author is aware.
+%
 % \subsubsection{Fugacities and Fugacity Coefficients}
 % \DescribeMacro{\fpure}
 % \DescribeMacro{\fmix}
 % \DescribeMacro{\phipure}
 % \DescribeMacro{\phimix}
-% Different textbooks use different modifications of the symbol $f$ for
+% Different textbooks use different variations on the symbol $f$ for
 % fugacity, so it is recommended to use the macro \cs{fpure} to denote the
 % pure-component fugacity and \cs{fmix} to denote the mixture fugacity.
 % Similarly, the pure-component fugacity coefficient should be generated with
@@ -576,16 +709,21 @@
 % For example, the following markup is an example of a common equation in
 % mixture thermodynamics:
 % \begin{verbatim}
-%   \[ \fmix_j = x_j \phimix_j P = x_j \gamma_j \fpure_j. \]
+%   \[ \fmix_j = x_j \phimix_j P = x_j \gamma_j \fpure_j
+%       = x_j \gamma_j \phipure_j P. \]
 %\end{verbatim}
 % With the default package options, this produces
-%   \[ \hat f_j = x_j \hat\phi_j P = x_j \gamma_j f_j. \]
+%   \[ \fmix_j = x_j \phimix_j P = x_j \gamma_j \fpure_j
+%       = x_j \gamma_j \phipure_j P. \]
 % With the |Thompson| package option, however, the same markup produces
-%   \[ \hat f_j = x_j \hat\phi_j P = x_j \gamma_j f^\bullet_j. \]
+%   \[ \hat f_j = x_j \hat\phi_j P = x_j \gamma_j f^\bullet_j
+%       = x_j \gamma_j \phi^\bullet_j P. \]
 % Similarly, the |Prausnitz| package option causes it to generate
-%   \[ f_j = x_j \phi_j P = x_j \gamma_j f_{\text{pure},j}, \]
+%   \[ f_j = x_j \phi_j P = x_j \gamma_j f_{\text{pure},j}
+%          = x_j \gamma_j \phi_{\text{pure},j} P, \]
 % and the |Sandler| option causes it to generate
-%   \[ \bar f_j = x_j \bar \phi_j P = x_j \gamma_j f_j. \]
+%   \[ \bar f_j = x_j \bar \phi_j P = x_j \gamma_j f_j
+%          = x_j \gamma_j \phi_j  P. \]
 %
 % \subsubsection{Activity Coefficients and Henry's Constants}
 % \DescribeMacro{\gammarat}
@@ -592,9 +730,9 @@
 % \DescribeMacro{\gammamol}
 % \DescribeMacro{\Henryrat}
 % \DescribeMacro{\Henrymol}
-% The activity coefficient can be generated with \cs{gamma}, as usual.
-% The Henry's Law activity coefficients should be produced with \cs{gammarat}
-% (rational basis) and \cs{gammamol} (molal basis).
+% The activity coefficient based on the Lewis--Randall rule can be generated
+% with \cs{gamma}, as usual. The Henry's Law activity coefficients should be
+% produced with \cs{gammarat} (rational basis) and \cs{gammamol} (molal basis).
 % There are also macros to generate the Henry's law constants for both the
 % rational basis (\cs{Henryrat}) and the molal basis (\cs{Henrymol}).
 % These are interrelated:
@@ -603,10 +741,25 @@
 %            = C_i \gammamol_i \Henrymol_i \]
 %\end{verbatim}
 % produces
-% \[ \hat f_i = x_i \gamma_i f_i = x_i \gamma^*_i h_i
-%             = C_i \gamma^\square_i \mathcal{H}_i \]
+% \[ \fmix_i = x_i \gamma_i \fpure_i = x_i \gammarat_i \Henryrat_i
+%            = C_i \gammamol_i \Henrymol_i \]
 % using the default options.
+% These symbols can be customized either directly or by using package options.
+% For example, the |TesterModell| package option changes the equation
+% above to
+% \[ \hat f_i = x_i \gamma_i f_i = x_i \gamma_i^{**} f_i^{**}
+%   = C_i \gamma_i^* f_i^* \]
+% without any changes in markup.
 %
+% Note that some books (e.g., |ElliottLira|) prefer the atmospheric chemistry
+% convention for the molal basis, namely
+% \[ \fmix_i = x_i \gamma_i \fpure_i = x_i \gammarat_i \Henryrat_i
+%%^^A            = C_i \gammamol_i \Henrymol_i
+%            = C_i \gammamol_i / K_{H,i} \]
+% (that is, using $1/K_{H,i}$ in place of $\Henrymol_i$).
+% Unfortunately, this makes it impossible to change symbols without any edits
+% to markup, so this convention is \emph{not} supported by this package.
+%
 % \subsubsection{Saturation Properties}
 % \DescribeMacro{\Psat}
 % \DescribeMacro{\Pvap}
@@ -620,11 +773,11 @@
 %
 % \DescribeMacro{\sat}
 % The \cs{sat} macro is used ``behind the scenes'' as part of
-% \cs{Psat}, \cs{fsat}, and \cs{phisat}, which produce $P^\text{sat}$,
-% $f^\text{sat}$, and $\phi^\text{sat}$, respectively. If you wanted to
+% \cs{Psat}, \cs{fsat}, and \cs{phisat}, which produce $\Psat$,
+% $\fsat$, and $\phisat$, respectively (using the defaults). If you wanted to
 % redefine them to be $P^\text{vap}$, $f^\text{vap}$, and $\phi^\text{vap}$,
 % you could simply redefine \cs{sat} with
-% \verb"\renewcommand*{\sat}{{\text{vap}}}".
+% \verb"\RenewDocumentCommand{\sat}{}{{\text{vap}}}".
 % This is done automatically using package option |Sandler|.
 %
 % \subsubsection{Standard States}
@@ -635,21 +788,19 @@
 % This is intended to be easy to change should the user want to replace
 % $P^\circ$ with $P^\ominus$, say. This is accessed via the \cs{std} macro.
 % The macro \cs{Pstd} is defined as |P^\std| for convenience to denote
-% standard pressures, and \cs{fstd} is defined for standard fugacities so as to
-% ease implementation across textbooks.
+% standard pressures, and \cs{fstd} is defined for standard fugacities so as
+% to ease implementation across textbooks.
 %
 % The usual usage would be something like this:
 % \begin{verbatim}
 % \[ \Deltarxn\Gm = \sumall_i \nu_i \mu_i = \sumall_i \left[ \nu_i \mu^\std_i
 %    + \nu_i RT \log\left(\frac{\fmix_i}{\fstd_i}\right) \right]
-%    = \Deltarxn\Gm^\std + RT \log\left[\prodall_i a_i^{\nu_i} \right] \]
+%    = \Deltarxn\Gm^\std + RT \log\left[\prodall_i a_i^{\nu_i} \right] \],
 %\end{verbatim}
 % which produces
-% \[ \Delta G_\text{rxn} = \sum_{i=1}^C \nu_i \mu_i
-%   = \sum_{i=1}^C \left[ \nu_i \mu^\circ_i
-%       + \nu_i RT \log\left(\frac{\hat f_i}{f_i^\circ}\right) \right]
-%   = \Delta G^\circ_\text{rxn}
-%       + RT \log\left[\prod_{i=1}^C a_i^{\nu_i} \right] \]
+% \[ \Deltarxn\Gm = \sumall_i \nu_i \mu_i = \sumall_i \left[ \nu_i \mu^\std_i
+%    + \nu_i RT \log\left(\frac{\fmix_i}{\fstd_i}\right) \right]
+%    = \Deltarxn\Gm^\std + RT \log\left[\prodall_i a_i^{\nu_i} \right] \]
 % with the default settings.
 %
 % \subsubsection{Changes on Mixing, Reaction, Fusion, Vaporization, and
@@ -658,11 +809,11 @@
 % Mixing properties are handled via the \cs{Deltamix} macro, and are used as in
 % the following example:
 % \begin{verbatim}
+% \[ \Deltamix\Gm = \Gm - \sumall_i x_i \Gm_i
+%                 = \Deltamix\Hm - T\Deltamix\Sm \],
+%\end{verbatim}
+% which yields, using the default options,
 % \[ \Deltamix\Gm = \Gm - \sumall_i x_i \Gm_i = \Deltamix\Hm - T\Deltamix\Sm \]
-%\end{verbatim}
-% which yields
-% \[ \Delta G_\text{mix} = G - \sum_{i=1}^C x_i G_i
-%     = \Delta H_\text{mix} - T\Delta S_\text{mix}. \]
 % Some textbooks (|Sandler|, |Thompson|) choose to typeset these with the word
 % ``mix'' \emph{before} the symbol, which is handled automatically by this
 % package.
@@ -678,13 +829,15 @@
 % vaporization (boiling), respectively. Their use is straightforward, viz.,
 % \begin{verbatim}
 %  \[ \Deltasub\Hm = \Hm^V - \Hm^S = \Hm^V - \Hm^L + (\Hm^L - \Hm^S)
-%                  = \Deltafus\Hm + \Deltavap\Hm \]
+%                  = \Deltafus\Hm + \Deltavap\Hm \],
 %\end{verbatim}
 % yielding
-%  \[ \Delta\Hm^\text{sub} = \Hm^V - \Hm^S = \Hm^V - \Hm^L + (\Hm^L - \Hm^S)
-%                = \Delta\Hm^\text{vap} + \Delta\Hm^\text{fus} \]
+%  \[ \Deltasub\Hm = \Hm^V - \Hm^S = \Hm^V - \Hm^L + (\Hm^L - \Hm^S)
+%                  = \Deltafus\Hm + \Deltavap\Hm \]
 % with the default options. Note that some textbooks (e.g., |Sandler|) typeset
-% these quantities quite differently.
+% these quantities quite differently; this is handled automatically. Other
+% textbooks (e.g., |Koretsky|) typeset them as subscripts; this is also
+% handled automatically.
 %
 % \DescribeMacro{\Deltaf}
 % \DescribeMacro{\Deltarxn}
@@ -694,7 +847,7 @@
 %  \[ \Deltarxn\Hm^\std = \sumall_i \nu_i \Deltaf\Hm_i^\std \]
 %\end{verbatim}
 % results in
-% \[ \Delta\Hm_\text{rxn}^\circ = \sum_{i=1}^C \nu_i \Delta\Hm_{f,i}^\circ. \]
+% \[ \Deltarxn\Hm^\std = \sumall_i \nu_i \Deltaf\Hm_i^\std. \]
 % It is not anticipated that this command will be combined with something like
 % a heat capacity, which already has a (potentially double) subscript, but as
 % there is no ``formation'' heat capacity, that should not present a problem.
@@ -713,50 +866,54 @@
 % molar properties. These macros follow the same pattern: \cs{UR}, \cs{URt},
 % \cs{URs}, and \cs{URpm} typeset the molar, total, specific, and partial molar
 % residual internal energies, respectively, and by default expand to $U^R,$
-% $\thermounderline{U}^R,$ $\hat U^R, $ and $\smash[t]{\Upm[R]{i}}$ (the last
+% $\URt,$ $\URs, $ and $\smash[t]{\URpm{i}}$ (the last
 % is called as \verb"\URpm{i}" or \verb"\URpm_i"). Similarly, \cs{UE},
 % \cs{UEt}, \cs{UEs}, and \cs{UEpm} typeset the corresponding excess
 % properties. The first character of the macros for other properties follow the
 % same pattern as in Table~\ref{table:symbols}.
 %
+% The $R$ and $E$ characters are generated by the macros \cs{residual} and
+% \cs{excess}, respectively. These macros can be redefined; for example, if you
 % \DescribeMacro{\excess}
 % \DescribeMacro{\residual}
-% The $R$ and $E$ characters are generated by the macros \cs{residual} and
-% \cs{excess}, respectively. These macros can be redefined; for example, if you
-% want \cs{SE}, which normally produces $S^E$, to give you $S^{EX}$---and let's
+% want \cs{SE}, which normally produces $\SE$, to give you $S^{EX}$---and let's
 % be honest, who doesn't want that?\footnote{You knew that joke was
 % coming.}---then you can redefine it with
 % \begin{verbatim}
-%   \renewcommand*{\excess}{{EX}}
+%   \RenewDocumentCommand{\excess}{}{{EX}},
 %\end{verbatim}
 % or possibly
 % \begin{verbatim}
-%   \renewcommand*{\excess}{{\mathrm{EX}}}
+%   \RenewDocumentCommand{\excess}{}{{\mathrm{EX}}}
 %\end{verbatim}
 % or even
 % \begin{verbatim}
-%   \renewcommand*{\excess}{\text{EX}}
+%   \RenewDocumentCommand{\excess}{}{\text{EX}},
 %\end{verbatim}
 % which cause \cs{SE} to expand to $S^{EX},$ $S^\mathrm{EX},$ and
 % $S^\text{EX},$ respectively.
 %
-% It is generally not possible to use superscripts with the excess or
-% residual properties; in the event the user needs this, the \cs{excess} and
-% \cs{residual} macros can be used directly, viz.,
+% It is generally possible to use superscripts with the excess or residual
+% properties; in the event this fails, the \cs{excess} and \cs{residual} macros
+% can be used directly, viz.,
 % \begin{verbatim}
 %   \begin{gather*}
-%     \Hm^{\excess,\std} = \HE(T,\Pstd) \\
-%   \renewcommand*{\excess}{EX}
-%     \Hm^{\excess,\std} = \HE(T,\Pstd)
-%   \end{gather*}
+%     \HE^\std = \Hm^{\excess,\std} = \HE(T,\Pstd)
+%       = \HR(T,\Pstd) - \HR^\IS(T,\Pstd) = \HR^\std - \HR^{\IS,\std} \\
+%   \RenewDocumentCommand{\excess}{{EX}}
+%     \HE^\std = \Hm^{\excess,\std} = \HE(T,\Pstd)
+%       = \HR(T,\Pstd) - \HR^\IS(T,\Pstd)
+%   \end{gather*},
 %\end{verbatim}
 % which yields
 % \begin{gather*}
-%   \Hm^{E,\circ} = H^E(T,P^\circ) \\
-%   \Hm^{EX,\circ} = H^{EX}(T,P^\circ)
+%     \HE^\std = \Hm^{\excess,\std} = \HE(T,\Pstd)
+%       = \HR(T,\Pstd) - \HR^\IS(T,\Pstd) = \HR^\std - \HR^{\IS,\std} \\
+%   \RenewDocumentCommand{\excess}{}{{EX}}
+%     \HE^\std = \Hm^{\excess,\std} = \HE(T,\Pstd)
+%       = \HR(T,\Pstd) - \HR^\IS(T,\Pstd)
 % \end{gather*}
 % using the default options.
-% \clearpage
 %
 % \subsection{Partial Derivatives}
 % \DescribeMacro{\Partial}%
@@ -764,18 +921,36 @@
 % Partial derivatives are easily rendered using the \cs{Partial} command.
 % There is a starred form (\cs{Partial*}) that additionally adjusts the
 % spacing after the closing symbol to remove some of the space, anticipating
-% that the following binary operator will overhang the subscripts. Compare
-% the following:
+% that the following binary operator will overhang the subscripts.
+% Compare the following:
 % \begin{verbatim}
-%   \begin{gather*}
-%     \Partial{\Hm}{T}{P} = \cP \qquad \Partial*{\Hm}{T}{P} = \cP
-%   \end{gather*}
+%  \[ \Partial{\Hm}{T}{P} = \cP \qquad \Partial*{\Hm}{T}{P} = \cP \],
 %\end{verbatim}
 % which yields
-% \begin{gather*}
-%   \left(\frac{\partial\Hm}{\partial T}\right)_{P} = C_P \qquad
-%   \left(\frac{\partial\Hm}{\partial T}\right)_{P} \mkern-8mu = C_P
-% \end{gather*}
+%  \[ \Partial{\Hm}{T}{P} = \cP \qquad \Partial*{\Hm}{T}{P} = \cP. \]
+%
+% \DescribeMacro{\Partialinline}%
+% Inline first derivatives\footnote{The ``inline'' versions of
+%   partial derivatives are ``sticky'': if you issue \cs{Partialinline} or
+%   its second-order equivalents anywhere in a line, all subsequent
+%   \cs{Partial} and \cs{Partial[Mix]Second} macros on the same line
+%    (technically, anywhere in the same \TeX\ ``group'') will
+%   expand inline as well. To prevent this, enclose your \cs{Partialinline} and
+%   associated arguments in its own group (i.e.,
+%   \texttt{\{\cs{Partialinline}\dots\}}).%
+%   \label{fn:inline}}
+% can be entered the same way; compare:
+% \begin{verbatim}
+%  \[ \Partial*{\Hm}{T}{P} = \Partialinline{\Hm}{T}{P}
+%       = T\Partial{\Sm}{T}{P} \],
+%\end{verbatim}
+% which results in
+%   \[ \Partial*{\Hm}{T}{P} = \Partialinline{\Hm}{T}{P}
+%       = T\Partial{\Sm}{T}{P}. \]
+% There is no need for an inline starred form, as the subscripts do not
+% extend far enough below the baseline.
+%
+% \subsubsection{Second-Order Partial Derivatives}
 % \DescribeMacro{\PartialSecond}%
 % \DescribeMacro{\PartialSecond*}%
 % \DescribeMacro{\PartialMixSecond}%
@@ -793,35 +968,46 @@
 %             = \Partial{\Gpm_i}{P}{T,\allNs} \]
 %\end{verbatim}
 % looks like
-%   \[ \Vpm{i} = \left(\frac{\partial\Vt}
-%                           {\partial\Nt_i}\right)_{T,P,\allNsbut{i}}
-%       \mkern-15mu
-%              = \left(\frac{\partial^2\Gt}
-%                           {\partial\Nt_i\partial P}\right)_{T,\allNsbut{i}}
-%       \mkern-15mu
-%              = \left(\frac{\partial^2\Gt}
-%                           {\partial P\partial\Nt_i}\right)_{T,\allNsbut{i}}
-%       \mkern-15mu
-%              = \left(\frac{\partial\Gpm{i}}{\partial P}\right)_{T,\allNs}. \]
-% \DescribeMacro{\PartialBigg}
-% \SpecialUsageIndex{\PartialBigg*}\relax
-% \DescribeMacro{\PartialSecondBigg}
-% \SpecialUsageIndex{\PartialSecondBigg*}\relax
-% \DescribeMacro{\PartialMixSecondBigg}
-% \SpecialUsageIndex{\PartialMixSecondBigg*}\relax
-% \DescribeMacro{\Partialbigg}
-% \SpecialUsageIndex{\Partialbigg*}\relax
-% \DescribeMacro{\PartialSecondbigg}
-% \SpecialUsageIndex{\PartialSecondbigg*}\relax
-% \DescribeMacro{\PartialMixSecondbigg}
-% \SpecialUsageIndex{\PartialMixSecondbigg*}\relax
+%   \[ \Vpm_i = \Partial*{\Vt}{\Nt_i}{T,P,\allNsbut{i}}
+%             = \PartialMixSecond*{\Gt}{\Nt_i}{P}{T,\allNsbut{i}}
+%             = \PartialMixSecond*{\Gt}{P}{\Nt_i}{T,\allNsbut{i}}
+%             = \Partial{\Gpm_i}{P}{T,\allNs}. \]
+% \DescribeMacro{\PartialSecondinline}%
+% \DescribeMacro{\PartialMixSecondinline}%
+% Inline versions\footref{fn:inline} of second-order derivatives are handled
+% with \cs{PartialSecondinline} and \cs{PartialMixSecondinline}, viz.,
+% \begin{verbatim}
+% \begin{equation}
+%   \Vpm_i = \Partialinline{\Vt}{\Nt_i}{T,P,\allNsbut{i}}
+%          = \PartialMixSecondinline{\Gt}{\Nt_i}{P}{T,\allNsbut{i}}
+%          = \PartialMixSecondinline{\Gt}{P}{\Nt_i}{T,\allNsbut{i}}
+%          = \Partialinline{\Gpm_i}{P}{T,\allNs} \]
+% \end{equation}
+%\end{verbatim}
+% looks like
+% \begin{equation}
+%     \Vpm_i = \Partialinline{\Vt}{\Nt_i}{T,P,\allNsbut{i}}
+%            = \PartialMixSecondinline{\Gt}{\Nt_i}{P}{T,\allNsbut{i}}
+%            = \PartialMixSecondinline{\Gt}{P}{\Nt_i}{T,\allNsbut{i}}
+%            = \Partialinline{\Gpm_i}{P}{T,\allNs}.
+%   \label{eq:Vpm-inline}
+% \end{equation}
+% \pagebreak[0]%
+%
+% \subsubsection{Delimiter Sizing}
+% \DescribeMacro{\PartialBigg}%
+% \DescribeMacro{\PartialSecondBigg}%
+% \DescribeMacro{\PartialMixSecondBigg}%
+% \DescribeMacro{\Partialbigg}%
+% \DescribeMacro{\PartialSecondbigg}%
+% \DescribeMacro{\PartialMixSecondbigg}%
 % There are instances (such as the line above) when \cs{Partial} causes
 % parentheses that are slightly
 % too tall but do not need to be---particularly when partial molar properties,
 % specific quantities, or fugacities are involved. The macro \cs{PartialBigg}
-% uses \verb"amsmath"'s \cs{Biggl} and \cs{Biggr} macros in place of \cs{left}
-% and \cs{right} to size the parentheses accordingly; \cs{Partiallbigg} uses
-% \cs{biggl} and \cs{biggr} in a similar fashion. For example, compare the
+% uses \pkg{amsmath}'s \tn{Biggl} and \tn{Biggr} macros in place of \tn{left}
+% and \tn{right} to size the delimiters accordingly; \cs{Partialbigg} uses
+% \tn{biggl} and \tn{biggr} in a similar fashion. For example, compare the
 % following:
 % \begin{verbatim}
 %  \[ \Vpm_i = \Partial*{\Vt}{\Nt_i}{T,P,\allNsbut{i}}
@@ -829,55 +1015,65 @@
 %            = \PartialBigg*{\Gpm_i}{P}{T,\allNs}
 %            = RT\Partial*{\log\fmix_i}{P}{T,\allNs}
 %            = RT\,\PartialBigg*{\log\fmix_i}{P}{T,\allNs}
-%            = RT\,\Partialbigg{\log\fmix_i}{P}{T,\allNs} \]
+%            = RT\,\Partialbigg{\log\fmix_i}{P}{T,\allNs} \],
 %\end{verbatim}
 % which typesets as
-% \[ \Vpm{i}
-%      = \left(\frac{\partial\Vt}{\partial \Nt_i}\right)_{T,P,\allNsbut{i}}
-%        \mkern-15mu
-%      = \left(\frac{\partial\Gpm{i}}{\partial P}\right)_{T,\allNs}
-%        \mkern-15mu
-%      = \Biggl(\frac{\partial\Gpm{i}}{\partial P}\Biggr)_{T,\allNs}
-%        \mkern-15mu
-%      = RT\left(\frac{\partial\log\hat f_i}{\partial P}\right)_{T,\allNs}
-%        \mkern-15mu
-%      = RT\,\Biggl(\frac{\partial\log\hat f_i}{\partial P}\Biggr)_{T,\allNs}
-%        \mkern-15mu
-%      = RT\,\biggl(\frac{\partial\log\hat f_i}{\partial P}\biggr)_{T,\allNs} \]
+%  \[ \Vpm{i} = \Partial*{\Vt}{\Nt_i}{T,P,\allNsbut{i}}
+%            = \Partial*{\Gpm{i}}{P}{T,\allNs}
+%            = \PartialBigg*{\Gpm{i}}{P}{T,\allNs}
+%            = RT\Partial*{\log\fmix_i}{P}{T,\allNs}
+%            = RT\,\PartialBigg*{\log\fmix_i}{P}{T,\allNs}
+%            = RT\,\Partialbigg{\log\fmix_i}{P}{T,\allNs}. \]
 % Note that a similar effect---possibly with other side effects---can be
-% achieved with \verb"amsmath"'s \cs{smash} command, which has the effect of
+% achieved with \pkg{amsmath}'s \tn{smash} command, which has the effect of
 % removing all vertical space associated with a particular character.
 % Observe:
 % \begin{verbatim}
-%  \[ \Vpm_i = \Partial{\Vt}{\Nt_i}{T,P,\allNsbut{i}}
+%  \[ \Vpm_i = \Partial*{\Vt}{\Nt_i}{T,P,\allNsbut{i}}
 %            = \Partial{\smash{\Gpm_i}}{P}{T,\allNs} \]
-% \end{verbatim}
+%\end{verbatim}
 % produces
-% \[ \Vpm{i}
-%      = \left(\frac{\partial\Vt}{\partial \Nt_i}\right)_{T,P,\allNsbut{i}}
-%      = \left(\frac{\partial\smash{\Gpm{i}}}{\partial P}\right)_{T,\allNs}. \]
-% Note that the vertical spacing is not quite as good here as it was above.
-% This can be fixed by using the optional argument to \cs{smash}, viz.,
+%  \[ \Vpm_i = \Partial*{\Vt}{\Nt_i}{T,P,\allNsbut{i}}
+%            = \Partial{\smash{\Gpm_i}}{P}{T,\allNs}. \]
+%
+% \setmarginparsize{\footnotesize}%
+% \DescribeMacro{\Partialinlinetext}%
+% \DescribeMacro{\PartialSecondinlinetext}%
+% \restoremarginparsize
+% \setmarginparsize{\scriptsize}
+% \DescribeMacro{\PartialMixSecondinlinetext}%
+% \restoremarginparsize
+% Similarly, there are times when \cs{Partialinline} causes parentheses that
+% are too big for inline text, and they do not need to be---particularly for
+% symbols with overlines, underlines, or other decorations. In this case, the
+% macros \cs{Partialinlinetext}, \cs{PartialSecondinlinetext}, and
+% \cs{PartialMixSecondinlinetext} come in handy; using these macros like so,
 % \begin{verbatim}
-%  \[ \Vpm_i = \Partial{\Vt}{\Nt_i}{T,P,\allNsbut{i}}
-%            = \Partial{\smash[t]{\Gpm_i}}{P}{T,\allNs} \]
+% \[ \Vpm_i = \Partialinlinetext{\Vt}{\Nt_i}{T,P,\allNsbut{i}}
+%           = \PartialMixSecondinlinetext{\Gt}{\Nt_i}{P}{T,\allNsbut{i}}
+%           = \PartialMixSecondinlinetext{\Gt}{P}{\Nt_i}{T,\allNsbut{i}}
+%           = \Partialinlinetext{\Gpm_i}{P}{T,\allNs} \],
 %\end{verbatim}
-% \[ \Vpm{i}
-%   = \left(\frac{\partial\Vt}{\partial \Nt_i}\right)_{T,P,\allNsbut{i}}
-%   = \left(\frac{\partial\smash[t]{\Gpm{i}}}{\partial P}\right)_{T,\allNs}. \]
+% Equation~\eqref{eq:Vpm-inline} looks like
+% \[ \Vpm{i} = \Partialinlinetext{\Vt}{\Nt_i}{T,P,\allNsbut{i}}
+%           = \PartialMixSecondinlinetext{\Gt}{\Nt_i}{P}{T,\allNsbut{i}}
+%           = \PartialMixSecondinlinetext{\Gt}{P}{\Nt_i}{T,\allNsbut{i}}
+%           = \Partialinlinetext{\Gpm{i}}{P}{T,\allNs}. \]
+%
+% \subsubsection{Higher-Order Derivatives}
 % It is possible to ``fake'' higher-order derivatives via some trickery.
 % For example,
 % \begin{verbatim}
-% \[ \cPpm_i = T\Partial{\Spm_i}{T}{P,\allXs}
-%            = T\PartialSecond{\St}{T}{\Nt_i}{P,\allNsbut{i}}
+% \[ \cPpm_i = T\Partial*{\Spm_i}{T}{P,\allXs}
+%            = T\PartialMixSecond*{\St}{T}{\Nt_i}{P,\allNsbut{i}}
 %            = -T\Partial{^3\Gt}{T^2\partial\Nt_i}{P,\allNsbut{i}} \]
 %\end{verbatim}
 % gives
-% \[ \cPpm{i} = T\Partial{\Spm{i}}{T}{P,\allXs}
-%             = T\Partial{^2\St}{T\partial\Nt_i}{P,\allNsbut{i}}
+% \[ \cPpm{i} = T\Partial*{\Spm{i}}{T}{P,\allXs}
+%             = T\PartialMixSecond*{\St}{T}{\Nt_i}{P,\allNsbut{i}}
 %             = -T\Partial{^3\Gt}{T^2\partial\Nt_i}{P,\allNsbut{i}}, \]
 % which is probably pretty close to what you wanted. Using this trickery with
-% the package option \verb"nosubscripts" will not work as well, and the use of
+% the package option \verb"nosubscripts" will not work, and the use of
 % third- and higher-order derivatives with this package should generally be
 % considered unsupported.
 %
@@ -895,16 +1091,22 @@
 % \DescribeMacro{\allWs}%
 % \DescribeMacro{\allWsbut}%
 % It is common in thermodynamics to use notation such as
-% \[ \Vpm{k} = \left(\frac{\partial\Vt}{\partial\Nt_k}\right)_{T,P,\Nt_{j\neq k}} \]
+% \[ \Vpm_k = \Partial{\Vt}{\Nt_k}{T,P,\allNsbut{k}}, \]
 % or perhaps
-% \[ \Vpm{k} = \left(\frac{\partial\Vt}{\partial\Nt_k}\right)_{T,P,\Nt_1,\dotsc,[\Nt_k],\dots,\Nt_C} \]
+% \begin{thermomolesrange}
+% \[ \Vpm{k} = \Partial{\Vt}{\Nt_k}{T,P,\allNsbut{k}} \]
+% \end{thermomolesrange}
+% or
+% \[ \Vpm{k} = \left(\frac{\partial\Vt}{\partial\Nt_k}\right)_{T,P,\Nt_j[k]} \]
 % to mean partial derivatives that hold the number of moles of each species
 % constant \emph{except} the one being changed.
 % Similarly, a property determined with all mole fractions held
 % constant might be written
-% \[ C_P = \left(\frac{\partial\Hm}{\partial T}\right)_{P,\vec{x}} \]
+% \[ \cP = \Partial{\Hm}{T}{P,\allXs}, \]
 % or perhaps
-% \[ C_P = \left(\frac{\partial\Hm}{\partial T}\right)_{P,x_1,\dotsc,x_C}. \]
+% \begin{thermomolesrange}\relax
+% \[ \cP = \Partial{\Hm}{T}{P,\allXs}. \]
+% \end{thermomolesrange}\relax
 % There are several macros that standardize such constructs.
 % The \cs{allNs} macro expands to something meaning the number of moles of all
 % species; by default, this is $\vec{n}$ (package option
@@ -915,62 +1117,106 @@
 % fractions, namely \cs{allXs} and \cs{allXsbut} for $x$ and \cs{allYs} and
 % \cs{allYsbut} for $y$, as well as \cs{allWs} and \cs{allWsbut} for mass
 % fractions---these implicitly assume that all mole or mass fractions
-% \emph{except} the last are used as variables.  The macros \cs{allNsbut},
-% \cs{allMsbut}, \cs{allmusbut}, \cs{allXsbut}, \cs{allYsbut}, and
-% \cs{allWsbut} take an optional argument; for example,
+% \emph{except} the last are used as variables.
+% These macros all take an optional argument; for example,
 % \begin{verbatim}
-%   \Partial{\Ht}{\Nt_1}{T,P,\allNsbut{1}} =
-%   \Partial{\Ht}{\Nt_1}{T,P,\allNsbut[m]{1}} = \Hpm_1
+% \[ \Partial{\Ht}{\Nt_1}{T,P,\allNsbut{1}} =
+%    \Partial{\Ht}{\Nt_1}{T,P,\allNsbut[m]{1}} = \Hpm_1 \]
 %\end{verbatim}
 % typesets as
-% \[ \left(\frac{\partial\Ht}{\partial\Nt_1}\right)_{T,P,\Nt_{j\neq 1}}
-%   = \left(\frac{\partial\Ht}{\partial\Nt_1}\right)_{T,P,\Nt_{m\neq 1}}
-%   = \Hpm{1} \]
+% \[ \Partial{\Ht}{\Nt_1}{T,P,\allNsbut{1}} =
+%    \Partial{\Ht}{\Nt_1}{T,P,\allNsbut[m]{1}} = \Hpm{1}. \]
 % Similarly,
 % \begin{verbatim}
-%   \Partial{\Hm}{x_i}{T,P,\allXsbut{i}} =
-%   \Partial{\Hm}{x_i}{T,P,\allXsbut[m]{i}} = \Hpm_i - \Hpm_\ncomponents
+% \[ \Partial{\Hm}{x_i}{T,P,\allXsbut{i}}
+%   = \Partial{\Hm}{x_i}{T,P,\allXsbut[m]{i}}
+%   = \Hpm_i - \Hpm_\ncomponents \]
 %\end{verbatim}
 % becomes
-% \[ \left(\frac{\partial\Hm}{\partial x_i}\right)_{T,P,x_{j\neq i,C}}
-%   = \left(\frac{\partial\Hm}{\partial x_i}\right)_{T,P,x_{m\neq i,C}}
-%   = \Hpm{i} - \Hpm{C} \]
-% The user must supply their own redefinition if they wish to hold something
-% other than \cs{ncomponents} constant in addition to the argument.
+% \[ \Partial{\Hm}{x_i}{T,P,\allXsbut{i}}
+%  = \Partial{\Hm}{x_i}{T,P,\allXsbut[m]{i}}
+%  = \Hpm{i} - \Hpm{\ncomponents}. \]
+% Users must supply their own redefinitions if they wish to hold something
+% other than \cs{ncomponents} constant in addition to the argument for mole
+% and mass fractions.
 % Using the \verb"moles-range" package option, for which \verb"\allXsbut{k}"
-% expands to $x_1,\dotsc,[x_k],\dotsc,x_{C-1}$ rather than $x_{j \neq k,C}$,
-% the optional argument is ignored.
+% expands to
+% \( \begin{thermomolesrange}\allXsbut{k}\end{thermomolesrange} \)
+% rather than \( \allXsbut{k} \), the optional argument is ignored.
 %
+% The optional argument to \cs{allNs} and similar commands is ignored when
+% using the default options; it is relevant for package options that redefine
+% \cs{allNs} to make $N_i$, for example; in this case, one can enter
+% \cs{allNs[j]} to make \TeX\ render $N_j$ instead of $N_i$. This is useful
+% if you are using $i$ somewhere else in the equation.
+%
 % \DescribeMacro{\allbut}
 % \DescribeMacro{\allbutlastand}
 % Users can define new ``all but'' macros using the \cs{allbut} and
 % \cs{allbutlastand} commands. For example,
 % \begin{verbatim}
-%   \newcommand*{\allNsbut}[2][j]{\allbut[#1]{#2}{\Nt}}
-%   \newcommand*{\allXsbut}[2][j]{\allbutlastand[#1]{#2}{x}}
+%   \NewDocumentCommand{\allNsbut}{O{j} m}{\allbut[#1]{#2}{\Nt}}
+%   \NewDocumentCommand{\allXsbut}{O{j} m}{\allbutlastand[#1]{#2}{x}}
 %\end{verbatim}
 % are the definitions of \cs{allNsbut} and \cs{allXsbut}, respectively.
 %
+% \subsection{Jacobians}
+% \DescribeMacro{\Jacobian}%
+% \DescribeMacro{\Jacobiandet}%
+% The Jacobian determinant is often denoted with Leibnitz-like notation, viz.,
+% \begin{verbatim}
+% \[ \Jacobian{K,L}{X,Y} = \Jacobiandet{K,L}{X,Y} \],
+%\end{verbatim}
+% which produces (assuming the \pkg{amsmath} package has been loaded)
+% \[ \Jacobian{K,L}{X,Y} = \Jacobiandet{K,L}{X,Y}. \]
+% There are two optional arguments to \cs{Jacobiandet}. The first will be
+% pre-pended before every element of the matrix (typically \cs{textstyle} or
+% \cs{displaystyle}); the second is the extra spacing added between rows
+% (default is 1.25~ex for text-style fractions and 2.75~ex for display-style
+% fractions).  More than two variables can be specified, viz.,
+% \begin{verbatim}
+% \[ \Jacobian{K,L,M}{X,Y,Z}
+%   = \Jacobiandet[\displaystyle][3ex]{K,L,M}{X,Y,Z} \]
+%\end{verbatim}
+% will produce
+% \[ \Jacobian{K,L,M}{X,Y,Z} = \Jacobiandet[\displaystyle][3ex]{K,L,M}{X,Y,Z}.
+% \]
+% The \cs{Jacobiandet} macro will understand implied multicomponent Jacobians,
+% too, namely,
+% \begin{verbatim}
+% \[ \Jacobian{f_1,\dots,f_m}{x_1,\dots,x_m} =
+%    \Jacobiandet{f_1,\dots,f_m}{x_1,\dots,x_m} \]
+%\end{verbatim}
+% typesets as
+% \[ \Jacobian{f_1,\dots,f_m}{x_1,\dots,x_m} =
+%    \Jacobiandet{f_1,\dots,f_m}{x_1,\dots,x_m}. \]
+% If the option |moles-range| or the \env{thermomolesrange} environment is
+% used, the same code produces
+% \begin{thermomolesrange}
+% \[ \Jacobian{f_1,\dots,f_m}{x_1,\dots,x_m} =
+%    \Jacobiandet{f_1,\dots,f_m}{x_1,\dots,x_m}. \]
+% \end{thermomolesrange}
+%
 % \subsection{Sums and Products}
 % \DescribeMacro{\sumall}
 % \DescribeMacro{\sumallbutlast}
 % \DescribeMacro{\prodall}
 % It is common to require sums and products such as
-% \[ \sum_{i=1}^C x_i = 1 \quad \text{or} \quad
-%    x_C = 1 - \sum_{i=1}^{C-1} x_i \quad \text{or} \quad
-%    \Gt = \sum_{j=1}^C \mu_j\Nt_j \quad \text{and} \quad
-%    K = \prod_{k=1}^C a_k^{\nu_k}. \]
+% \[ \sumall_i x_i = 1 \quad \text{or} \quad
+%    x_\ncomponents = 1 - \sumallbutlast_i x_i \quad \text{or} \quad
+%    \Gt = \sumall_j \mu_j\Nt_j \quad \text{and} \quad
+%    K = \prodall_k a_k^{\nu_k}. \]
 % This package defines shortcuts to typeset such terms thus:
 % \begin{verbatim}
 % \[ \sumall_i x_i = 1 \quad \text{or} \quad
 %    x_\ncomponents = 1 - \sumallbutlast_i x_i \quad \text{or} \quad
 %    \Gt = \sumall_j \mu_j\Nt_j \quad \text{and} \quad
-%    K = \prodall_k a_k^{\nu_k}. \]
+%    K = \prodall_k a_k^{\nu_k} \].
 %\end{verbatim}
-% The symbol $C$ can be changed by redefining \cs{ncomponents}. This is done
-% automatically by some package options (e.g., |TesterModell| changes it to
-% $n$; |Sandler| changes it to $\mathcal{C}$; |Thompson| changes it to
-% $c$).
+% The symbol $C$ can be changed by redefining the expandable macro
+% \cs{ncomponents}. This is done automatically by some package options (e.g.,
+% |TesterModell| changes it to $n$; |Sandler| changes it to $\mathcal{C}$;
+% |Thompson| changes it to $c$).
 %
 % \section{Loading the Package} \label{sec:loading}
 % To load the package with the defaults enabled, load it the usual way:
@@ -981,9 +1227,11 @@
 % \verb"parentheses", \verb"intensive-plain", and \verb"moles-index".
 % These define, respectively, the default symbols to use for total energy,
 % internal energy, Helmholtz free energy, and so forth; the manner of writing
-% partial derivatives; the delimiters around partial derivatives; and the
-% manner of denoting extensive, molar, and specific properties. The default
-% behavior can be altered by options in the following section.
+% partial derivatives; the delimiters around partial derivatives; the
+% manner of denoting extensive, molar, and specific properties; and the
+% manner of writing the number of moles of all or most species in partial
+% derivatives. The default behavior can be altered by options in the following
+% section.
 %
 % \subsection{Package Options}
 % There are three categories of options: options that affect which symbols are
@@ -995,6 +1243,10 @@
 % energy, internal energy, Helmholtz free energy, and so forth. These are
 % summarized in Table~\ref{table:symbol-sets}. The default is \verb"EUAGHan".
 %
+% \NewExtensiveProperty{f}{F}
+% \NewExtensiveProperty{a}{A}
+% \NewExtensiveProperty{ee}{\mathcal{E}}
+% \NewExtensiveProperty{aa}{\mathcal{A}}
 % \begin{table}
 %   \caption{Options controlling which symbols to use by default. The
 %       macros \cs{Et}, \cs{Ut}, \cs{Ft}, \cs{Gt}, \cs{Ht}, \cs{At}, and
@@ -1010,112 +1262,21 @@
 %   Option & \verb"\Et" & \verb"\Ut" & \verb"\Ft" & \verb"\Gt" & \verb"\Ht"
 %          & \verb"\At" & \verb"\Nt" \\
 %   \midrule
-%     \verb"EUAGHan" & $\thermounderline{E}$
-%                    & $\thermounderline{U}$
-%                    & $\thermounderline{A}$
-%                    & $\thermounderline{G}$
-%                    & $\thermounderline{H}$
-%                    & $\thermounderline{a}$
-%                    & $n$
-%   \\
-%     \verb"EUAGHaN" & $\thermounderline{E}$
-%                    & $\thermounderline{U}$
-%                    & $\thermounderline{A}$
-%                    & $\thermounderline{G}$
-%                    & $\thermounderline{H}$
-%                    & $\thermounderline{a}$
-%                    & $N$
-%   \\
-%     \verb"EUHAGan" & \multicolumn{7}{l}{(synonym for \texttt{EUAGHan})} \\
-%     \verb"EUHAGaN" & \multicolumn{7}{l}{(synonym for \texttt{EUAGHaN})} \\
-%     \verb"EUFGHAn" & $\thermounderline{E}$
-%                    & $\thermounderline{U}$
-%                    & $\thermounderline{F}$
-%                    & $\thermounderline{G}$
-%                    & $\thermounderline{H}$
-%                    & $\thermounderline{A}$
-%                    & $n$
-%   \\
-%     \verb"EUFGHAN" & $\thermounderline{E}$
-%                    & $\thermounderline{U}$
-%                    & $\thermounderline{F}$
-%                    & $\thermounderline{G}$
-%                    & $\thermounderline{H}$
-%                    & $\thermounderline{A}$
-%                    & $N$
-%   \\
-%     \verb"EEFGHAn" & $\thermounderline{E}$
-%                    & $\thermounderline{E}$
-%                    & $\thermounderline{F}$
-%                    & $\thermounderline{G}$
-%                    & $\thermounderline{H}$
-%                    & $\thermounderline{A}$
-%                    & $n$
-%   \\
-%     \verb"EEFGHAn" & $\thermounderline{E}$
-%                    & $\thermounderline{E}$
-%                    & $\thermounderline{F}$
-%                    & $\thermounderline{G}$
-%                    & $\thermounderline{H}$
-%                    & $\thermounderline{A}$
-%                    & $N$
-%   \\
-%     \verb"EEFGHan" & $\thermounderline{E}$
-%                    & $\thermounderline{E}$
-%                    & $\thermounderline{F}$
-%                    & $\thermounderline{G}$
-%                    & $\thermounderline{H}$
-%                    & $\thermounderline{a}$
-%                    & $n$
-%   \\
-%     \verb"EEFGHaN" & $\thermounderline{E}$
-%                    & $\thermounderline{E}$
-%                    & $\thermounderline{F}$
-%                    & $\thermounderline{G}$
-%                    & $\thermounderline{H}$
-%                    & $\thermounderline{a}$
-%                    & $N$
-%   \\
-%     \verb"EEAGHaN" & $\thermounderline{E}$
-%                    & $\thermounderline{E}$
-%                    & $\thermounderline{A}$
-%                    & $\thermounderline{G}$
-%                    & $\thermounderline{H}$
-%                    & $\thermounderline{a}$
-%                    & $N$
-%   \\
-%     \verb"EUAGHAn" & $\thermounderline{E}$
-%                    & $\thermounderline{U}$
-%                    & $\thermounderline{A}$
-%                    & $\thermounderline{G}$
-%                    & $\thermounderline{H}$
-%                    & $\thermounderline{A}$
-%                    & $n$
-%   \\
-%     \verb"EUAGHAN" & $\thermounderline{E}$
-%                    & $\thermounderline{U}$
-%                    & $\thermounderline{A}$
-%                    & $\thermounderline{G}$
-%                    & $\thermounderline{H}$
-%                    & $\thermounderline{A}$
-%                    & $N$
-%   \\
-%     \verb"EUFGHan" & $\thermounderline{E}$
-%                    & $\thermounderline{U}$
-%                    & $\thermounderline{F}$
-%                    & $\thermounderline{G}$
-%                    & $\thermounderline{H}$
-%                    & $\thermounderline{a}$
-%                    & $n$
-%   \\
-%     \verb"EUFGHaN" & $\thermounderline{E}$
-%                    & $\thermounderline{U}$
-%                    & $\thermounderline{F}$
-%                    & $\thermounderline{G}$
-%                    & $\thermounderline{H}$
-%                    & $\thermounderline{a}$
-%                    & $N$
-%   \\
+%     |EUAGHan| & $\Et$ & $\Ut$ & $\Ft$ & $\Gt$ & $\Ht$ & $\At$ & $n$ \\
+%     |EUAGHaN| & $\Et$ & $\Ut$ & $\Ft$ & $\Gt$ & $\Ht$ & $\At$ & $N$ \\
+%     |EUHAGan| & \multicolumn{7}{l}{(synonym for \texttt{EUAGHan})} \\
+%     |EUHAGaN| & \multicolumn{7}{l}{(synonym for \texttt{EUAGHaN})} \\
+%     |EUFGHAn| & $\Et$ & $\Ut$ & $\ft$ & $\Gt$ & $\Ht$ & $\at$ & $n$ \\
+%     |EUFGHAN| & $\Et$ & $\Ut$ & $\ft$ & $\Gt$ & $\Ht$ & $\at$ & $N$ \\
+%     |EEFGHAn| & $\eet$ & $\Et$ & $\ft$ & $\Gt$ & $\Ht$ & $\at$ & $n$ \\
+%     |EEFGHAN| & $\eet$ & $\Et$ & $\ft$ & $\Gt$ & $\Ht$ & $\at$ & $N$ \\
+%     |EEFGHan| & $\eet$ & $\Et$ & $\ft$ & $\Gt$ & $\Ht$ & $\At$ & $n$ \\
+%     |EEFGHaN| & $\eet$ & $\Et$ & $\ft$ & $\Gt$ & $\Ht$ & $\At$ & $N$ \\
+%     |EEAGHaN| & $\eet$ & $\Et$ & $\Ft$ & $\Gt$ & $\Ht$ & $\At$ & $N$ \\
+%     |EEAGHAN| & $\eet$ & $\Et$ & $\Ft$ & $\Gt$ & $\Ht$ & $\aat$ & $n$ \\
+%     |EUAGHAN| & $\Et$ & $\Ut$ & $\Ft$ & $\Gt$ & $\Ht$ & $\aat$ & $N$ \\
+%     |EUFGHan| & $\Et$ & $\Ut$ & $\ft$ & $\Gt$ & $\Ht$ & $\At$ & $n$ \\
+%     |EUFGHaN| & $\Et$ & $\Ut$ & $\ft$ & $\Gt$ & $\Ht$ & $\At$ & $N$ \\
 %   \bottomrule
 %   \end{tabular}
 % \end{table}
@@ -1122,21 +1283,18 @@
 %
 % Using \verb"EUAGHan" (the default), we might use the following markup:
 % \begin{verbatim}
-%   \[ \Ft = \Ut - T\St = -P\Vt + \sum_i \mu_i \Nt_i + \sigma d\At
-%      \qquad \Hm = \Um + P\Vm \qquad \Et = \Ut + \frac12 mv^2 \]
+%   \[ \Ft = \Ut - T\St = -P\Vt + \sumall_i \mu_i \Nt_i + \sigma \At
+%      \qquad \Hm = \Um + P\Vm \qquad \Et = \Ut + \frac12 mv^2 \],
 %\end{verbatim}
 % which would look like
-% \[ \thermounderline{A}
-%    = \thermounderline{U} - T\thermounderline{S}
-%    = -P\thermounderline{V} + \sum_i \mu_i n_i + \sigma d\thermounderline{a}
+%   \[ \Ft = \Ut - T\St = -P\Vt + \sumall_i \mu_i \Nt_i + \sigma \At
+%      \qquad \Hm = \Um + P\Vm \qquad \Et = \Ut + \frac12 mv^2 \]
+% Using the \verb"EEFGHAN" option, the same markup would yield
+% \[ \ft
+%    = \Et - T\St
+%    = -P\Vt + \sumall_i \mu_i N_i + \sigma \at
 %    \qquad H = U + PV
-%    \qquad \thermounderline{E} = \thermounderline{U} + \frac12 mv^2. \]
-% Using the \verb"EUFGHAN" option, the same markup would yield
-% \[ \thermounderline{F}
-%    = \thermounderline{U} - T\thermounderline{S}
-%    = -P\thermounderline{V} + \sum_i \mu_i N_i + \sigma d\thermounderline{A}
-%    \qquad H = U + PV
-%    \qquad \thermounderline{E} = \thermounderline{U} + \frac12 mv^2. \]
+%    \qquad \eet = \Et + \frac12 mv^2. \]
 %
 % \subsubsection{Options for Extensive vs.\ Molar Properties}
 % There are four sets of notation that define how extensive properties are
@@ -1143,36 +1301,40 @@
 % represented, as shown in Table~\ref{table:extensive}.
 % The default is \verb"intensive-plain", which (using the volume as an
 % example) represents the total, molar, specific, and partial molar volumes,
-% respectively, as $\thermounderline{V},$ $V,$ $\hat V,$ and $\Vpm{j},$
+% respectively, as $\Vt,$ $\Vm,$ $\Vs,$ and $\Vpm{j},$
 % respectively.
 %
 % For example, the definition of the partial molar enthalpy would be different
 % depending on which set of notation is used. The markup
 % \begin{verbatim}
-%   \Hpm_i = \Partial{\Ht}{\Nt_i}{T,P,\allNsbut{i}}
-%          = \Partial{\Nt\Hm}{\Nt_i}{T,P,\allNsbut{i}}
+% \[ \Hpm_i = \Partial*{\Ht}{\Nt_i}{T,P,\allNsbut{i}}
+%           = \Partial{\Nt\Hm}{\Nt_i}{T,P,\allNsbut{i}} \]
 %\end{verbatim}
 % yields the following, depending on the package option loaded:
 % \begin{align*}
-%   \Hpm{i} &= \left(\frac{\partial\thermounderline{H}}
-%                         {\partial n_i}\right)_{T,P,n_{j\neq i}}
-%            = \left(\frac{\partial nH}
-%                         {\partial n_i}\right)_{T,P,n_{j\neq i}}
+%   \Hpm_i &= \Partial*{\Ht}{\Nt_i}{T,P,\allNsbut{i}}
+%           = \Partial{\Nt\Hm}{\Nt_i}{T,P,\allNsbut{i}}
 %       && \text{\texttt{intensive-plain}} \\
-%   \Hpm{i} &= \left(\frac{\partial H}
-%                         {\partial n_i}\right)_{T,P,n_{j\neq i}}
-%            = \left(\frac{\partial n\thermounderline{H}}
-%                         {\partial n_i}\right)_{T,P,n_{j\neq i}}
+%   \Hpm_i &=
+% \begin{thermoextensiveplain}
+%             \Partial*{\Ht}{\Nt_i}{T,P,\allNsbut{i}}
+%           = \Partial{\Nt\Hm}{\Nt_i}{T,P,\allNsbut{i}}
+% \end{thermoextensiveplain}
 %       && \text{\texttt{extensive-plain}} \\
-%   \Hpm{i} &= \left(\frac{\partial H^t}
-%                         {\partial n_i}\right)_{T,P,n_{j\neq i}}
-%            = \left(\frac{\partial nH}
-%                         {\partial n_i}\right)_{T,P,n_{j\neq i}}
+%   \Hpm_i &=
+% \begin{thermoextensivesuperscript}
+%             \Partial*{\Ht}{\Nt_i}{T,P,\allNsbut{i}}
+%           = \Partial{\Nt\Hm}{\Nt_i}{T,P,\allNsbut{i}}
+% \end{thermoextensivesuperscript}
 %       && \text{\texttt{extensive-superscript}} \\
-%   \Hpm{i} &= \left(\frac{\partial H}
-%                         {\partial n_i}\right)_{T,P,n_{j\neq i}}
-%            = \left(\frac{\partial nh}
-%                         {\partial n_i}\right)_{T,P,n_{j\neq i}}
+% \begin{thermointensivelowercase}
+%   \Hpm_i
+% \end{thermointensivelowercase}
+%          &=
+% \begin{thermointensivelowercase}
+%             \Partial*{\Ht}{\Nt_i}{T,P,\allNsbut{i}}
+%           = \Partial{\Nt\Hm}{\Nt_i}{T,P,\allNsbut{i}}
+% \end{thermointensivelowercase}
 %       && \text{\texttt{intensive-lowercase}}
 % \end{align*}
 % The use of \verb"intensive-lowercase" is strongly discouraged.
@@ -1183,28 +1345,52 @@
 % \begin{table}
 %   \caption{Notation sets that can be set using the options
 %       \texttt{intensive-plain} (the default), \texttt{extensive-plain},
-%       \texttt{extensive-superscript}, and \texttt{intensive-lowercase},
-%       respectively. Note that specific quantities are generally assumed to
-%       look like the molar symbol with a caret on top.}
+%       \texttt{extensive-superscript}, and \texttt{intensive-lowercase}.}
 %   \label{table:extensive}
 %   \centering\small
-%   \newcommand*{\vpm}[2][]{\mkern1mu\overline{\mkern-1mu v_{\mkern-2mu #2}^{#1}\mkern-2mu}\mkern2mu}
 %   \begin{tabular}{l l l l l l}
 %   \toprule
 %     Option & \verb"\Vt" & \verb"\Vm" & \verb"\Vs" & \verb"\Vpm_i" \\
 %   \midrule
-%     \verb"intensive-plain" & $\thermounderline{V}$ & $V$ & $\hat V$
-%       & $\Vpm{i}$ \\
-%     \verb"extensive-plain" & $V$ & $\thermounderline{V}$ & $\hat V$
-%       & $\Vpm{i}$\rule{0pt}{2.5ex} \\
-%     \verb"extensive-superscript" & $V^t$ & $V$ & $\hat V$
-%       & $\Vpm{i}$\rule{0pt}{2.5ex} \\
-%     \verb"intensive-lowercase" & $V$ & $v$ & $\hat v$
-%       & $\vpm{i}$\rule{0pt}{2.5ex} \\
+%     \verb"intensive-plain" & $\Vt$ & $\Vm$ & $\Vs$ & $\Vpm{i}$ \\[2ex]
+%     \verb"extensive-plain" &
+%       \begin{thermoextensiveplain}$\Vt$\end{thermoextensiveplain} &
+%       \begin{thermoextensiveplain}$\Vm$\end{thermoextensiveplain} &
+%       \begin{thermoextensiveplain}$\Vs$\end{thermoextensiveplain} &
+%       \begin{thermoextensiveplain}$\Vpm{i}$\end{thermoextensiveplain}
+%     \\[2ex]
+%     \verb"extensive-superscript" &
+%       \begin{thermoextensivesuperscript}$\Vt$\end{thermoextensivesuperscript} &
+%       \begin{thermoextensivesuperscript}$\Vm$\end{thermoextensivesuperscript} &
+%       \begin{thermoextensivesuperscript}$\Vs$\end{thermoextensivesuperscript} &
+%       \begin{thermoextensivesuperscript}$\Vpm{i}$\end{thermoextensivesuperscript} \\[2ex]
+%     \verb"intensive-lowercase" &
+%       \begin{thermointensivelowercase}$\Vt$\end{thermointensivelowercase} &
+%       \begin{thermointensivelowercase}$\Vm$\end{thermointensivelowercase} &
+%       \begin{thermointensivelowercase}$\Vs$\end{thermointensivelowercase} &
+%       \begin{thermointensivelowercase}$\Vpm{i}$\end{thermointensivelowercase} 
+%     \\
 %   \bottomrule
 %   \end{tabular}
 % \end{table}
 %
+% \pagebreak[1]\relax
+% \setmarginparsize{\footnotesize}
+% \DescribeEnv{thermointensiveplain}
+% \DescribeEnv{thermoextensiveplain}
+% \DescribeEnv{thermoextensivesuperscript}
+% \DescribeEnv{thermointensivelowercase}
+% \restoremarginparsize
+% It is possible to change notation locally, though there are very, very few
+% good reasons why you would want to do this in a regular document---normally,
+% one would use the corresponding package options. The environment
+% \env{thermointensiveplain} means \cs{St} will become $\St$ and \cs{Sm} will
+% become $\Sm$ in the text. Similarly, inside \env{thermoextensiveplain},
+% \cs{St} will become $S$ and \cs{Sm} will become $\St$.
+% Inside \env{thermoextensivesuperscript}, \cs{St} will become $S^t$ and
+% \cs{Sm} will be $S$; and inside \env{thermointensivesubscript},
+% \cs{St} will be $S$ and \cs{Sm} will be $s$.
+%
 % \subsubsection{Options Affecting Partial Derivatives}
 % There are several options that change how partial derivatives are rendered.
 % First are the options that affect the delimiters. We will use the following
@@ -1214,54 +1400,60 @@
 %                           = \PartialMixSecond{\Gm}{P}{T}{}
 %                           = -\Partial{\Sm}{P}{T}. \]
 %\end{verbatim}
-% Using the \verb"parentheses" option (the default), this gives
-%   \[ \left(\frac{\partial V}{\partial T}\right)_{P} \mkern-8mu
-%       = \left(\frac{\partial^2 G}{\partial T \partial P}\right)
-%       = \left(\frac{\partial^2 G}{\partial P \partial T}\right)
-%       = -\left(\frac{\partial S}{\partial P}\right)_{T}. \]
-% The option \verb"brackets" changes the output to
-%   \[ \left[\frac{\partial V}{\partial T}\right]_{P} \mkern-8mu
-%       = \left[\frac{\partial^2 G}{\partial T \partial P}\right]
-%       = \left[\frac{\partial^2 G}{\partial P \partial T}\right]
-%       = -\left[\frac{\partial S}{\partial P}\right]_{T}. \]
+% Using the |parentheses| option (the default), this gives
+%   \[ \Partial*{\Vm}{T}{P} = \PartialMixSecond{\Gm}{T}{P}{}
+%                           = \PartialMixSecond{\Gm}{P}{T}{}
+%                           = -\Partial{\Sm}{P}{T}. \]
+% The option |brackets| changes the output to
+% \begin{thermobrackets}
+%   \[ \Partial*{\Vm}{T}{P} = \PartialMixSecond{\Gm}{T}{P}{}
+%                           = \PartialMixSecond{\Gm}{P}{T}{}
+%                           = -\Partial{\Sm}{P}{T}. \]
+% \end{thermobrackets}\relax
 % The option \verb"bar" changes the output to
-%   \[ \left.\frac{\partial V}{\partial T}\right\rvert_{P} \mkern-8mu
-%       = \left.\frac{\partial^2 G}{\partial T \partial P}\right.
-%       = \left.\frac{\partial^2 G}{\partial P \partial T}\right.
-%       = -\left.\frac{\partial S}{\partial P}\right\rvert_{T}. \]
+% \begin{thermobar}
+%   \[ \Partial*{\Vm}{T}{P} = \PartialMixSecond{\Gm}{T}{P}{}
+%                           = \PartialMixSecond{\Gm}{P}{T}{}
+%                           = -\Partial{\Sm}{P}{T}. \]
+% \end{thermobar}\relax
 % The option \verb"plain-derivatives" eliminates all delimiters; this forces
 % the \verb"nosubscripts" option. The output in this case is
-%   \[ \left.\frac{\partial V(T,P)}{\partial T}\right.
-%       = \left.\frac{\partial^2 G(T,P)}{\partial T \partial P}\right.
-%       = \left.\frac{\partial^2 G(P,T)}{\partial P \partial T}\right.
-%       = -\left.\frac{\partial S(P,T)}{\partial P}\right. \]
-%
+% \begin{thermoplain}%
+%   \[ \Partial*{\Vm}{T}{P} = \PartialMixSecond{\Gm}{T}{P}{}
+%                           = \PartialMixSecond{\Gm}{P}{T}{}
+%                           = -\Partial{\Sm}{P}{T}. \]
+% \end{thermoplain}\relax
 % Accompanying the \verb"plain-derivatives" option is the \verb"nosubscripts"
 % option, which overrides the default option \verb"subscripts". This option
 % makes partial derivatives such as
-% \[ \left(\frac{\partial V}{\partial P}\right)_{T}
-%   \qquad \text{(\texttt{subscripts} option)}, \]
+% \[ \begin{thermosubscripts}
+%      \Partial{\Vm}{P}{T} \qquad \text{(\texttt{subscripts} option)},
+%     \end{thermosubscripts}\relax \]
 % and instead renders them
-% \[ \left(\frac{\partial V(P,T)}{\partial P}\right)
-%   \qquad \text{(\texttt{nosubscripts} option)}. \]
+% \[ \begin{thermoNOsubscripts}
+%       \Partial{\Vm}{P}{T} \qquad \text{(\texttt{nosubscripts} option)},
+%    \end{thermoNOsubscripts} \]
 % Combined with \verb"plain-derivatives", this would give
-% \[ \left.\frac{\partial V(P,T)}{\partial P}\right.
-%   \qquad \text{(\texttt{nosubscripts} and \texttt{plain-derivatives}
-%   options)} . \]
-% The order of the variables is determined by the arguments given: it is
-% always written with the variable that is changing first, and the other
-% variables in the order given in the final argument to \cs{Partial} and
-% friends. This will result in things like the following:
-% \begin{verbatim}
-%   \[ \Partial{\Vm}{T}{P} = \PartialMixSecond{\Gm}{T}{P}{}
-%       = \PartialMixSecond{\Gm}{P}{T}{} = -\Partial{\Sm}{P}{T}, \]
-%\end{verbatim}
-% which would produce (using \verb"plain-derivatives")
-% \[ \frac{\partial V(T,P)}{\partial T}
-%      = \frac{\partial^2 G(T,P)}{\partial T\partial P}
-%      = \frac{\partial^2 G(P,T)}{\partial P\partial T}
-%      = - \frac{\partial S(P,T)}{\partial P} \]
-% This is not unclear, but the variables appear in a different order.
+% \[ \begin{thermoplain}
+%      \Partial{\Vm}{P}{T} \qquad \text{(\texttt{nosubscripts} and
+%                                        \texttt{plain-derivatives} options)}.
+%    \end{thermoplain} \]
+% The variables are sorted into an order defined by an internal constant,
+% meaning $T$ will always be listed before $P$. The order by default is in
+% the order that terms appear in the fundamental equations, that is,
+% \begin{gather*}
+%   d\Ut = T \,d\St - P \,d\Vt + \mu \,d\Nt \\
+%   d\Ht = T \,d\St + \Vt \,dP + \mu \,d\Nt \\
+%   d\Ft = -\St\,dT - P \,d\Vt + \mu \,d\Nt \\
+%   \vdots \\
+%   d\Lt = -\St\,dT - P \,d\Vt - \Nt\,d\mu,
+% \end{gather*}
+% with the exception that subscripted variables are (currently) not sortable.
+% If \verb"\Nt_i" or some similar construct appears as a variable and
+% \verb"\allNsbut{i}" appears in the held-constant list, the package will
+% assume that the argument list \emph{should} contain all of the mole numbers.
+% Symbols without subscripts that are not in the fundamental equation or one of
+% its variants are sorted in alphabetical order.
 %
 % \DescribeEnv{thermoparentheses}
 % \DescribeEnv{thermobrackets}
@@ -1268,47 +1460,59 @@
 % \DescribeEnv{thermobar}
 % \DescribeEnv{thermoplain}
 % If you want to use parentheses \emph{locally}, even though your overall
-% document uses another delimiter, the |thermoparentheses| environment will do
-% that. Similarly, |thermobrackets| will temporarily switch to brackets,
-% |thermobar| will temporarily switch to a tailing vertical bar, and
-% |thermoplain| will remove delimiters altogether.
+% document uses another delimiter, the \env{thermoparentheses} environment will
+% do that. Similarly, \env{thermobrackets} will temporarily switch to brackets,
+% \env{thermobar} will temporarily switch to a tailing vertical bar, and
+% \env{thermoplain} will remove delimiters altogether.
 %
 % \DescribeEnv{thermosubscripts}
 % \DescribeEnv{thermoNOsubscripts}
-% The environments |thermosubscripts| and |thermoNOsubscripts| force the
-% use or disuse of subscripts, respectively.
+% The environments \env{thermosubscripts} and \env{thermoNOsubscripts}
+% force the use or disuse of subscripts, respectively.
 %
 % \subsubsection{Options Regarding the Number of Moles}
-% \DescribeMacro{\allNs}
-% \DescribeMacro{\allNsbut}
+% \DescribeMacro{\allNs}%
+% \DescribeMacro{\allNsbut}%
 % The default option \verb"moles-index" defines the macro \cs{allNs} to expand
-% to $\vec{n}$ and the macro \verb"\allNsbut{i}" to expand to $n_{j\neq i}$.
+% to $\allNs$ and the macro \verb"\allNsbut{i}" to expand to $\allNsbut{i}$.
 % You can change the dummy index: \verb"\allNsbut[k]{i}" expands to
-% $n_{k\neq i}$ by default. This is typically not necessary, however: if you
-% type \verb"\allNsbut{j}", the package will figure out that you want
-% $\Nt_{k\neq j}$ rather than $\Nt_{j\neq j}$. The time to use the optional
+% $\allNsbut[k]{i}$ by default. This is typically not necessary, however: if
+% you type \verb"\allNsbut{j}", the package will figure out that you want
+% $\allNsbut{j}$ rather than $\Nt_{j\neq j}$. The time to use the optional
 % argument is in situations such as
-% \[ \Partial{\mu_j}{\Nt_k}{\Nt_{i\neq k}}, \]
+% \[ \Partial{\mu_j}{\Nt_k}{\allNsbut[i]{k}}, \]
 % which is incorrect if the dummy index $j$ is used in place of the $i$.
 %
 % You can change these to expand to ranges using the \verb"moles-range"
-% option, which renders \cs{allNs} as $n_1,\dotsc,n_C$ and \verb"\allNsbut{i}"
-% as $n_1,\dotsc,[n_i],\dotsc,n_C$. The optional argument is ignored in this
-% set of notation. Examples of these options are shown in
-% Table~\ref{table:allNs}.
+% option, which renders \cs{allNs} as
+% $\begin{thermomolesrange}\allNs\end{thermomolesrange}$ and
+% \verb"\allNsbut{i}" as
+% $\begin{thermomolesrange}\allNsbut{i}\end{thermomolesrange}.$
+% The optional argument is ignored in this set of notation. Examples of these
+% options are shown in Table~\ref{table:allNs}.
 %
-% \DescribeMacro{\ncomponents}
+% \DescribeEnv{thermomolesrange}
+% The environment \env{thermomolesrange} temporarily redefines \cs{allNs} and
+% other range-oriented macros as though the |moles-range| package option had
+% been invoked.
+%
+% \DescribeMacro{\ncomponents}%
 % You can change the symbol for the number of components (default: $C$) by
-% redefining the macro \cs{ncomponents}.
+% redefining the macro \cs{ncomponents}. This is done for you by some package
+% options that define notation for particular textbooks.
 %
 % \begin{table}
 %   \caption{Illustration of the \texttt{moles-index} and \texttt{moles-range}
 %       options and their effects on \cs{allNs} and \cs{allNsbut}.}
 %   \label{table:allNs}
-%   \SpecialUsageIndex{\allNs}\relax
-%   \SpecialUsageIndex{\allNsbut}\relax
-%   \SpecialUsageIndex{\allXs}\relax
-%   \SpecialUsageIndex{\allXsbut}\relax
+%^^A TODO The \leavevmode macro here is to prevent whitespace from building
+%^^A      up due to a bug in old versions of hypdoc. It should be harmless to
+%^^A      leave it in there, but consider removing it at some point.
+%   \leavevmode
+%   \SpecialMacroIndex{\allNs}\relax
+%   \SpecialMacroIndex{\allNsbut}\relax
+%   \SpecialMacroIndex{\allXs}\relax
+%   \SpecialMacroIndex{\allXsbut}\relax
 %   \centering
 %   \begin{minipage}{4.49in}\renewcommand*{\footnoterule}{\vskip-1.5ex}%
 %   \small
@@ -1315,27 +1519,46 @@
 %     \begin{tabular}{l l l}
 %     \toprule
 %       Macro\footnote{You may use $C$ directly instead of \cs{ncomponents}
-%         here, but then it will not change $C-1$ to $C-2$ (or, say, $M-1$ to
-%         $M-2$) if you want to redefine \cs{ncomponents} later.}
+%         here, but then it will not change to another symbol if you want to
+%         switch to an option that redefines \cs{ncomponents} later.}
 %       & \verb"moles-index" & \verb"moles-range" \\
 %     \midrule
-%       \verb"\allNs" & $\vec{n}$ & $n_1,\dotsc,n_C$ \\
-%       \verb"\allNsbut{1}" & $n_{j\neq 1}$ & $n_2,\dotsc,n_C$ \\
-%       \verb"\allNsbut{i}" & $n_{j\neq i}$ & $n_1,\dotsc,[n_i],\dotsc,n_C$ \\
-%       \verb"\allNsbut{j}" & $n_{k\neq j}$ & $n_1,\dotsc,[n_j],\dotsc,n_C$ \\
-%       \verb"\allNsbut{\ncomponents}" & $n_{j\neq C}$ & $n_1,\dotsc,n_{C-1}$ \\
-%       \verb"\allNsbut[k]{i}" & $n_{k\neq i}$ & $n_1,\dotsc,[n_i],\dotsc,n_C$ \\
-%       \verb"\allXs" & $\vec{x}$ & $x_1,\dotsc,x_{C}$ \\
-%       \verb"\allXsbut{1}" & $x_{j\neq 1,C}$ & $x_2,\dotsc,x_{C-1}$ \\
-%       \verb"\allXsbut{i}" & $x_{j\neq i,C}$ & $x_1,\dotsc,[x_i],\dotsc,x_{C-1}$ \\
-%       \verb"\allXsbut{j}" & $x_{k\neq j,C}$ & $x_1,\dotsc,[x_j],\dotsc,x_{C-1}$ \\
-%       \verb"\allXsbut{\ncomponents-1}" & $x_{j\neq C-1,C}$ & $x_1,\dotsc,x_{C-2}$ \\
-%       \verb"\allXsbut[k]{\ncomponents-1}" & $x_{k\neq C-1,C}$ & $x_1,\dotsc,x_{C-2}$ \\
+%       \verb"\allNs" & $\allNs$
+%           & $\begin{thermomolesrange}\allNs\end{thermomolesrange}$ \\
+%       \verb"\allNsbut{1}" & $\allNsbut{1}$
+%           & $\begin{thermomolesrange}\allNsbut{1}\end{thermomolesrange}$ \\
+%       \verb"\allNsbut{i}" & $\allNsbut{i}$
+%           & $\begin{thermomolesrange}\allNsbut{i}\end{thermomolesrange}$ \\
+%       \verb"\allNsbut{j}" & $\allNsbut{j}$
+%           & $\begin{thermomolesrange}\allNsbut{j}\end{thermomolesrange}$ \\
+%       \verb"\allNsbut{\ncomponents}" & $\allNsbut{\ncomponents}$
+%  & $\begin{thermomolesrange}\allNsbut{\ncomponents}\end{thermomolesrange}$\\
+%       \verb"\allNsbut[k]{i}" & $\allNsbut[k]{i}$
+%           & $\begin{thermomolesrange}\allNsbut[k]{i}\end{thermomolesrange}$\\
+%       \verb"\allXs" & $\allXs$
+%           & $\begin{thermomolesrange}\allXs\end{thermomolesrange}$ \\
+%       \verb"\allXsbut{1}" & $\allXsbut{1}$
+%           & $\begin{thermomolesrange}\allXsbut{1}\end{thermomolesrange}$ \\
+%       \verb"\allXsbut{i}" & $\allXsbut{i}$
+%           & $\begin{thermomolesrange}\allXsbut{i}\end{thermomolesrange}$ \\
+%       \verb"\allXsbut{j}" & $\allXsbut{j}$
+%           & $\begin{thermomolesrange}\allXsbut{j}\end{thermomolesrange}$ \\
+%       \verb"\allXsbut{\ncomponents-1}" & $\allXsbut{\ncomponents-1}$
+%           & $\begin{thermomolesrange}\allXsbut{\ncomponents-1}
+%               \end{thermomolesrange}$ \\
+%       \verb"\allXsbut[k]{\ncomponents-1}" & $\allXsbut[k]{\ncomponents-1}$
+%           & $\begin{thermomolesrange}\allXsbut[k]{\ncomponents-1}
+%               \end{thermomolesrange}$ \\
 %       \verb"\allXsbut{\ncomponents}"\footnote{This would typically be used
-%           to denote something like $\Gt(T,P,n,x_1,\dotsc,x_{C-1})$ rather
-%           than in a subscript, but it looks silly if we don't handle this
-%           case this way.}
-%           & $x_{j\neq C}$ & $x_1,\dotsc,x_{C-1}$ \\
+%           to denote something like
+%           \( \begin{thermomolesrange}
+%                \Gt(T,P,\Nt,\allXsbut{\ncomponents})
+%               \end{thermomolesrange}
+%           \) rather than in a subscript, but it looks silly if we do not
+%           handle this case this way.}
+%           & $\allXsbut{\ncomponents}$
+%           & $\begin{thermomolesrange}\allXsbut{\ncomponents}
+%              \end{thermomolesrange}$ \\
 %     \bottomrule
 %     \end{tabular}
 %   \end{minipage}
@@ -1342,20 +1565,19 @@
 % \end{table}
 %
 % \subsubsection{Other Options}
-% \DescribeMacro{\dbar}
-% \newcommand*{\dbar}{{\mkern5mu\mathchar'26\mkern-10mu d}}\relax
+% \DescribeMacro{\dbar}%
 % The default for path-dependent one-forms (often called ``inexact
 % differentials'') is \cs{dbar}, which looks like $\dbar$. This can be changed,
 % if desired, to a delta ($\delta$) with the \verb"delta" option to the
 % package.
 %
-% It should be noted that the \cs{dbar} macro is not very stable: changing
+% It should be noted that the \cs{dbar} macro is context-dependent: changing
 % the typeface to something not supported will probably ruin it, as the kerning
 % is very font-specific. This package currently supports Computer Modern,
 % Times, Palatino, Bitstream Charter, Garamond, and Utopia, but other typefaces
 % may require a manual redefinition.
 %
-% \subsubsection{Options for Specific Textbooks}
+% \subsubsection{Options for Particular Textbooks}
 % There are several options that load package options and/or redefine
 % particular commands to match the notation in a particular textbook. So far
 % the following textbooks are supported:
@@ -1363,8 +1585,8 @@
 %   \item[Bejan] Notation used by Bejan, \emph{Advanced Engineering
 %     Thermodynamics}, Third Edition. Wiley: Hoboken, 2006. Loads non-default
 %     package options \verb"EUFGHAN", \verb"intensive-lowercase", and
-%     \verb"delta". Also swaps the definitions of \verb"\@specific" and
-%     \verb"\@intensive" and redefines \cs{cV}, \cs{cVs}, \cs{cVt},
+%     \verb"delta". Also swaps the notation for specific and
+%     intensive properties and redefines \cs{cV}, \cs{cVs}, \cs{cVt},
 %     \cs{expansivitysymbol}, and \cs{ncomponents} to match his notation.
 %   \item[CBK] Notation used by \c Cengel, Boles, and Kano\u glu,
 %     \emph{Thermodynamics: An Engineering Approach}, Ninth Edition.
@@ -1371,14 +1593,16 @@
 %     McGraw Hill: Singapore, 2020. Loads the non-default package options
 %     \verb"EUAGHAN" and \verb"intensive-lowercase"; also redefines
 %     partial molar, specific, and molar properties' notation to fit theirs,
-%     and redefines \cs{pressure at symbol}, \cs{Deltarxn},
+%     and redefines the internal symbol for pressure, \cs{Deltarxn},
 %     \cs{compressibilitysymbol}, and \cs{expansivitysymbol} to fit their
-%     usage. Their prodigal symbols for specific and total volume are not
+%     usage. Their prodigal symbols for specific and total volume, which appear
+%     to be from the font ITC Benguiat Gothic Standard Book Oblique, are not
 %     supported.
 %   \item[ElliottLira] Notation used by Elliott and Lira, \emph{Introductory
 %     Chemical Engineering Thermodynamics}, Second Edition. Prentice Hall:
 %     Upper Saddle River, 2012. Loads the default package options and
-%     redefines \cs{allcomponents} and \cs{Deltarxn} to fit their notation.
+%     redefines \cs{IG}, \cs{IGM}, \cs{allcomponents}, and \cs{Deltarxn} to fit
+%     their notation.
 %   \item[Koretsky] Notation used by Koretsky, \emph{Engineering and Chemical
 %     Thermodynamics}, Second Edition, Wiley: New Caledonia, 2013.
 %     Loads the non-default package options \verb"EUAGHAn", \verb"brackets",
@@ -1396,15 +1620,15 @@
 %     \verb"EUFGHAn", \verb"intensive-lowercase", and \verb"delta"; removes the
 %     left parenthesis in partial derivatives and redefines \cs{IGM}, \cs{IG},
 %     \cs{expansitivitysymbol}, \cs{allcomponents}, \cs{allbut}, \cs{Ft},
-%     \cs{Helmholtz at symbol}, \cs{@intensive}, \cs{@specific}, \cs{fmix},
-%     \cs{phimix}, and \cs{pressure at symbol} to fit their somewhat ill-advised
-%     notation. Also resets \cs{partialmolar} to match their use.
+%     \cs{fmix}, and \cs{phimix}, as well as symbols for the Helmholtz free
+%     energy and pressure, intensive and specific property notation, and
+%     partial molar notation to fit their somewhat ill-advised notation.
 %   \item[Prausnitz] Notation used by Prausnitz, Lichtenthaler, and de Azevedo,
 %     \emph{Molecular Thermodynamics of Fluid-Phase Equilibria}, Third Edition,
 %     Pearson, 1998. Loads the non-default package option
 %     \verb"intensive-lowercase" and redefines \cs{fmix}, \cs{phimix},
-%     \cs{fpure}, \cs{phipure}, \cs{residual}, \cs{allcomponents}, and
-%     \cs{allbut} to fit their notation.
+%     \cs{fpure}, \cs{phipure}, \cs{Henryrat}, \cs{residual},
+%     \cs{allcomponents}, and \cs{allbut} to fit their notation.
 %   \item[Sandler] Notation used by Sandler, \emph{Chemical, Biochemical, and
 %     Engineering Thermodynamics}, Fifth Edition. Wiley: Hoboken, 2017.
 %     Loads non-default package options \verb"EUAGHaN" and
@@ -1430,28 +1654,42 @@
 %     \cs{Henrymol}, \cs{gammarat}, and \cs{gammamol} to fit their style.
 %   \item[Thompson] Notation used by Thompson, \emph{A Unified Introduction to
 %     Chemical Engineering Thermodynamics}, Stillwater Press: Orono, 2000.
-%     Loads the non-default package options \verb"EUAGHAn" and \verb"delta";
-%     also redefines \cs{excess}, \cs{residual}, \cs{allcomponents},
-%     \cs{ncomponents}, \cs{IS}, \cs{IG}, \cs{IGM}, \cs{fpure}, \cs{phipure},
-%     \cs{mix}, \cs{Deltamix}, \cs{Deltarxn}, \cs{@intensive}, and \cs{allbut}
-%     to match his notation.  Note that he uses $c$, $n_C$, and $\mathrm{n}$
-%     for the number of components in various places in the book; I chose $c$
-%     for the definition of \cs{ncomponents}, but it is impossible to be
-%     completely consistent with his notation.
+%     Loads the non-default package options |EUAGHAn| and |delta|;
+%     also redefines \cs{excess}, \cs{residual}, \cs{Henryrat}, \cs{Henrymol},
+%     \cs{allcomponents}, \cs{ncomponents}, \cs{IS}, \cs{IG}, \cs{IGM},
+%     \cs{fpure}, \cs{phipure}, \cs{mix}, \cs{Deltamix}, \cs{Deltarxn}, and
+%     \cs{allbut} to match his notation, plus adjustments to intensive (molar)
+%     properties.  Note that he uses $c$, $\mathrm{c}$, $n_C$, and 
+%     $\mathrm{n}$ for the number of components in various places in the book;
+%     I chose $c$ for the definition of \cs{ncomponents}, but it is impossible
+%     to be completely consistent with his notation.
 % \end{description}
 % There may well be some inconsistencies between the notation in these books
 % and the symbols used here. I will fix such inconsistencies as I become aware
 % of them.
+%^^X \end{documentation}
 %
+% \setcounter{IndexColumns}{2}
 % \StopEventually{\PrintChanges\PrintIndex}
 %
 % ^^A--------------------------------------------------------------------------
 % \iffalse
 %<*package>
+%<@@=thermodynamics>
 % \fi
 %
+%^^X\begin{implementation}
 % \section{Implementation}
-% This package requires the \verb"amstext" package, as \cs{text} is used to
+% We set up some non-standard token comparison variants; these are designed
+% to catch both \cs{ncomponents}=\cs{ncomponents} and \cs{ncomponents}=$C$
+% (using the default options); we have to define \cs{ncomponents} to be
+% expandable to make these work at all.
+%    \begin{macrocode}
+\ExplSyntaxOn
+\cs_generate_variant:Nn \tl_if_eq:nnTF { xxTF }
+%    \end{macrocode}
+%
+% This package requires the \pkg{amstext} package, as \tn{text} is used to
 % handle \cs{sat}, \cs{IS}, \cs{IG}, \cs{IGM}, \cs{Henrymol}, \cs{fusion},
 % \cs{reaction}, \cs{vaporization}, and \cs{sublimation} by default, as well
 % as several other macros defined by package options.
@@ -1469,47 +1707,57 @@
 % We try to determine, at \verb"\begin{document}", which typeface you chose
 % based on the packages that are loaded and some of their internal definitions.
 % The \textsf{thermodynamics} package currently supports
-% Computer Modern (the default or through \verb"lmodern"),
-% Palatino (through \verb"pxfonts" or \verb"newpxmath"),
-% Times (through \verb"txfonts", \verb"mathptmx", or \verb"newtxmath"),
-% Utopia (through \verb"mathdesign"),
-% Bitstream Charter (through \verb"mathdesign"), and
-% Garamond (through \verb"mathdesign").
-% Definitions of \cs{dbar} (with \cs{newcommand*} or \cs{providecommand*})
+% Computer Modern (the default or through \pkg{lmodern}),
+% Palatino (through \pkg{pxfonts} or \pkg{newpxmath}),
+% Times (through \pkg{txfonts}, \pkg{mathptmx}, or \pkg{newtxmath}),
+% Utopia (through \pkg{mathdesign}),
+% Bitstream Charter (through \pkg{mathdesign}), and
+% Garamond (through \pkg{mathdesign}).
+% Definitions of \cs{dbar} (with \cs{newcommand*}, \cs{providecommand*},
+% \cs{NewDocumentCommand}, or \cs{ProvideDocumentCommand})
 % in the preamble will override the ones here.
 %    \begin{macrocode}
 \AtBeginDocument{
     \@ifpackageloaded{pxfonts}{%
-        \providecommand*{\dbar}{{\mkern5mu\mathchar'26\mkern-10mu d}}%
+        \ProvideDocumentCommand{\dbar}{}
+            {\mkern5mu\mathchar'26\mkern-10mu d}
     }{}
     \@ifpackageloaded{newpxmath}{%
-        \providecommand*{\dbar}{{\mkern5mu\mathchar'26\mkern-10mu d}}%
+        \ProvideDocumentCommand{\dbar}{}
+            {\mkern5mu\mathchar'26\mkern-10mu d}
     }{}
     \@ifpackageloaded{txfonts}{%
-        \providecommand*{\dbar}{{\mkern5mu\mathchar'26\mkern-11mu d}}%
+        \ProvideDocumentCommand{\dbar}{}
+            {\mkern5mu\mathchar'26\mkern-11mu d}
     }{}
     \@ifpackageloaded{mathptmx}{%
-        \providecommand*{\dbar}{{\mkern5mu\mathchar'26\mkern-10mu d}}%
+        \ProvideDocumentCommand{\dbar}{}
+            {\mkern5mu\mathchar'26\mkern-10mu d}
     }{}
     \@ifpackageloaded{newtxmath}{%
-        \providecommand*{\dbar}{{\mkern5mu\mathchar'26\mkern-12mu d}}%
+        \ProvideDocumentCommand{\dbar}{}
+            {\mkern5mu\mathchar'26\mkern-11mu d}
     }{}
     \@ifpackageloaded{mathdesign}{%
-        \def\@charter{mdbch}%
-        \def\@utopia{mdput}%
-        \def\@garamond{mdugm}%
-        \ifx\MD at default@family\@utopia
-            \providecommand*{\dbar}{{\mkern8mu\mathchar'26\mkern-20mu d}}%
-        \fi
-        \ifx\MD at default@family\@charter
-            \providecommand*{\dbar}{{\mkern5mu\mathchar'26\mkern-15mu d}}%
-        \fi
-        \ifx\MD at default@family\@garamond
-            \providecommand*{\dbar}{{\mkern5mu\mathchar'26\mkern-17mu d}}%
-        \fi
+        \tl_const:Nn \c_@@_charter_tl {mdbch}
+        \tl_const:Nn \c_@@_utopia_tl {mdput}
+        \tl_const:Nn \c_@@_garamond_tl {mdugm}
+        \tl_if_eq:NNT \MD at default@family \c_@@_utopia_tl
+        { \ProvideDocumentCommand{\dbar}{}
+            {\mkern5mu\mathchar'26\mkern-20mu d}
+        }
+        \tl_if_eq:NNT \MD at default@family \c_@@_charter_tl
+        { \ProvideDocumentCommand{\dbar}{}
+            {\mkern5mu\mathchar'26\mkern-15mu d}
+        }
+        \tl_if_eq:NNT \MD at default@family \c_@@_garamond_tl
+        { \ProvideDocumentCommand{\dbar}{}
+            {\mkern5mu\mathchar'26\mkern-17mu d}
+        }
     }{}
     % Defaults to Computer Modern
-    \providecommand*{\dbar}{{\mkern3mu\mathchar'26\mkern-12mu d}}
+    \ProvideDocumentCommand{\dbar}{}
+        {\mkern3mu\mathchar'26\mkern-12mu d}
 }
 %    \end{macrocode}
 % \end{macro}
@@ -1521,30 +1769,16 @@
 % their own, but rather accessed through the macros \cs{Ut}, \cs{Um}, and
 % \cs{Us} (using the internal energy as an example).
 %
-% \begin{macro}{\totalenergy at symbol}
-% \begin{macro}{\internalenergy at symbol}
-% \begin{macro}{\Helmholtz at symbol}
-% \begin{macro}{\Gibbs at symbol}
-% \begin{macro}{\Landau at symbol}
-% \begin{macro}{\enthalpy at symbol}
-% \begin{macro}{\entropy at symbol}
-% \begin{macro}{\area at symbol}
-% \begin{macro}{\volume at symbol}
-% \begin{macro}{\mole at symbol}
-% \begin{macro}{\heat at symbol}
-% \begin{macro}{\work at symbol}
-% \begin{macro}{\temperature at symbol}
-% \begin{macro}{\pressure at symbol}
 % The default symbols are not intended to be easy to change---the intended
 % mechanism is through package options. If you want to use a non-standard
 % symbol that is not available through one of the package options, you can
-% redefine these macros inside
-% \cs{makeatletter}\dots\cs{makeatother}. For example,
+% redefine the internal token lists inside
+% \cs{ExplSyntaxOn}\dots\cs{ExplSyntaxOff}. For example,
 % \begin{verbatim}
-%    \makeatletter
-%       \renewcommand*{\Helmholtz at symbol}{H}
-%       \renewcommand*{\enthalpy at symbol}{h}
-%    \makeatother
+%    \ExplSyntaxOn
+%       \tl_gset:Nn \g__thermodynamics_Helmholtz_symbol {H}
+%       \tl_gset:Nn \g__thermodynamics_enthalpy_symbol {h}
+%    \ExplSyntaxOff
 %\end{verbatim}
 % would define the ill-advised notation that I have nonetheless heard of
 % that uses $H$ for Helmholtz free energy and $h$ for enthalpy.
@@ -1553,208 +1787,236 @@
 % capacities; there is no user-level macro for the temperature or the pressure,
 % so it is up to the user to use consistent symbols for those properties.
 %    \begin{macrocode}
-\newcommand*{\totalenergy at symbol}{E}
-\newcommand*{\internalenergy at symbol}{U}
-\newcommand*{\Helmholtz at symbol}{A}
-\newcommand*{\Gibbs at symbol}{G}
-\newcommand*{\Landau at symbol}{\Omega}
-\newcommand*{\enthalpy at symbol}{H}
-\newcommand*{\entropy at symbol}{S}
-\newcommand*{\area at symbol}{a}
-\newcommand*{\volume at symbol}{V}
-\newcommand*{\mole at symbol}{n}
-\newcommand*{\heat at symbol}{Q}
-\newcommand*{\work at symbol}{W}
-\newcommand*{\temperature at symbol}{T}
-\newcommand*{\pressure at symbol}{P}
+\tl_new:N \g_@@_total_energy_symbol
+\tl_new:N \g_@@_internal_energy_symbol
+\tl_new:N \g_@@_Helmholtz_symbol
+\tl_new:N \g_@@_Gibbs_symbol
+\tl_new:N \g_@@_Landau_symbol
+\tl_new:N \g_@@_enthalpy_symbol
+\tl_new:N \g_@@_entropy_symbol
+\tl_new:N \g_@@_area_symbol
+\tl_new:N \g_@@_volume_symbol
+\tl_new:N \g_@@_mole_symbol
+\tl_new:N \g_@@_heat_symbol
+\tl_new:N \g_@@_work_symbol
+\tl_new:N \g_@@_temperature_symbol
+\tl_new:N \g_@@_pressure_symbol
+
+\tl_gset:Nn \g_@@_total_energy_symbol E
+\tl_gset:Nn \g_@@_internal_energy_symbol U
+\tl_gset:Nn \g_@@_Helmholtz_symbol A
+\tl_gset:Nn \g_@@_Gibbs_symbol G
+\tl_gset:Nn \g_@@_Landau_symbol \Omega
+\tl_gset:Nn \g_@@_enthalpy_symbol H
+\tl_gset:Nn \g_@@_entropy_symbol S
+\tl_gset:Nn \g_@@_area_symbol a
+\tl_gset:Nn \g_@@_volume_symbol V
+\tl_gset:Nn \g_@@_mole_symbol n
+\tl_gset:Nn \g_@@_heat_symbol Q
+\tl_gset:Nn \g_@@_work_symbol W
+\tl_gset:Nn \g_@@_temperature_symbol T
+\tl_gset:Nn \g_@@_pressure_symbol P
 %    \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
 %
-% \begin{macro}{\thermo at underline}
-% \begin{macro}{\thermo at overline}
-% We then define two macros and several lengths that we shall use when
+% We then define two functions and several lengths that we shall use when
 % drawing rules above or below a symbol. The default is to use underlined
 % symbols for extensive quantities, plain symbols for molar quantities, and
 % carets for specific quantities, but this can be changed using package
 % options.
-% ^^A TODO these would work better as kern 0.1*width, symbol, kern 0.2*width
+%^^A TODO these might work better as kern 0.1*width, symbol, kern 0.2*width
 %    \begin{macrocode}
-\newcommand*{\thermo at underline}[1]{%
-  \mkern1mu\underline{\mkern-1mu #1\mkern-4mu}\mkern4mu%
-}
-\newcommand*{\thermo at overline}[1]{%
-  \mkern2mu\overline{\mkern-2mu #1\mkern-1mu}\mkern1mu%
-}
+\cs_new:Nn \@@_underline:n
+{ \mkern1mu\underline{\mkern-1mu #1\mkern-4mu}\mkern4mu }
+\cs_new:Nn \@@_overline:n
+{ \mkern2mu\overline{\mkern-2mu #1\mkern-1mu}\mkern1mu }
 %    \end{macrocode}
-% \end{macro}
-% \end{macro}
 %
-% \begin{macro}{\PartialOpen}
-% \begin{macro}{\PartialClose}
-% \begin{macro}{\PartialEmptyClose}
+% \begin{macro}{\PartialOpen,\PartialClose,\PartialEmptyClose}
 % We define three commands to use to denote the beginning and end of partial
 % derivatives. These symbols can be customized by package options. Default
-% is \verb"parentheses", meaning that \verb"\[ \Partial{f}{x}{y} \]" renders as
+% is |parentheses|, meaning that \verb"\[ \Partial{f}{x}{y} \]" renders as
 % \[ \left(\frac{\partial f}{\partial x}\right)_y \]
 % with the defaults. The macro \cs{PartialEmptyClose} is used when the last
-% argument to \cs{Partial} is empty, which is important for the \verb"bar"
-% option to the document class or inside the \verb"thermobar" environment.
+% argument to \cs{Partial} is empty, which is important for the |bar|
+% option to the document class or inside the \env{thermobar} environment.
 %    \begin{macrocode}
-\newcommand*{\PartialOpen}{(}
-\newcommand*{\PartialClose}{)}
-\newcommand*{\PartialEmptyClose}{)}
+\tl_new:N \l_@@_PartialOpen_tl
+\tl_new:N \l_@@_PartialEmptyClose_tl
+\tl_new:N \l_@@_PartialClose_tl
+
+\tl_set:Nn \l_@@_PartialOpen_tl {(}
+\tl_set:Nn \l_@@_PartialClose_tl {)}
+\tl_set:Nn \l_@@_PartialEmptyClose_tl {)}
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
-% \end{macro}
 %
 % \subsection{Package Options}
 % We declare a bunch of options for which sets of symbols to use.
 % These are summarized in Table~\ref{table:symbol-sets}.
+% \changes{v1.01}{2023/09/15}{Changed options with two $E$ or two $A$
+%    variables to use calligraphic letters for the less-common of the two.}
 %    \begin{macrocode}
 \DeclareOption{EUAGHan}{}% the default
-\DeclareOption{EUAGHaN}{\renewcommand*{\mole at symbol}{N}}%
+\DeclareOption{EUAGHaN}{\tl_gset:Nn \g_@@_mole_symbol N}%
 \DeclareOption{EUHAGan}{\ExecuteOptions{EUAGHan}}
 \DeclareOption{EUHAGaN}{\ExecuteOptions{EUAGHaN}}
-\DeclareOption{EUFGHAn}{% this is my favorite set of symbols
-  \renewcommand*{\Helmholtz at symbol}{F}%
-  \renewcommand*{\area at symbol}{A}%
+\DeclareOption{EUFGHAn}{%
+  \tl_gset:Nn \g_@@_Helmholtz_symbol F
+  \tl_gset:Nn \g_@@_area_symbol A
 }
-\DeclareOption{EUFGHAN}{% this is my second favorite set of symbols
-  \renewcommand*{\Helmholtz at symbol}{F}%
-  \renewcommand*{\area at symbol}{A}%
-  \renewcommand*{\mole at symbol}{N}%
+\DeclareOption{EUFGHAN}{%
+  \tl_gset:Nn \g_@@_Helmholtz_symbol F
+  \tl_gset:Nn \g_@@_area_symbol A
+  \tl_gset:Nn \g_@@_mole_symbol N
 }
-\DeclareOption{EEFGHAn}{% this treats all energy the same way(?)
-  \renewcommand*{\internalenergy at symbol}{E}%
-  \renewcommand*{\Helmholtz at symbol}{F}%
-  \renewcommand*{\area at symbol}{A}%
+\DeclareOption{EEFGHAn}{%
+  \tl_gset:Nn \g_@@_total_energy_symbol {\mathcal{E}}
+  \tl_gset:Nn \g_@@_internal_energy_symbol E
+  \tl_gset:Nn \g_@@_Helmholtz_symbol F
+  \tl_gset:Nn \g_@@_area_symbol A
 }
-\DeclareOption{EEFGHAN}{% this treats all energy the same way(?)
-  \renewcommand*{\internalenergy at symbol}{E}%
-  \renewcommand*{\Helmholtz at symbol}{F}%
-  \renewcommand*{\area at symbol}{A}%
-  \renewcommand*{\mole at symbol}{N}%
+\DeclareOption{EEFGHAN}{%
+  \tl_gset:Nn \g_@@_total_energy_symbol {\mathcal{E}}
+  \tl_gset:Nn \g_@@_internal_energy_symbol E
+  \tl_gset:Nn \g_@@_Helmholtz_symbol F
+  \tl_gset:Nn \g_@@_area_symbol A
+  \tl_gset:Nn \g_@@_mole_symbol N
 }
 \DeclareOption{EEFGHan}{%
-  \renewcommand*{\internalenergy at symbol}{E}%
-  \renewcommand*{\Helmholtz at symbol}{F}
+  \tl_gset:Nn \g_@@_total_energy_symbol {\mathcal{E}}
+  \tl_gset:Nn \g_@@_internal_energy_symbol E
+  \tl_gset:Nn \g_@@_Helmholtz_symbol F
 }
 \DeclareOption{EEFGHaN}{%
-  \renewcommand*{\internalenergy at symbol}{E}%
-  \renewcommand*{\Helmholtz at symbol}{F}
-  \renewcommand*{\mole at symbol}{N}%
+  \tl_gset:Nn \g_@@_total_energy_symbol {\mathcal{E}}
+  \tl_gset:Nn \g_@@_internal_energy_symbol E
+  \tl_gset:Nn \g_@@_Helmholtz_symbol F
+  \tl_gset:Nn \g_@@_mole_symbol N
 }
 \DeclareOption{EEAGHan}{%
-  \renewcommand*{\internalenergy at symbol}{E}%
+  \tl_gset:Nn \g_@@_total_energy_symbol {\mathcal{E}}
+  \tl_gset:Nn \g_@@_internal_energy_symbol E
 }
 \DeclareOption{EEAGHaN}{%
-  \renewcommand*{\internalenergy at symbol}{E}%
-  \renewcommand*{\mole at symbol}{N}%
+  \tl_gset:Nn \g_@@_total_energy_symbol {\mathcal{E}}
+  \tl_gset:Nn \g_@@_internal_energy_symbol E
+  \tl_gset:Nn \g_@@_mole_symbol N
 }
-\DeclareOption{EUAGHAn}{% Helmholtz free energy and area look the same here
-  \renewcommand*{\area at symbol}{A}%
+\DeclareOption{EUAGHAn}{%
+  \tl_gset:Nn \g_@@_area_symbol {\mathcal{A}}
 }
-\DeclareOption{EUAGHAN}{% Helmholtz free energy and area look the same here
-  \renewcommand*{\area at symbol}{A}%
-  \renewcommand*{\mole at symbol}{N}%
+\DeclareOption{EUAGHAN}{%
+  \tl_gset:Nn \g_@@_area_symbol {\mathcal{A}}
+  \tl_gset:Nn \g_@@_mole_symbol N
 }
 \DeclareOption{EUFGHan}{%
-  \renewcommand*{\Helmholtz at symbol}{F}%
+  \tl_gset:Nn \g_@@_Helmholtz_symbol F
 }
 \DeclareOption{EUFGHaN}{%
-  \renewcommand*{\Helmholtz at symbol}{F}%
-  \renewcommand*{\mole at symbol}{N}%
+  \tl_gset:Nn \g_@@_Helmholtz_symbol F
+  \tl_gset:Nn \g_@@_mole_symbol N
 }
 %    \end{macrocode}
-% The \verb"delta" option redefines \cs{dbar} to produce the symbol $\delta$.
+% The |delta| option redefines \cs{dbar} to produce the symbol $\delta$.
 % The default is to use a $d$ with a slash through it ($\dbar$) for inexact
 % differentials unless the user overrides it with this option. The macro could
 % also be redefined manually, of course.
 %    \begin{macrocode}
-\DeclareOption{delta}{\let\dbar\delta}
+\DeclareOption{delta}{ \cs_set_eq:NN \dbar \delta }
 %    \end{macrocode}
 %
-% \begin{macro}{\@extensive}
-% \begin{macro}{\@intensive}
-% \begin{macro}{\@specific}
 % Next, we define options for the set of notation. The default is
-% \verb"intensive-plain", which produces things like $V$ for molar volume,
+% |intensive-plain|, which produces things like $V$ for molar volume,
 % $\Vt$ for total volume, and $\hat V$ for specific volume.
-% These are defined via the internal macros \verb"\@extensive",
-% \verb"\@intensive", and \verb"\@specific".
+% The symbols themselves are produced via internal (non-user-facing) macros.
 %    \begin{macrocode}
-\let\@extensive\relax
-\let\@intensive\relax
-\let\@specific\hat
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%    \begin{macrocode}
-\DeclareOption{extensive-plain}{%
-    \let\@extensive\relax
-    \let\@intensive\thermo at underline
+\cs_new:Nn \@@_extensive:n {#1}
+\cs_new:Nn \@@_intensive:n {#1}
+\cs_new:Nn \@@_specific:n {\hat{#1}}
+
+\cs_new:Npn \@@_set_intensive_plain
+{
+  \cs_set:Nn \@@_extensive:n {\@@_underline:n{##1}}
+  \cs_set:Nn \@@_intensive:n {##1}
 }
-\DeclareOption{intensive-plain}{% the default
-    \let\@extensive\thermo at underline
-    \let\@intensive\relax
+\cs_new:Npn \@@_set_extensive_plain
+{
+  \cs_set:Nn \@@_extensive:n {##1}
+  \cs_set:Nn \@@_intensive:n {\@@_underline:n{##1}}
 }
+\cs_new:Npn \@@_set_lowercase_pms
+{
+  \RenewDocumentCommand{\partialmolar}{m}
+  {
+    \tl_set:Nn \l_@@_pm_symbol_tl {\text_lowercase:n {##1}}
+    \@@_generic_pm:
+  }
+}
+\cs_new:Npn \@@_set_intensive_lowercase
+{
+  \cs_set:Nn \@@_extensive:n {\text_uppercase:n {##1}}
+  \cs_set:Nn \@@_intensive:n {\text_lowercase:n {##1}}
+  \cs_set:Nn \@@_specific:n {\hat{\text_lowercase:n {##1}}}
+}
+\cs_new:Npn \@@_set_extensive_superscripts
+{
+  \cs_set:Nn \@@_extensive:n {{##1}\c_math_superscript_token t}
+  \cs_set:Nn \@@_intensive:n {##1}
+}
+\DeclareOption{extensive-plain}{\@@_set_extensive_plain}
+\DeclareOption{intensive-plain}{\@@_set_intensive_plain} % the default
 \DeclareOption{intensive-lowercase}{% PLEASE don't use this!
-    \let\@extensive\MakeUppercase
-    \let\@intensive\MakeLowercase
-    \def\@specific#1{\MakeLowercase{\hat #1}}
-    \AtEndOfPackage{
-        \renewcommand*{\partialmolar}[1]{%
-            \gdef\pm at symbol{\MakeLowercase #1}\generic at pm}
-        \renewcommand*{\heatcapacitysymbol}{c}
-    }
+  \@@_set_intensive_lowercase
+  \AtEndOfPackage{
+    \@@_set_lowercase_pms
+    \RenewDocumentCommand{\heatcapacitysymbol}{}{c}
+  }
 }
 \DeclareOption{extensive-superscript}{%
-    \gdef\@extensive#1{{#1}^t}%
-    \let\@intensive\relax%
-    \AtEndOfPackage{%
-      \renewcommand*{\URt}{\internalenergy at symbol^{\residual,t}}
-      \renewcommand*{\HRt}{\enthalpy at symbol^{\residual,t}}
-      \renewcommand*{\FRt}{\Helmholtz at symbol^{\residual,t}}
-      \renewcommand*{\GRt}{\Gibbs at symbol^{\residual,t}}
-      \renewcommand*{\VRt}{\volume at symbol^{\residual,t}}
-      \renewcommand*{\SRt}{\entropy at symbol^{\residual,t}}
-      \renewcommand*{\UEt}{\internalenergy at symbol^{\excess,t}}
-      \renewcommand*{\HEt}{\enthalpy at symbol^{\excess,t}}
-      \renewcommand*{\FEt}{\Helmholtz at symbol^{\excess,t}}
-      \renewcommand*{\GEt}{\Gibbs at symbol^{\excess,t}}
-      \renewcommand*{\VEt}{\volume at symbol^{\excess,t}}
-      \renewcommand*{\SEt}{\entropy at symbol^{\excess,t}}
-    }
+  \@@_set_extensive_superscripts
+  \AtEndOfPackage{%
+    \RenewDocumentCommand{\URt}{}{\g_@@_internal_energy_symbol
+      \c_math_superscript_token{\residual,t}}
+    \RenewDocumentCommand{\HRt}{}{\g_@@_enthalpy_symbol
+      \c_math_superscript_token{\residual,t}}
+    \RenewDocumentCommand{\FRt}{}{\g_@@_Helmoholtz_symbol
+      \c_math_superscript_token{\residual,t}}
+    \RenewDocumentCommand{\GRt}{}{\g_@@_Gibbs_symbol
+      \c_math_superscript_token{\residual,t}}
+    \RenewDocumentCommand{\VRt}{}{\g_@@_volume_symbol
+      \c_math_superscript_token{\residual,t}}
+    \RenewDocumentCommand{\SRt}{}{\g_@@_entropy_symbol
+      \c_math_superscript_token{\residual,t}}
+    \RenewDocumentCommand{\UEt}{}{\g_@@_internal_energy_symbol
+      \c_math_superscript_token{\excess,t}}
+    \RenewDocumentCommand{\HEt}{}{\g_@@_enthalpy_symbol
+      \c_math_superscript_token{\excess,t}}
+    \RenewDocumentCommand{\FEt}{}{\g_@@_Helmoholtz_symbol
+      \c_math_superscript_token{\excess,t}}
+    \RenewDocumentCommand{\GEt}{}{\g_@@_Gibbs_symbol
+      \c_math_superscript_token{\excess,t}}
+    \RenewDocumentCommand{\VEt}{}{\g_@@_volume_symbol
+      \c_math_superscript_token{\excess,t}}
+    \RenewDocumentCommand{\SEt}{}{\g_@@_entropy_symbol
+      \c_math_superscript_token{\excess,t}}
+  }
 }
 %    \end{macrocode}
 %
 % The next two options choose whether variables held constant are subscripted
-% (the default) or placed next to the function. The \verb"nosubscripts"
-% option currently requires that the variable being changed is the first one
-% in the argument list. The difference is
-% \[ \left(\frac{\partial U}{\partial S}\right)_V \quad\text{versus}\quad
-%    \left(\frac{\partial U(S,V)}{\partial S}\right) \]
+% (the default) or placed next to the function. The difference is
+%%^^A \[ \left(\frac{\partial U}{\partial S}\right)_V \quad\text{versus}\quad
+%%^^A    \left(\frac{\partial U(S,V)}{\partial S}\right) \]
+%  \[ \Partial{\Um}{\Sm}{\Vm} \quad\text{versus}\quad
+%     \begin{thermoNOsubscripts}
+%       \Partial{\Um}{\Sm}{\Vm}
+%     \end{thermoNOsubscripts} \]
 % for \verb"subscripts" and \verb"nosubscripts", respectively.
 %    \begin{macrocode}
-\newif\if at subscripted
-\@subscriptedtrue
-\DeclareOption{subscripts}{\@subscriptedtrue}
-\DeclareOption{nosubscripts}{\@subscriptedfalse}
+\bool_new:N \l_@@_subscripted_bool
+\bool_set_true:N \l_@@_subscripted_bool
+\DeclareOption{subscripts}{\bool_set_true:N \l_@@_subscripted_bool}
+\DeclareOption{nosubscripts}{\bool_set_false:N \l_@@_subscripted_bool}
 %    \end{macrocode}
 % These options change how \cs{Partial} and friends render derivatives.
 % The default is parentheses, but other options include brackets, braces,
@@ -1762,42 +2024,38 @@
 %    \begin{macrocode}
 \DeclareOption{parentheses}{}
 \DeclareOption{brackets}{%
-  \renewcommand*{\PartialOpen}{[}%
-  \renewcommand*{\PartialClose}{]}%
-  \renewcommand*{\PartialEmptyClose}{]}%
+  \tl_set:Nn \l_@@_PartialOpen_tl {[}
+  \tl_set:Nn \l_@@_PartialClose_tl {]}
+  \tl_set:Nn \l_@@_PartialEmptyClose_tl {]}
 }
 \DeclareOption{braces}{%
-  \renewcommand*{\PartialOpen}{\{}%
-  \renewcommand*{\PartialClose}{\}}%
-  \renewcommand*{\PartialEmptyClose}{\}}%
+  \tl_set:Nn \l_@@_PartialOpen_t1 {\{}
+  \tl_set:Nn \l_@@_PartialClose_t1 {\}}
+  \tl_set:Nn \l_@@_PartialEmptyClose_tl {\}}
 }
 \DeclareOption{bar}{%
-  \renewcommand*{\PartialOpen}{.}%
-  \renewcommand*{\PartialClose}{\rvert}%
-  \renewcommand*{\PartialEmptyClose}{.}%
+  \tl_set:Nn \l_@@_PartialOpen_tl {.}
+  \tl_set:Nn \l_@@_PartialClose_tl {\rvert}
+  \tl_set:Nn \l_@@_PartialEmptyClose_tl {.}
 }
 \DeclareOption{plain-derivatives}{% This implies dU(S,V,N)/dS notation
-  \renewcommand*{\PartialOpen}{.}%
-  \renewcommand*{\PartialClose}{.}%
-  \renewcommand*{\PartialEmptyClose}{.}%
-  \ExecuteOptions{nosubscripts}%
+  \tl_set:Nn \l_@@_PartialOpen_tl {.}
+  \tl_set:Nn \l_@@_PartialClose_tl {.}
+  \tl_set:Nn \l_@@_PartialEmptyClose_tl {.}
+  \ExecuteOptions{nosubscripts}
 }
 %    \end{macrocode}
 % \subsection{The Number of Moles Macros}
 % \begin{macro}{\ncomponents}
 % We define the number of components, default $C$, for use in the ``all moles''
-% and related macros.
+% and related macros. The command is expandable so we can perform comparisons
+% to user-entered values.
 %    \begin{macrocode}
-\newcommand*{\ncomponents}{C}
+\NewExpandableDocumentCommand \ncomponents {} {C}
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\allNs}
-% \begin{macro}{\allNsbut}
-% \begin{macro}{\allMs}
-% \begin{macro}{\allmus}
-% \begin{macro}{\allMsbut}
-% \begin{macro}{\allmusbut}
+% \begin{macro}{\allNs,\allXs,\allYs,\allmus,\allMs,\allWs}
 % Several macros define a shorthand for ``moles of all species'' (\cs{allNs})
 % and ``moles of all species except'' (\cs{allNsbut}), as well as similar
 % quantities for masses (\cs{allMs}, \cs{allMsbut}) and chemical potentials
@@ -1811,25 +2069,15 @@
 % masses: \cs{allmus} and \cs{allmusbut} and \cs{allMs} and \cs{allMsbut},
 % respectively.
 %    \begin{macrocode}
-\newcommand*{\allNs}{\allcomponents{\Nt}}
-\newcommand*{\allXs}{\allcomponents{x}}
-\newcommand*{\allYs}{\allcomponents{y}}
-\newcommand*{\allmus}{\allcomponents{\mu}}
-\newcommand*{\allMs}{\allcomponents{m}}
-\newcommand*{\allWs}{\allcomponents{w}}%
+\NewDocumentCommand{\allNs}{O{i}}{\allcomponents[#1]{\Nt}}
+\NewDocumentCommand{\allXs}{O{i}}{\allcomponents[#1]{x}}
+\NewDocumentCommand{\allYs}{O{i}}{\allcomponents[#1]{y}}
+\NewDocumentCommand{\allmus}{O{i}}{\allcomponents[#1]{\mu}}
+\NewDocumentCommand{\allMs}{O{i}}{\allcomponents[#1]{m}}
+\NewDocumentCommand{\allWs}{O{i}}{\allcomponents[#1]{w}}
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \begin{macro}{\allXs}
-% \begin{macro}{\allYs}
-% \begin{macro}{\allWs}
-% \begin{macro}{\allWsbut}
-% \begin{macro}{\allXsbut}
-% \begin{macro}{\allYsbut}
+% \begin{macro}{\allNsbut,\allXsbut,\allYsbut,\allMsbut,\allWsbut}
 % Similar commands are defined for mole fractions (\cs{allXs}, \cs{allYs},
 % etc.), but these assume the last mole fraction is \emph{not} one of the
 % variables---that is, \cs{allXsbut} and \cs{allYsbut} assume the argument
@@ -1842,98 +2090,89 @@
 % \[ \Partial{G}{T}{P,\allXs} = -S \qquad
 %    \Partial{G}{x_i}{T,P,x_{j\neq i,C}} \neq \Gpm{i}. \]
 %    \begin{macrocode}
-\newcommand*{\allNsbut}[2][j]{\allbut[#1]{#2}{\Nt}}
-\newcommand*{\allXsbut}[2][j]{\allbutlastand[#1]{#2}{x}}
-\newcommand*{\allYsbut}[2][j]{\allbutlastand[#1]{#2}{y}}
-\newcommand*{\allmusbut}[2][j]{\allbut[#1]{#2}{\mu}}
-\newcommand*{\allMsbut}[2][j]{\allbut[#1]{#2}{m}}
-\newcommand*{\allWsbut}[2][j]{\allbutlastand[#1]{#2}{w}}%
+\NewDocumentCommand{\allNsbut}{O{j} m} {\allbut[#1]{#2}{\Nt}}
+\NewDocumentCommand{\allXsbut}{O{j} m} {\allbutlastand[#1]{#2}{x}}
+\NewDocumentCommand{\allYsbut}{O{j} m} {\allbutlastand[#1]{#2}{y}}
+\NewDocumentCommand{\allmusbut}{O{j} m} {\allbut[#1]{#2}{\mu}}
+\NewDocumentCommand{\allMsbut}{O{j} m} {\allbut[#1]{#2}{m}}
+\NewDocumentCommand{\allWsbut}{O{j} m} {\allbutlastand[#1]{#2}{w}}
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \begin{macro}{\allbutlastand}
-% \begin{macro}{\allbut}
-% \begin{macro}{\allcomponents}
+% \begin{macro}{\allbutlastand,\allbut,\allcomponents}
+% \changes{v1.01}{10/04/2023}{Updated \cs{allcomponents} to include an
+%   optional argument that changes $N_i$ to $N_j$, say, when using
+%   TesterModell or other options that denote moles of all components that
+%   way. Similar updates to \cs{allNs} and friends.}
 % The \cs{allcomponents}, \cs{allbut}, and \cs{allbutlastand} macros can be
 % used to define new entities; say, if you want to use $z_i$ as a mole
 % fraction, then use
 % \begin{verbatim}
-%   \newcommand*{\allZsbut}[2][j]{\allbutlastand[#1]{#2}{z}}
+%   \NewDocumentCommand{\allZsbut}{O{j} m}{\allbutlastand[#1]{#2}{z}}
 %\end{verbatim}
 % Similarly, something meaning the concentrations of every species could be
 % defined via
 % \begin{verbatim}
-%   \newcommand*{\allCs}{\allcomponents{C}}
+%   \NewDocumentCommand{\allCs}{O{}}{\allcomponents{C}}
 %\end{verbatim}
 %    \begin{macrocode}
-\newcommand*{\allcomponents}[1]{\vec{#1}}
-\newcommand*{\allbut}[3][j]{%
-  \def\tmp at arg{#2}%
-  \def\tmp@@arg{#1}%
-  \ifx\tmp at arg\tmp@@arg
-    {#3}_{k\neq #2}%
-  \else
-    {#3}_{#1\neq #2}%
-  \fi
+\NewDocumentCommand{\allcomponents}{O{} m}{\vec{#2}}
+\NewDocumentCommand{\allbut}{O{j} m m}
+{ \tl_if_eq:nnTF {#1} {#2}
+  { {#3}\c_math_subscript_token{k \neq #2} }
+  { {#3}\c_math_subscript_token{#1 \neq #2} }
 }
-\newcommand*{\allbutlastand}[3][j]{%
-  \edef\tmp at arg{#1}%
-  \edef\tmp@@arg{#2}%
-  \ifx\tmp@@arg\ncomponents
-    {#3}_{#1 \neq #2}%
-  \else
-    \ifx\tmp at arg\tmp@@arg
-      {#3}_{k \neq #2,\ncomponents}%
-    \else
-      {#3}_{#1 \neq #2,\ncomponents}%
-    \fi
-  \fi
+\NewDocumentCommand{\allbutlastand}{O{j} m m}
+{ \tl_if_eq:xxTF {#2} {\ncomponents}
+  { {#3}\c_math_subscript_token{#1 \neq #2} }
+  { \tl_if_eq:nnTF {#1} {#2}
+    { {#3}\c_math_subscript_token{k \neq #2,\ncomponents} }
+    { {#3}\c_math_subscript_token{#1 \neq #2,\ncomponents} }
+  }
 }
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
-% \end{macro}
 %
 % We then define two package options that change how to render \cs{allNs} and
-% friends.
+% friends.\relax
+% \changes{v1.01}{2022/05/04}{Fixed bug in \cs{allbutlastand} when using the
+%   |moles-range| option ($C$ should have been $C-1$ in the last option).}
 %    \begin{macrocode}
 \DeclareOption{moles-index}{}
-\DeclareOption{moles-range}{%
-  \renewcommand*{\allcomponents}[1]{{#1}_1,\dots,{#1}_{\ncomponents}}
-  \renewcommand*{\allbut}[3][j]{%
-    \def\@one{1}%
-    \edef\tmp at arg{#2}%
-    \ifx\tmp at arg\@one
-      {#3}_2,\dots,{#3}_{\ncomponents}%
-    \else
-      \ifx\tmp at arg\ncomponents
-        {#3}_1,\dots,{#3}_{\ncomponents-1}%
-      \else
-        {#3}_1,\dots,[{#3}_{#2}],\dots,{#3}_{\ncomponents}%
-      \fi
-    \fi
+\DeclareOption{moles-range}{ \@@_set_moles_range }
+\cs_new:Npn \@@_set_moles_range {%
+  \RenewDocumentCommand{\allcomponents}{O{} m}
+  { {##2}\c_math_subscript_token 1,\dots,
+        {##2}\c_math_subscript_token{\ncomponents} }
+  \RenewDocumentCommand{\allbut}{O{j} m m}
+  { \tl_if_eq:nnTF {##2} {1}
+    { {##3}\c_math_subscript_token 2,\dots,
+        {##3}\c_math_subscript_token{\ncomponents} }
+    { \tl_if_eq:xxTF {##2} {\ncomponents}
+      { {##3}\c_math_subscript_token 1,\dots,
+          {##3}\c_math_subscript_token{\ncomponents-1} }
+      { {##3}\c_math_subscript_token 1,\dots,
+            [{##3}\c_math_subscript_token{##2}],
+            \dots,{##3}\c_math_subscript_token{\ncomponents} }
+    }
   }
-  \renewcommand*{\allbutlastand}[3][j]{%
-    \def\@one{1}%
-    \edef\tmp at arg{#2}%
-    \edef\@ncminusone{\ncomponents-1}%
-    \ifx\tmp at arg\@one
-      {#3}_2,\dots,{#3}_{\ncomponents-1}%
-    \else
-      \ifx\tmp at arg\@ncminusone
-        {#3}_1,\dots,{#3}_{\ncomponents-2}%
-      \else
-        \ifx\tmp at arg\ncomponents
-          {#3}_1,\dots,{#3}_{\ncomponents-1}%
-      \else
-          {#3}_1,\dots,[{#3}_{#2}],\dots,{#3}_{\ncomponents}%
-        \fi
-      \fi
-    \fi
+  \RenewDocumentCommand{\allbutlastand}{O{j} m m}
+  { \tl_if_eq:nnTF {##2} {1}
+    { {##3}\c_math_subscript_token 2,\dots,
+        {##3}\c_math_subscript_token{\ncomponents-1} }
+    { \tl_if_eq:xxTF {##2} {\ncomponents}
+      { {##3}\c_math_subscript_token 1,\dots,
+        {##3}\c_math_subscript_token{\ncomponents-1}
+      }
+      { \tl_if_eq:xxTF {##2} {\ncomponents-1}
+        { {##3}\c_math_subscript_token 1,\dots,
+          {##3}\c_math_subscript_token{\ncomponents-2} }
+        {
+          {##3}\c_math_subscript_token 1,\dots,
+          [{##3}\c_math_subscript_token{##2}],\dots,
+           {##3}\c_math_subscript_token{\ncomponents-1}
+        }
+      }
+    }
   }
 }
 %    \end{macrocode}
@@ -1941,224 +2180,289 @@
 %    \begin{macrocode}
 \DeclareOption{Bejan}{
   \ExecuteOptions{EUFGHAN,intensive-lowercase,delta}
-  \let\@specific\MakeLowercase
-  \def\@intensive#1{\MakeLowercase{\bar #1}}
-  \AtEndOfPackage{
-    \DeclareSubscrSymbol{cV}{\bar\heatcapacitysymbol}{v}
-    \DeclareSubscrSymbol{cVs}{\heatcapacitysymbol}{v}
-    \DeclareSubscrSymbol{cVt}{\Nt\heatcapacitysymbol}{v}
-    \renewcommand*{\expansivitysymbol}{\beta}
-    \renewcommand*{\ncomponents}{n}
-  }
+  \cs_set:Nn \@@_specific:n {\text_lowercase:n {#1}}
+  \cs_set:Nn \@@_intensive:n {\bar{\text_lowercase:n {#1}}}
+  \tl_gset:Nn \g_@@_volume_symbol v
 }
 \DeclareOption{CBK}{
   \ExecuteOptions{EUAGHAN,intensive-lowercase}
   \AtEndOfPackage{
-    \let\thermo at overline\widetilde
-    \let\@specific\MakeLowercase
-    \renewcommand*{\@intensive}[1]{\MakeLowercase{\bar{#1}}}
-    \renewcommand*{\pressure at symbol}{p}
-    \renewcommand*{\Deltarxn}[1]{#1_R}
-    \renewcommand*{\compressibilitysymbol}{\beta}
-    \renewcommand*{\expansivitysymbol}{\alpha}
+    \cs_set:Nn \@@_overline:n {\widetilde{#1}}
+    \cs_set:Nn \@@_specific:n {\text_lowercase:n {#1}}
+    \cs_set:Nn \@@_intensive:n {\bar{\text_lowercase:n{#1}}}
+    \tl_gset:Nn \g_@@_pressure_symbol p
+    \RenewDocumentCommand{\Deltarxn}{m}{{#1}\c_math_subscript_token R}
+    \RenewDocumentCommand{\compressibilitysymbol}{}{\beta}
+    \RenewDocumentCommand{\expansivitysymbol}{}{\alpha}
   }
 }
 \DeclareOption{ElliottLira}{
   \AtEndOfPackage{
-    \renewcommand*{\allcomponents}[1]{#1}
-    \renewcommand*{\Deltarxn}[1]{\Delta #1}
+    \RenewDocumentCommand{\allcomponents}{O{} m}{#2}
+    \RenewDocumentCommand{\Deltarxn}{m}{\Delta #1}
+    \RenewDocumentCommand{\IG}{}{{\text{ig}}}
+    \RenewDocumentCommand{\IGM}{}{{\text{ig}}}
+    \RenewDocumentCommand{\IS}{}{{\text{is}}}
   }
 }
 \DeclareOption{Koretsky}{
   \ExecuteOptions{EUAGHAn,brackets,intensive-lowercase,delta}
   \AtEndOfPackage{
-    \renewcommand*{\partialmolar}[1]{\gdef\pm at symbol{#1}\generic at pm}
-    \renewcommand*{\expansivitysymbol}{\beta}
-    \renewcommand*{\IS}{{\text{ideal}}}
-    \renewcommand*{\residual}{{\text{dep}}}
-    \renewcommand*{\IG}{{\text{ideal}}}
-    \renewcommand*{\IGM}{{\text{ideal}}}
-    \renewcommand*{\Deltafus}[1]{\Delta{#1}_\fusion}
-    \renewcommand*{\Deltasub}[1]{\Delta{#1}_\sublimation}
-    \renewcommand*{\Deltavap}[1]{\Delta{#1}_\vaporization}
-    \renewcommand*{\Henryrat}{{\mathcal{H}}}
-    \renewcommand*{\gammarat}{\gamma^\text{Henry's}}
-    \let\phipure\varphi
-    \renewcommand*{\phimix}{\hat\varphi}
-    \renewcommand*{\phisat}{\varphi^\sat}
-    \let\Delta at fus@sym\relax
-    \DeclareSubscrSymbol{@Deltafus}{\Delta at fus@sym}{\fusion}
-    \renewcommand*{\Deltafus}[1]{\def\Delta at fus@sym{\Delta #1}\@Deltafus}
-    \let\Delta at vap@sym\relax
-    \DeclareSubscrSymbol{@Deltavap}{\Delta at vap@sym}{\vaporization}
-    \renewcommand*{\Deltasub}[1]{\def\Delta at sub@sym{\Delta #1}\@Deltasub}
-    \let\Delta at sub@sym\relax
-    \DeclareSubscrSymbol{@Deltasub}{\Delta at sub@sym}{\sublimation}
-    \renewcommand*{\Deltasub}[1]{\def\Delta at sub@sym{\Delta #1}\@Deltasub}
+    %^^A Undo part of intensive-lowercase
+    \RenewDocumentCommand{\partialmolar}{m}
+    { \tl_set:Nn \l_@@_pm_symbol_tl {#1}
+      \@@_generic_pm:
+    }
+    \RenewDocumentCommand{\expansivitysymbol}{}{\beta}
+    \RenewDocumentCommand{\IS}{}{{\text{ideal}}}
+    \RenewDocumentCommand{\residual}{}{{\text{dep}}}
+    \RenewDocumentCommand{\IG}{}{{\text{ideal}}}
+    \RenewDocumentCommand{\IGM}{}{{\text{ideal}}}
+    \RenewDocumentCommand{\Henryrat}{}{{\mathcal{H}}}
+    \RenewDocumentCommand{\gammarat}{}
+        {\gamma\c_math_superscript_token\text{Henry's}}
+    \RenewDocumentCommand{\phipure}{}{\varphi}
+    \RenewDocumentCommand{\phimix}{}{\hat\varphi}
+    \RenewDocumentCommand{\phisat}{}{\varphi\c_math_superscript_token\sat}
+    \cs_new:Npn \Delta_fus_sym {} {}
+    \NewSubscriptedSymbol{\Delta_fus}{\Delta_fus_sym}{\fusion}
+    \RenewDocumentCommand{\Deltafus}{m}{
+      \cs_set:Npn \Delta_fus_sym {} { \Delta #1 }
+      \Delta_fus
+    }
+    \cs_new:Npn \Delta_vap_sym {} {}
+    \NewSubscriptedSymbol{\Delta_vap}{\Delta_vap_sym}{\vaporization}
+    \RenewDocumentCommand{\Deltavap}{m}{
+      \cs_set:Npn \Delta_vap_sym {} { \Delta #1 }
+      \Delta_vap
+    }
+    \cs_new:Npn \Delta_sub_sym {} {}
+    \NewSubscriptedSymbol{\Delta_sub}{\Delta_sub_sym}{\sublimation}
+    %^^A Undo part of intensive-lowercase
+    \RenewDocumentCommand{\Deltasub}{m}{
+      \cs_set:Npn \Delta_sub_sym {} { \Delta #1 }
+      \Delta_sub
+    }
   }
 }
 \DeclareOption{MSBB}{
   \ExecuteOptions{EUFGHAn,intensive-lowercase,delta}
   \AtEndOfPackage{
-    \renewcommand*{\IGM}{\ast}
-    \renewcommand*{\IG}{\ast}
-    \renewcommand*{\expansivitysymbol}{\beta}
-    \renewcommand*{\allcomponents}[1]{#1}
-    \renewcommand*{\allbut}[3][j]{%
-      \def\tmp at arg{#2}%
-      \def\tmp@@arg{#1}%
-      \ifx\tmp at arg\tmp@@arg
-        {#3}_{k}%
-      \else
-        {#3}_{#1}%
-      \fi
+    \RenewDocumentCommand{\IGM}{}{\ast}
+    \RenewDocumentCommand{\IG}{}{\ast}
+    \RenewDocumentCommand{\expansivitysymbol}{}{\beta}
+    \RenewDocumentCommand{\allcomponents}{O{} m}{#2}
+    \RenewDocumentCommand{\allbut}{O{j} m m}
+    {
+      \tl_if_eq:nnTF {#1} {#2}
+      { {#3}\c_math_subscript_token k }
+      { {#3}\c_math_subscript_token{#1} }
     }
-    \let\Helmholtz at symbol\psi
-    \renewcommand*{\Ft}{\Psi}
-    \def\@intensive#1{\MakeLowercase{\thermo at overline #1}}
-    \let\@specific\MakeLowercase
-    \renewcommand*{\partialmolar}[1]{\gdef\pm at symbol{#1}\generic at pm}
-    \renewcommand*{\fmix}{\bar f}
-    \renewcommand*{\phimix}{\bar\phi}
-    \renewcommand*{\pressure at symbol}{p}
+    \tl_gset_eq:NN \g_@@_Helmholtz_symbol \psi
+    \RenewDocumentCommand{\Ft}{}{\Psi}
+    \cs_set:Nn \@@_intensive:n {\@@_overline:n{\text_lowercase:n{#1}}}
+    \cs_set:Nn \@@_specific:n {\text_lowercase:n{#1}}
+    \RenewDocumentCommand{\fmix}{}{\bar f}
+    \RenewDocumentCommand{\phimix}{}{\bar\phi}
+    \RenewDocumentCommand{\phimix}{}{\bar\phi}
+    \tl_gset:Nn \g_@@_pressure_symbol p
+    \RenewDocumentCommand{\partialmolar}{m}
+    {
+      \tl_set:Nn \l_@@_pm_symbol_tl {#1}
+      \@@_generic_pm:
+    }
   }
 }
 \DeclareOption{Prausnitz}{
   \ExecuteOptions{intensive-lowercase}
   \AtEndOfPackage{
-    \renewcommand*{\fmix}{f}
-    \let\phimix\phi
-    \renewcommand*{\fsat}{\fpure^\sat}
-    \DeclareSubscrSymbol{fpure}{f}{{\text{pure}}}
-    \DeclareSubscrSymbol{phipure}{\phi}{{\text{pure}}}
-    \renewcommand*{\residual}{{{\mathcal{R}}}}
-    \renewcommand*{\allcomponents}[1]{{#1}_i}
-    \renewcommand*{\allbut}[3][j]{%
-      \def\tmp at arg{#2}%
-      \def\tmp@@arg{#1}%
-      \ifx\tmp at arg\tmp@@arg
-        {#3}_{k}%
-      \else
-        {#3}_{#1}%
-      \fi
+    \RenewDocumentCommand{\fmix}{}{f}
+    \RenewDocumentCommand{\phimix}{}{\phi}
+    \RenewDocumentCommand{\fsat}{}{\fpure\c_math_superscript_token\sat}
+    % TODO: this should pick up H_2 and make it into H_{2,1} (assuming the
+    % solvent is always 1...?)
+    \RenewDocumentCommand{\Henryrat}{}{H}
+    \RenewDocumentCommand{\residual}{}{{{\mathcal{R}}}}
+    \RenewDocumentCommand{\allcomponents}{O{i} m}
+      { {#2}\c_math_subscript_token{#1} }
+    \RenewDocumentCommand{\allbut}{O{i} m m}
+    { \tl_if_eq:nnTF {#1} {#2}
+        { {#3}\c_math_subscript_token k }
+        { {#3}\c_math_subscript_token{#1} }
     }
+    \RenewSubscriptedSymbol{\fpure}{f}{{\text{pure}}}
+    \RenewSubscriptedSymbol{\phipure}{\phi}{{\text{pure}}}
   }
 }
 \DeclareOption{Sandler}{
   \ExecuteOptions{EUAGHaN,extensive-plain}
   \AtEndOfPackage{
-    \renewcommand*{\sat}{{\text{vap}}}
-    \renewcommand*{\excess}{{\text{{ex}}}}
-    \renewcommand*{\residual}{{\text{r}}}
-    \renewcommand*{\ncomponents}{\mathcal{C}}
-    \renewcommand*{\fmix}{\bar f}
-    \renewcommand*{\fstd}{\bar f^\circ}
-    \renewcommand*{\phimix}{\bar\phi}
-    \renewcommand*{\allcomponents}[1]{\thermo at underline{#1}}
-    \renewcommand*{\IG}{{\text{IG}}}
-    \renewcommand*{\IGM}{{\text{IGM}}}
-    \renewcommand*{\IS}{{\text{IM}}}
-    \renewcommand*{\Deltamix}[1]{\Delta_\mixing #1}
-    \renewcommand*{\Deltarxn}[1]{\Delta_\reaction #1}
-    \renewcommand*{\Deltasub}[1]{\Delta_\sublimation #1}
-    \renewcommand*{\Deltafus}[1]{\Delta_\fusion #1}
-    \renewcommand*{\Deltavap}[1]{\Delta_\vaporization #1}
-    \renewcommand*{\Henryrat}{H}
-    \DeclareSubscrSymbol{cV}{\heatcapacitysymbol}{\volume at symbol}
-    \DeclareSubscrSymbol{cP}{\heatcapacitysymbol}{\pressure at symbol}
-    \DeclareSubscrSymbol{cVt}{\Nt\heatcapacitysymbol}{\volume at symbol}
-    \DeclareSubscrSymbol{cPt}{\Nt\heatcapacitysymbol}{\pressure at symbol}
+    \RenewDocumentCommand{\sat}{}{{\text{vap}}}
+    \RenewDocumentCommand{\excess}{}{{\text{ex}}}
+    \RenewDocumentCommand{\residual}{}{{\text{r}}}
+    \RenewExpandableDocumentCommand{\ncomponents}{}{\mathcal{C}}
+    \RenewDocumentCommand{\fmix}{}{\bar f}
+    \RenewDocumentCommand{\fstd}{}{\bar f\c_math_superscript_token\std}
+    \RenewDocumentCommand{\phimix}{}{\bar\phi}
+    \RenewDocumentCommand{\allcomponents}{O{} m}{\@@_underline:n{#2}}
+    \RenewDocumentCommand{\IG}{}{{\text{IG}}}
+    \RenewDocumentCommand{\IGM}{}{{\text{IGM}}}
+    \RenewDocumentCommand{\IS}{}{{\text{IM}}}
+    \RenewDocumentCommand{\Deltamix}{m}
+        {\Delta\c_math_subscript_token\mixing #1}
+    \RenewDocumentCommand{\Deltarxn}{m}
+        {\Delta\c_math_subscript_token\reaction #1}
+    \RenewDocumentCommand{\Deltasub}{m}
+        {\Delta\c_math_subscript_token\sublimation #1}
+    \RenewDocumentCommand{\Deltafus}{m}
+        {\Delta\c_math_subscript_token\fusion #1}
+    \RenewDocumentCommand{\Deltavap}{m}
+        {\Delta\c_math_subscript_token\vaporization #1}
+    \RenewDocumentCommand{\Henryrat}{}{H}
+    \RenewSubscriptedSymbol{\cV}
+        {\heatcapacitysymbol}{\g_@@_volume_symbol}
+    \RenewSubscriptedSymbol{\cP}
+        {\heatcapacitysymbol}{\g_@@_pressure_symbol}
+    \RenewSubscriptedSymbol{\cVt}
+        {\Nt\heatcapacitysymbol}{\g_@@_volume_symbol}
+    \RenewSubscriptedSymbol{\cPt}
+        {\Nt\heatcapacitysymbol}{\g_@@_pressure_symbol}
   }
 }
 \DeclareOption{SVNAS}{
   \ExecuteOptions{extensive-superscript}
   \AtEndOfPackage{
-    \renewcommand*{\allcomponents}[1]{#1}
-    \renewcommand*{\allbut}[3][j]{%
-      \def\tmp at arg{#2}%
-      \def\tmp@@arg{#1}%
-      \ifx\tmp at arg\tmp@@arg
-        {#3}_{k}%
-      \else
-        {#3}_{#1}%
-      \fi
+    \RenewDocumentCommand{\allcomponents}{O{} m}{#2}
+    \RenewDocumentCommand{\allbut}{O{j} m m}
+    {
+      \tl_if_eq:nnTF {#1} {#2}
+      { {#3}\c_math_subscript_token k }
+      { {#3}\c_math_subscript_token{#1} }
     }
-    \renewcommand*{\IG}{{ig}}
-    \renewcommand*{\IGM}{{ig}}
-    \renewcommand*{\IS}{{id}}
-    \renewcommand*{\expansivitysymbol}{\beta}
-    \renewcommand*{\Deltarxn}[1]{\Delta #1}
-    \DeclareSubscrSymbol{cVt}{\Nt\heatcapacitysymbol}{\volume at symbol}
-    \DeclareSubscrSymbol{cPt}{\Nt\heatcapacitysymbol}{\pressure at symbol}
+    \RenewDocumentCommand{\IG}{}{{ig}}
+    \RenewDocumentCommand{\IGM}{}{{ig}}
+    \RenewDocumentCommand{\IS}{}{{id}}
+    \RenewDocumentCommand{\expansivitysymbol}{}{\beta}
+    \RenewDocumentCommand{\Deltarxn}{m}{\Delta #1}
+    \RenewSubscriptedSymbol{\cVt}
+        {\Nt\heatcapacitysymbol}{\g_@@_volume_symbol}
+    \RenewSubscriptedSymbol{\cPt}
+        {\Nt\heatcapacitysymbol}{\g_@@_pressure_symbol}
   }
 }
 \DeclareOption{TesterModell}{
   \ExecuteOptions{EUAGHaN,delta}
   \AtEndOfPackage{
-    \renewcommand*{\ncomponents}{n}
-    \renewcommand*{\allcomponents}[1]{{#1}_i}
-    \renewcommand*{\allbut}[3][j]{%
-      \def\tmp at arg{#2}%
-      \def\tmp@@arg{#1}%
-      \ifx\tmp at arg\tmp@@arg
-        {#3}_k\relax[#2]
-      \else
-        {#3}_{#1}\relax[#2]
-      \fi
+    \RenewExpandableDocumentCommand{\ncomponents}{}{n}
+    \RenewDocumentCommand{\allcomponents}{O{i} m}
+    {
+      {#2}\c_math_subscript_token{#1}
     }
-    \renewcommand*{\allbutlastand}[3][j]{%
-      \edef\tmp at arg{#1}%
-      \edef\tmp@@arg{#2}%
-      \ifx\tmp@@arg\ncomponents
-        {#3}_{#1}\relax[#2]%
-      \else
-        \ifx\tmp at arg\tmp@@arg
-          {#3}\relax[#2,\ncomponents]%
-        \else
-          {#3}\relax[#2,\ncomponents]%
-        \fi
-      \fi
+    \RenewDocumentCommand{\allbut}{O{i} m m}
+    { \tl_if_eq:nnTF {#1} {#2}
+      { {#3}\c_math_subscript_token{k}[#2] }
+      { {#3}\c_math_subscript_token{#1}[#2] }
     }
-    \renewcommand*{\IG}{{ig}}
-% Tester & Modell never use "igm" anywhere, and I only found ig once
-    \renewcommand*{\IGM}{{igm}}
-    \renewcommand*{\IS}{{ID}}
-    \renewcommand*{\excess}{{EX}}%
-    \renewcommand*{\reaction}{{rx}}
-    \renewcommand*{\Henryrat}{f^{\ast\ast}}
-    \renewcommand*{\Henrymol}{f^\ast}
-    \renewcommand*{\gammarat}{\gamma^{\ast\ast}}
-    \renewcommand*{\gammamol}{\gamma^\ast}
+    \RenewDocumentCommand{\allbutlastand}{O{j} m m}
+    { \tl_if_eq:xxTF {#2} {\ncomponents}
+      { {#3}\c_math_subscript_token{#1}\relax[#2] }
+      { \tl_if_eq:nnTF {#1} {#2}
+        { {#3}\c_math_subscript_token{k}[#2,\ncomponents] }
+        { {#3}\c_math_subscript_token{#1}[#2,\ncomponents] }
+      }
+    }
+    \RenewDocumentCommand{\IG}{}{{o}}
+    \RenewDocumentCommand{\IGM}{}{{o}}
+    \RenewDocumentCommand{\IS}{}{{ID}}
+    \RenewDocumentCommand{\excess}{}{{EX}}
+    \RenewDocumentCommand{\reaction}{}{{rx}}
+    \RenewDocumentCommand{\Henryrat}{}
+        {f\c_math_superscript_token{\ast\ast}}
+    \RenewDocumentCommand{\Henrymol}{}{f\c_math_superscript_token\ast}
+    \RenewDocumentCommand{\gammarat}{}
+        {\gamma\c_math_superscript_token{\ast\ast}}
+    \RenewDocumentCommand{\gammamol}{}
+        {\gamma\c_math_superscript_token\ast}
+    \RenewExpandableDocumentCommand{\JTsymbol}{}{\alpha}
+    \RenewSubscriptedSymbol{\muJT}{\JTsymbol}{H}
   }
 }
 \DeclareOption{Thompson}{
   \ExecuteOptions{EUAGHAn,delta}
-  \AtEndOfPackage{
-    \renewcommand*{\excess}{{EX}}
-    \renewcommand*{\residual}{{R}}
-    \renewcommand*{\allcomponents}[1]{{#1}_j}
-    \renewcommand*{\ncomponents}{c}
-    \renewcommand*{\IS}{{IS}}
-    \renewcommand*{\IG}{{IG}}
-    \let\IGM\IG
-    \def\@fpure_#1{f_{#1}\@ifnextchar^{}{^\bullet}}
-    \renewcommand*{\fpure}{\@ifnextchar_{\@fpure}{f}}
-    \def\@phi at pure_#1{\phi_{#1}\@ifnextchar^{}{^\bullet}}
-    \renewcommand*{\phipure}{\@ifnextchar_{\@phi at pure}{\phi}}
-    \renewcommand*{\mixing}{{MIX}}
-    \renewcommand*{\Deltamix}[1]{\Delta_\mixing #1}
-    \renewcommand*{\Deltarxn}[1]{\Delta #1}
-    \def\@@intensive_#1{_{#1}\@ifnextchar^{}{^\bullet}}
-    \newcommand*{\@intensive}[1]{#1\@ifnextchar_{\@@intensive}{}}
-    \renewcommand*{\allbut}[3][j]{%
-      \def\tmp at arg{#2}%
-      \def\tmp@@arg{#1}%
-      \ifx\tmp at arg\tmp@@arg
-        {#3}_{k}\neq{#3}_{#2}%
-      \else
-        {#3}_{#1}\neq{#3}_{#2}%
-      \fi
+  \AtEndOfPackage
+  {
+    \RenewDocumentCommand{\excess}{}{{EX}}
+    \RenewDocumentCommand{\residual}{}{{R}}
+    %^^A He uses k_H for both types of Henry's constant, but I changed
+    %^^A the rational basis one just so there is SOME difference
+    \RenewSubscriptedSymbol{\Henryrat}{k}{h}
+    \RenewSubscriptedSymbol{\Henrymol}{k}{H}
+    \RenewDocumentCommand{\allcomponents}{O{j} m}
+    {
+      {#2}\c_math_subscript_token{#1}
     }
+    \RenewDocumentCommand{\allNs}{O{j}}{\allcomponents[#1]{\Nt}}
+    \RenewDocumentCommand{\allXs}{O{j}}{\allcomponents[#1]{x}}
+    \RenewDocumentCommand{\allYs}{O{j}}{\allcomponents[#1]{y}}
+    \RenewDocumentCommand{\allmus}{O{j}}{\allcomponents[#1]{\mu}}
+    \RenewDocumentCommand{\allMs}{O{j}}{\allcomponents[#1]{m}}
+    \RenewDocumentCommand{\allWs}{O{j}}{\allcomponents[#1]{w}}
+    \RenewExpandableDocumentCommand{\ncomponents}{}{c}
+    \RenewDocumentCommand{\IS}{}{{IS}}
+    \RenewDocumentCommand{\IG}{}{{IG}}
+    \RenewDocumentCommand{\IGM}{}{{IG}}
+    \cs_new:Nn \@@_fpure_one:n
+    {
+      f\c_math_subscript_token{#1}
+      \peek_catcode_remove:NF \c_math_superscript_token
+      { \c_math_superscript_token\bullet }
+    }
+    \RenewDocumentCommand{\fpure}{}
+    {
+      \peek_catcode_remove:NTF \c_math_subscript_token
+      { \@@_fpure_one:n }
+      { f }
+    }
+    \cs_new:Nn \@@_intensive_two:n
+    {
+      \c_math_subscript_token{#1}
+      \peek_catcode:NF \c_math_superscript_token
+      {
+        \c_math_superscript_token\bullet
+      }
+    }
+    \cs_set:Nn \@@_intensive:n
+    { #1
+      \peek_catcode_remove:NT \c_math_subscript_token
+      { \@@_intensive_two:n }
+    }
+    \cs_new:Nn \@@_phipure_one:n
+    {
+      \phi\c_math_subscript_token{#1}
+      \peek_catcode:NF \c_math_superscript_token
+      { \c_math_superscript_token\bullet }
+    }
+    \RenewDocumentCommand{\phipure}{}
+    {
+      \peek_catcode_remove:NTF \c_math_subscript_token
+      {
+        \@@_phipure_one:n
+      }
+      {\phi}
+    }
+    \RenewDocumentCommand{\mixing}{}{{MIX}}
+    \RenewDocumentCommand{\Deltamix}{m}
+        {\Delta\c_math_subscript_token\mixing #1}
+    \RenewDocumentCommand{\Deltarxn}{m}{\Delta #1}
+    \RenewDocumentCommand{\allbut}{O{j} m m}
+    { \tl_if_eq:nnTF {#1} {#2}
+      {
+        {#3}\c_math_subscript_token k\neq{#3}\c_math_subscript_token{#2}
+      }
+      {
+        {#3}\c_math_subscript_token{#1}\neq{#3}\c_math_subscript_token{#2}
+      }
+    }
   }
 }
 %    \end{macrocode}
@@ -2167,6 +2471,50 @@
 \ExecuteOptions{EUAGHan,subscripts,parentheses,intensive-plain,moles-index}
 \ProcessOptions
 %    \end{macrocode}
+% We next encode a routine to sort non-subscripted variables into a consistent
+% order. It currently does not sort variables with subscripts.
+% \changes{v2.00}{2023/11/16}{Added a sorting routine to make function
+%       arguments be in a consistent order using the |nosubscripts| option.}
+%    \begin{macrocode}
+\tl_const:Nn \c_@@_sort_order_tl
+    {\Et\Em\Es\Ut\Um\Us\Ht\Hm\Hs\Ft\Fm\Fs\Gt\Gm\Gs\Lt\Lm\Ls T\St\Sm\Ss
+        P\Vt\Vm\Vs\mu\Nt mwxyz\At\Am\As\sigma
+        ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklnopqrstuvwxyz}
+\clist_new:N \l_@@_in_list_clist
+\clist_new:N \l_@@_sorted_list_clist
+\clist_new:N \l_@@_remaining_list_clist
+\cs_new:Nn \@@_sort_clist:n
+{% Sort the list in the order of \c_@@_sort_order_tl
+
+  % Wipe out any remnants from the last sort
+  \clist_clear:N \l_@@_in_list_clist
+  \clist_clear:N \l_@@_sorted_list_clist
+
+  % Make a copy of the list
+  \clist_set:Nn \l_@@_remaining_list_clist {#1}
+
+  % Make a list of everything that's in the known sort order list
+  % and put everything else in the "not in sort order list" list.
+  \tl_map_inline:Nn \c_@@_sort_order_tl
+  {
+    \clist_if_in:NnT \l_@@_remaining_list_clist {##1}
+    { \clist_put_right:Nn \l_@@_in_list_clist {##1} }
+
+    \clist_remove_all:Nn \l_@@_remaining_list_clist {##1}
+  }
+
+  % Then merge the lists back together again.
+  \clist_if_empty:NF \l_@@_in_list_clist
+  {
+    \clist_put_right:Nn \l_@@_sorted_list_clist \l_@@_in_list_clist
+  }
+  \clist_if_empty:NF \l_@@_remaining_list_clist
+  {
+    \clist_put_right:Nn \l_@@_sorted_list_clist \l_@@_remaining_list_clist
+  }
+  \clist_use:Nn \l_@@_sorted_list_clist ,
+}
+%    \end{macrocode}
 %
 % \subsection{Commands for Partial Derivatives}
 % The \cs{Partial} command and its second-order siblings are defined as below.
@@ -2177,423 +2525,710 @@
 % The starred forms adjust the spacing after the partial derivative so the
 % trailing binary operator (assumed to be the same width as an equals sign)
 % overhangs the variables held constant.
-% We thus set \verb"operator at width" to be \emph{just} greater than the width of
+% We thus set \verb"operator_width" to be \emph{just} greater than the width of
 % an equals sign.
-%^^A 3/1/2022: changed adjust at width to 2pt (up from 1pt)
-%^^A 4/21/2022: changed adjust at width to 0.1\operator at width (from 2pt)
 %    \begin{macrocode}
-\newlength{\Partial at const@width}
-\newlength{\operator at width}
-\settowidth{\operator at width}{=}
-\newlength{\adjust at width}
-\setlength{\adjust at width}{0.1\operator at width}
-\addtolength{\operator at width}{\adjust at width}
+\dim_new:N \l_@@_Partial_const_dim
+\dim_new:N \l_@@_operator_width_dim
+\dim_new:N \l_@@_adjust_width_dim
+\settowidth{\l_@@_operator_width_dim}{=}
+\dim_set:Nn \l_@@_adjust_width_dim {0.1\l_@@_operator_width_dim}
+\dim_add:Nn \l_@@_operator_width_dim \l_@@_adjust_width_dim
 %    \end{macrocode}
-% \begin{macro}{\Partial*}
 % \begin{macro}{\Partial}
 % The command \cs{Partial} and its friends drastically simplify the creation
 % of partial derivatives. The command \cs{Partial*} is the same as
 % \cs{Partial} except that it adjusts the spacing so the (presumably) binary
 % operator that follows it slightly overlaps the subscripts.
+% \changes{v1.01}{2022/03/01}{Changed \cs{adjust at width} to 2pt (up from 1pt)}
+% \changes{v1.01}{2022/04/21}{Changed \cs{adjust at width} 0.1\cs{operator at width}
+%   (from 2pt)}
+% \changes{v2.00}{2023/11/16}{Changed length added to
+%   \cs{l_@@_Partial_const_dim} from $-0.15$ to $-0.20$}
 %    \begin{macrocode}
-\def\Partial at start{\left\PartialOpen}
-\def\Partial at end{\right\PartialClose}
-\def\Partial at empty@end{\right\PartialEmptyClose}
-\def\Partial{\@ifstar\Partial at star\Partial at nostar}
-%^^A Several ifs to use later (breaks it if these definitions are inside)
-\newif\iftwo at has@Nt
-\two at has@Ntfalse
-\newif\iftwo at has@xory
-\two at has@xoryfalse
-\newif\ifthree at has@Nt
-\three at has@Ntfalse
-\newif\ifthree at has@xory
-\three at has@xoryfalse
-\AtEndOfPackage{%
-  \edef\thermo at Nt{\Nt}%
-  \edef\thermo at x{x}%
-  \edef\thermo at y{y}%
-}
-\def\thermo at parse@two#1\relax{%
-  \@tfor\@i:=#1\do{%
-    \edef\@@i{\@i}%
-    \ifx\@@i\thermo at Nt
-      \two at has@Nttrue
-      \@break at tfor
-    \fi
-    \ifx\@@i\thermo at x
-      \two at has@xorytrue
-      \@break at tfor
-    \fi
-    \ifx\@@i\thermo at y
-      \two at has@xorytrue
-      \@break at tfor
-    \fi
+\tl_new:N \l_@@_Partial_start_tl
+\tl_new:N \l_@@_Partial_end_tl
+\tl_new:N \l_@@_Partial_empty_end_tl
+\tl_new:N \l_@@_Partial_middle_tl
+\tl_set:Nn \l_@@_Partial_start_tl {\left\l_@@_PartialOpen_tl}
+\tl_set:Nn \l_@@_Partial_end_tl {\right\l_@@_PartialClose_tl}
+\tl_set:Nn \l_@@_Partial_empty_end_tl {\right\l_@@_PartialEmptyClose_tl}
+\tl_set:Nn \l_@@_Partial_middle_tl {\middle}
+\cs_set_eq:NN \@@_frac:nn \frac
+\NewDocumentCommand{\Partial}{s m m m}
+{ \bool_if:nTF {#1}
+  {% Starred form (recursive)
+    \settowidth{\l_@@_Partial_const_dim}{\ensuremath{#4}}%
+    \dim_add:Nn \l_@@_Partial_const_dim {-0.20\l_@@_Partial_const_dim}%
+    \Partial{#2}{#3}{#4}%
+    \bool_if:NT \l_@@_subscripted_bool
+    { \dim_compare:nNnTF \l_@@_operator_width_dim
+                       < \l_@@_Partial_const_dim
+      { \kern -\l_@@_operator_width_dim }
+      { \kern -\l_@@_Partial_const_dim }
+    }
   }
+  {% Unstarred form
+    \bool_if:NTF \l_@@_subscripted_bool
+    {% Handle case of empty variables held constant
+      \tl_if_eq:nnTF {#4} {}
+      { \l_@@_Partial_start_tl
+        \@@_frac:nn{\partial #2}{\partial #3}\l_@@_Partial_empty_end_tl
+      }
+      { \l_@@_Partial_start_tl\@@_frac:nn{\partial #2}
+                                         {\partial #3}\l_@@_Partial_end_tl
+        \c_math_subscript_token{#4}%
+      }
+    }
+    {% Check whether #4 contains \allNsbut{i} and #3 is \Nt_i
+      \tl_if_in:nnTF {#3} {\Nt}
+      { \RenewDocumentCommand{\allbut}{O{j} m m}{\allcomponents{##3}}
+        \l_@@_Partial_start_tl
+        \@@_frac:nn{\partial #2(\@@_sort_clist:n{#4})}
+                   {\partial #3}\l_@@_Partial_end_tl
+      }
+      { \l_@@_Partial_start_tl
+        \@@_frac:nn{\partial #2(\@@_sort_clist:n{#3,#4})}
+                   {\partial #3}\l_@@_Partial_end_tl
+      }
+    }
+  }
 }
-\newcommand*{\Partial at nostar}[3]{%
-  \def\tmp at arg{#3}%
-  \if at subscripted
-    % Handles situation of empty variables held constant
-    \ifx\tmp at arg\@empty
-      \ensuremath{\Partial at start\frac{\partial #1}
-                                     {\partial #2}\Partial at empty@end}%
-    \else
-      \ensuremath{\Partial at start\frac{\partial #1}
-                                     {\partial #2}\Partial at end_{#3}}%
-    \fi
-  \else
-    % If not subscripted, we put the arguments (if any) in the derivative
-    \ifx\tmp at arg\@empty
-      \ensuremath{\Partial at start\frac{\partial #1}
-                                     {\partial #2}\Partial at empty@end}%
-    \else
-      % Check for whether #3 contains \allNsbut{i}/etc. and #2 is \Nt_i/etc.
-      \thermo at parse@two#2\relax
-      \iftwo at has@Nt
-        \renewcommand*{\allbut}[3][j]{\allcomponents{##3}}%
-        \ensuremath{\Partial at start\frac{\partial #1(#3)}
-                                       {\partial #2}\Partial at end}%
-      \else
-        \iftwo at has@xory
-          \renewcommand*{\allbutlastand}[3][j]{\allbut{\ncomponents}{##3}}%
-          \ensuremath{\Partial at start\frac{\partial #1(#3)}
-                                         {\partial #2}\Partial at end}%
-        \else
-          \ensuremath{\Partial at start\frac{\partial #1(#2,#3)}
-                                         {\partial #2}\Partial at end}%
-        \fi
-      \fi
-    \fi
-  \fi
-}
-\newcommand*{\Partial at star}[3]{%
-  \settowidth{\Partial at const@width}{\ensuremath{#3}}%
-  \addtolength{\Partial at const@width}{-0.15\Partial at const@width}%
-  \Partial at nostar{#1}{#2}{#3}%
-  \if at subscripted
-    \ifdim\operator at width<\Partial at const@width
-      \kern -\operator at width
-    \else
-      \kern -\Partial at const@width
-    \fi
-  \fi
-}
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
 %
 % \begin{macro}{\PartialBigg}
-% \begin{macro}{\PartialBigg*}
-% The \cs{PartialBigg} macro (and its starred form) replace the \cs{left}
-% and \cs{right} commands in \cs{Partial} with \verb"amsmath"'s \cs{Biggl}
-% and \cs{Biggr} variants. The starred form is inherited from \cs{Partial}
+% The \cs{PartialBigg} macro (and its starred form) replace the \tn{left}
+% and \tn{right} commands in \cs{Partial} with \pkg{amsmath}'s \tn{Biggl}
+% and \tn{Biggr} variants. The starred form is inherited from \cs{Partial}
 % without modification.
 %    \begin{macrocode}
-\def\PartialBigg{%
-  \def\Partial at start{\Biggl\PartialOpen}%
-  \def\Partial at end{\Biggr\PartialClose}%
-  \def\Partial at empty@end{\Biggr\PartialClose}%
-  \Partial%
-}
+\NewDocumentCommand{\PartialBigg}{}
+  { \tl_set:Nn \l_@@_Partial_start_tl {\Biggl\l_@@_PartialOpen_tl}
+    \tl_set:Nn \l_@@_Partial_end_tl {\Biggr\l_@@_PartialClose_tl}
+    \tl_set:Nn \l_@@_Partial_Empty_end_tl
+        {\Biggr\l_@@_PartialEmptyClose_tl}
+    \Partial
+  }
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
 % \begin{macro}{\Partialbigg}
-% \begin{macro}{\Partialbigg*}
 % The \cs{Partialbigg} macro does the same thing as \cs{PartialBigg}, except
-% using \verb"amsmath"'s \cs{biggl}/\cs{biggr} variants.
+% using \pkg{amsmath}'s \tn{biggl}/\tn{biggr} variants.
 %    \begin{macrocode}
-\def\Partialbigg{%
-  \def\Partial at start{\biggl\PartialOpen}%
-  \def\Partial at end{\biggr\PartialClose}%
-  \def\Partial at empty@end{\biggr\PartialClose}%
-  \Partial%
-}
+\NewDocumentCommand{\Partialbigg}{}
+  { \tl_set:Nn \l_@@_Partial_start_tl {\biggl\l_@@_PartialOpen_tl}
+    \tl_set:Nn \l_@@_Partial_end_tl {\biggr\l_@@_PartialClose_tl}
+    \tl_set:Nn \l_@@_Partial_empty_end_tl
+        {\biggr\l_@@_PartialEmptyClose_tl}
+    \Partial
+  }
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
 %
 % \begin{macro}{\PartialSecond}
-% \begin{macro}{\PartialSecond*}
 % The second partial derivatives are defined similarly to \cs{Partial}.
 %    \begin{macrocode}
-\def\PartialSecond{\@ifstar\PartialSecond at star\PartialSecond at nostar}
-\newcommand*{\PartialSecond at nostar}[3]{%
-  \def\tmp at arg{#3}%
-  \if at subscripted
-  % Handles situation of empty variables held constant
-    \ifx\tmp at arg\@empty
-        \ensuremath{\Partial at start\frac{\partial^2 #1}
-                                       {\partial #2^2}\Partial at empty@end}%
-    \else
-        \ensuremath{\Partial at start\frac{\partial^2 #1}
-                                       {\partial #2^2}\Partial at end_{#3}}%
-    \fi
-  \else
-    \ifx\tmp at arg\@empty
-        \ensuremath{\Partial at start\frac{\partial^2 #1}
-                                       {\partial #2^2}\Partial at empty@end}%
-    \else
-      % Check for whether #3 contains \allNsbut{i}/etc. and #2 is \Nt_i/etc.
-      \thermo at parse@two#2\relax
-      \iftwo at has@Nt
-        \renewcommand*{\allbut}[3][j]{\allcomponents{##3}}%
-        \ensuremath{\Partial at start\frac{\partial^2 #1(#3)}
-                                       {\partial #2^2}\Partial at end}%
-      \else
-        \iftwo at has@xory
-          \renewcommand*{\allbutlastand}[3][j]{\allbut{\ncomponents}{##3}}%
-          \ensuremath{\Partial at start\frac{\partial^2 #1(#3)}
-                                         {\partial #2^2}\Partial at end}%
-        \else
-          \ensuremath{\Partial at start\frac{\partial^2 #1(#2,#3)}
-                                         {\partial {#2}^2}\Partial at end}%
-        \fi
-      \fi
-    \fi
-  \fi
+\NewDocumentCommand{\PartialSecond}{s m m m}
+{
+  \bool_if:nTF {#1}
+  {% Starred form
+    \settowidth{\l_@@_Partial_const_dim}{\ensuremath{#4}}%
+    \dim_add:Nn \l_@@_Partial_const_dim {-0.20\l_@@_Partial_const_dim}
+    \PartialSecond{#2}{#3}{#4}%
+    \bool_if:nT \l_@@_subscripted_bool
+    {  \dim_compare:nNnTF {\l_@@_operator_width_dim}
+                        < {\l_@@_Partial_const_dim}
+      { \kern -\l_@@_operator_width_dim }
+      { \kern -\l_@@_Partial_const_dim }
+    }
+  }
+  {% Unstarred form
+    \bool_if:NTF \l_@@_subscripted_bool
+    {% Handles case of empty variables held constant
+      \tl_if_eq:nnTF {#4} {}
+      { \l_@@_Partial_start_tl
+            \@@_frac:nn{\partial\c_math_superscript_token 2 #2}
+        {\partial #3\c_math_superscript_token 2}\l_@@_Partial_empty_end_tl
+      }
+      { \l_@@_Partial_start_tl
+        \@@_frac:nn{\partial\c_math_superscript_token 2 #2}
+            {\partial #3\c_math_superscript_token 2}\l_@@_Partial_end_tl
+            \c_math_subscript_token{#4}%
+      }
+    }
+    {% Check whether #4 contains \allNsbut{i} and #3 is \Nt_i
+      \tl_if_in:nnTF {#2} {\Nt}
+      { \RenewDocumentCommand{\allbut}{O{j} m m}{\allcomponents{##3}}
+        \l_@@_Partial_start_tl
+        \@@_frac:nn{\partial\c_math_superscript_token 2 #2(#4)}
+            {\partial\c_math_superscript_token 2 #3}\l_@@_Partial_end_tl
+      }
+      { \l_@@_Partial_start_tl
+        \@@_frac:nn{\partial\c_math_superscript_token 2
+                      #2(\@@_sort_clist:n{#3,#4})}
+            {\partial #3\c_math_superscript_token 2}\l_@@_Partial_end_tl
+      }
+    }
+  }
 }
-\newcommand*{\PartialSecond at star}[3]{%
-    \settowidth{\Partial at const@width}{\ensuremath{#3}}%
-    \addtolength{\Partial at const@width}{-0.15\Partial at const@width}%
-    \PartialSecond at nostar{#1}{#2}{#3}%
-    \if at subscripted
-      \ifdim\operator at width<\Partial at const@width
-        \kern -\operator at width
-      \else
-        \kern -\Partial at const@width
-      \fi
-    \fi
-}
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
 % \begin{macro}{\PartialSecondBigg}
-% \begin{macro}{\PartialSecondBigg*}
 % The \cs{PartialSecondBigg} macro and its starred variant replace \cs{left}
-% and \cs{right} with \verb"amsmath"'s \cs{Biggl} and \cs{Biggr}.
+% and \tn{right} with \pkg{amsmath}'s \cs[module=amsmath]{Biggl} and
+% \cs[module=amsmath]{Biggr}.
 %    \begin{macrocode}
-\def\PartialSecondBigg{%
-  \def\Partial at start{\expandafter\Biggl\PartialOpen}%
-  \def\Partial at end{\expandafter\Biggr\PartialClose}%
-  \PartialSecond%
+\NewDocumentCommand{\PartialSecondBigg}{}
+{ \tl_set:Nn \l_@@_Partial_start_tl {\biggl\l_@@_PartialOpen_tl}
+  \tl_set:Nn \l_@@_Partial_end_tl {\biggl\l_@@_PartialClose_tl}
+  \tl_set:Nn \l_@@_Partial_empty_end_tl {\biggl\l_@@_PartialClose_tl}
+  \PartialSecond
 }
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
 % \begin{macro}{\PartialSecondbigg}
-% \begin{macro}{\PartialSecondbigg*}
-% The \cs{PartialSecondbigg} macro and its starred variant replace \cs{left}
-% and \cs{right} with \verb"amsmath"'s \cs{biggl} and \cs{biggr}.
+% The \cs{PartialSecondbigg} macro and its starred variant replace \tn{left}
+% and \tn{right} with \pkg{amsmath}'s \cs[module=amsmath]{biggl} and
+% \cs[module=amsmath]{biggr}.
 %    \begin{macrocode}
-\def\PartialSecondbigg{%
-  \def\Partial at start{\expandafter\biggl\PartialOpen}%
-  \def\Partial at end{\expandafter\biggr\PartialClose}%
-  \PartialSecond%
+\NewDocumentCommand{\PartialSecondbigg}{}
+{ \tl_set:Nn \l_@@_Partial_start_tl {\biggl\l_@@_PartialOpen_tl}
+  \tl_set:Nn \l_@@_Partial_end_tl {\biggl\l_@@_PartialClose_tl}
+  \tl_set:Nn \l_@@_Partial_empty_end_tl {\biggl\l_@@_PartialClose_tl}
+  \PartialSecond
 }
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
 %
 % \begin{macro}{\PartialMixSecond}
-% \begin{macro}{\PartialMixSecond*}
 % The macro \cs{PartialMixSecond} takes an extra argument, but is otherwise
 % the same as its same-variable cousin.
 %    \begin{macrocode}
-\def\PartialMixSecond{\@ifstar\PartialMixSecond at star\PartialMixSecond at nostar}
-\newcommand*{\PartialMixSecond at nostar}[4]{%
-  \def\tmp at arg{#4}%
-  \if at subscripted
-  % Handles situation of empty variables held constant
-    \ifx\tmp at arg\@empty
-      \ensuremath{\Partial at start\frac{\partial^2 #1}
-                           {\partial #2\partial#3}\Partial at empty@end}%
-    \else
-      \ensuremath{\Partial at start\frac{\partial^2 #1}
-                           {\partial #2\partial#3}\Partial at end_{#4}}%
-    \fi
-  \else
-    \ifx\tmp at arg\@empty
-      \ensuremath{\Partial at start\frac{\partial^2 #1(#2,#3)}
-                           {\partial #2\partial#3}\Partial at empty@end}%
-    \else
-      % This time, we check whether #2 OR #3 are \Nt_i/etc.
-      \thermo at parse@two#3\relax
-      \iftwo at has@Nt\three at has@Nttrue\fi
-      \iftwo at has@xory\three at has@xorytrue\fi
-      \two at has@Ntfalse
-      \two at has@xoryfalse
-      \thermo at parse@two#2\relax
-      \iftwo at has@Nt
-        \renewcommand*{\allbut}[3][j]{\allcomponents{##3}}%
-        \ensuremath{\Partial at start\frac{\partial^2 #1(#3,#4)}
-                                       {\partial #2\partial#3}\Partial at end}%
-      \else
-        \iftwo at has@xory
-          \renewcommand*{\allbutlastand}[3][j]{\allbut{\ncomponents}{##3}}%
-          \ensuremath{\Partial at start\frac{\partial^2 #1(#3,#4)}
-                                         {\partial #2\partial#3}\Partial at end}%
-        \else
-          \ifthree at has@Nt
-            \renewcommand*{\allbut}[3][j]{\allcomponents{##3}}%
-            \ensuremath{\Partial at start\frac{\partial^2 #1(#2,#4)}
-                                      {\partial #2\partial#3}\Partial at end}%
-          \else
-            \ifthree at has@xory
-              \PackageWarning{thermodynamics}{GOT HERE}
-              %\renewcommand*{\allbutlastand}[3][j]{\allbut{\ncomponents}{##3}}%
-              \renewcommand*{\allbutlastand}[3][j]{SCREW YOU}%
-              \ensuremath{\Partial at start\frac{\partial^2 #1(#2,#4)}
-                                        {\partial #2\partial#3}\Partial at end}%
-            \else
-              \ensuremath{\Partial at start\frac{\partial^2 #1(#2,#3,#4)}
-                                        {\partial #2\partial#3}\Partial at end}%
-            \fi
-          \fi
-        \fi
-      \fi
-    \fi
-  \fi
+\bool_new:N \l_@@_has_x_or_y_bool
+\NewDocumentCommand{\PartialMixSecond}{s m m m m}
+{
+  \bool_if:nTF {#1}
+  {% Starred version
+    \settowidth{\l_@@_Partial_const_dim}{\ensuremath{#4}}%
+    \dim_add:Nn \l_@@_Partial_const_dim {-0.20\l_@@_Partial_const_dim}
+    \PartialMixSecond{#2}{#3}{#4}{#5}
+    \bool_if:nT \l_@@_subscripted_bool
+    { \dim_compare:nNnTF {\l_@@_operator_width_dim}
+                       < {\l_@@_Partial_const_dim}
+      { \kern -\l_@@_operator_width_dim }
+      { \kern -\l_@@_Partial_const_dim }
+    }
+  }
+  {% Unstarred version
+    \bool_if:nTF \l_@@_subscripted_bool
+    {% subscripted version
+      \tl_if_eq:nnTF {#5} {}
+      {% Handle case of empty variables held constant
+        \l_@@_Partial_start_tl
+        \@@_frac:nn{\partial\c_math_superscript_token 2 #2}
+            {\partial #3\partial #4}\l_@@_Partial_empty_end_tl
+      }
+      { \l_@@_Partial_start_tl
+        \@@_frac:nn{\partial\c_math_superscript_token 2 #2}
+            {\partial #3\partial #4}\l_@@_Partial_end_tl
+            \c_math_subscript_token{#5}
+      }
+    }
+    {% not subscripted
+      \tl_if_eq:nnTF {#5} {}
+      {% empty argument
+        \l_@@_Partial_start_tl
+        \@@_frac:nn{\partial\c_math_superscript_token 2
+                        #2(\@@_sort_clist:n{#3,#4,#5})}
+                   {\partial #3\partial #4}\l_@@_Partial_empty_end_tl
+      }
+      {% Check whether #3 OR #4 are \Nt_i/etc.
+        \tl_if_in:nnTF {#3} {\Nt}
+        { \RenewDocumentCommand{\allbut}{O{j} m m}{\allcomponents{##3}}%
+          \l_@@_Partial_start_tl
+          \@@_frac:nn{\partial\c_math_superscript_token 2
+                        #2(\@@_sort_clist:n{#4,#5})}
+                     {\partial #3\partial #4}\l_@@_Partial_end_tl
+        }
+        { \tl_if_in:nnTF {#4} {\Nt}
+          { \RenewDocumentCommand{\allbut}{O{j} m m}{\allcomponents{##3}}%
+            \l_@@_Partial_start_tl
+            \@@_frac:nn{\partial\c_math_superscript_token 2
+                            #2(\@@_sort_clist:n{#3,#5})}
+                       {\partial #3\partial #4}\l_@@_Partial_end_tl
+          }
+          {% Check for x, y, or w
+            \bool_set_false:N \l_@@_has_x_or_y_bool
+            \tl_if_in:nnT {#3} {x}
+            { \l_@@_has_x_or_y_bool }
+            \tl_if_in:nnT {#3} {y}
+            { \l_@@_has_x_or_y_bool }
+            \tl_if_in:nnT {#3} {w}
+            { \l_@@_has_x_or_y_bool }
+            \bool_if:NTF \l_@@_has_x_or_y_bool
+            { \RenewDocumentCommand{\allbutlastand}{O{j} m m}
+                {\allcomponents{##3}}
+              \l_@@_Partial_start_tl
+              \@@_frac:nn{\partial\c_math_superscript_token 2
+                            #2(\@@_sort_clist:n{#4,#5})}
+                         {\partial #3\partial #4}\l_@@_Partial_end_tl
+            }
+            {
+              \l_@@_Partial_start_tl
+              \@@_frac:nn{\partial\c_math_superscript_token 2
+                            #2(\@@_sort_clist:n{#3,#4,#5})}
+                         {\partial #3\partial #4}\l_@@_Partial_end_tl
+            }
+          }
+        }
+      }
+    }
+  }
 }
-\newcommand*{\PartialMixSecond at star}[4]{%
-    \settowidth{\Partial at const@width}{\ensuremath{#4}}%
-    \addtolength{\Partial at const@width}{-0.25\Partial at const@width}%
-    \PartialMixSecond at nostar{#1}{#2}{#3}{#4}%
-    \if at subscripted
-      \ifdim\operator at width<\Partial at const@width
-        \kern -\operator at width
-      \else
-        \kern -\Partial at const@width
-      \fi
-    \fi
-}
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
-% \begin{macro}{\PartialMixSecondBigg}
-% \begin{macro}{\PartialMixSecondBigg*}
-% \begin{macro}{\PartialMixSecondbigg}
-% \begin{macro}{\PartialMixSecondbigg*}
-% The macro \cs{PartialMixSecondBigg} and its starred form are analogous to
-% \cs{PartialBigg} and \cs{PartialSecondBigg}. \cs{PartialMixSecondbigg} and
-% its starred form are similarly analogous to \cs{Partialbigg} and
-% \cs{PartialSecondbigg}.
+% \begin{macro}{\PartialMixSecondBigg,\PartialMixSecondbigg}
+% The macro \cs{PartialMixSecondBigg} is analogous to the aforementioned macros
+% \cs{PartialBigg} and \cs{PartialSecondBigg}. \cs{PartialMixSecondbigg} is
+% analogous to \cs{Partialbigg} and \cs{PartialSecondbigg}.
 %    \begin{macrocode}
-\def\PartialMixSecondBigg{%
-  \def\Partial at start{\expandafter\Biggl\PartialOpen}%
-  \def\Partial at end{\expandafter\Biggr\PartialClose}%
-  \PartialMixSecond%
+\NewDocumentCommand{\PartialMixSecondBigg}{}
+{ \tl_set:Nn \l_@@_Partial_start_tl {\Biggl\l_@@_PartialOpen_tl}
+  \tl_set:Nn \l_@@_Partial_end_tl {\Biggl\l_@@_PartialClose_tl}
+  \tl_set:Nn \l_@@_Partial_empty_end_tl {\Biggl\l_@@_PartialClose_tl}
+  \PartialMixSecond
 }
-\def\PartialMixSecondbigg{%
-  \def\Partial at start{\expandafter\biggl\PartialOpen}%
-  \def\Partial at end{\expandafter\biggr\PartialClose}%
-  \PartialMixSecond%
+\NewDocumentCommand{\PartialMixSecondbigg}{}
+{ \tl_set:Nn \l_@@_Partial_start_tl {\biggl\l_@@_PartialOpen_tl}
+  \tl_set:Nn \l_@@_Partial_end_tl {\biggl\l_@@_PartialClose_tl}
+  \tl_set:Nn \l_@@_Partial_empty_end_tl {\biggl\l_@@_PartialClose_tl}
+  \PartialMixSecond
 }
 %    \end{macrocode}
-% If the user does not load the \verb"amsmath" package, we will not have access
-% to \cs{Biggl}, \cs{Biggr}, \cs{biggl}, and \cs{biggr}, so we revert them back
+%
+% If the user does not load the \pkg{amsmath} package, we will not have access
+% to \cs[module=amsmath]{Biggl}, \cs{Biggr}, \cs{biggl}, and \cs{biggr}, so we revert them back
 % to the ordinary \cs{left} and \cs{right} versions and warn the user.
 %    \begin{macrocode}
 \AtBeginDocument{%
   \@ifpackageloaded{amsmath}{}{%
       \PackageWarningNoLine{thermodynamics}
-        {Package amsmath not loaded; load to make PartialBigg and friends
-            work correctly}%
-      \let\PartialBigg\Partial
-      \let\Partialbigg\Partial
-      \let\PartialSecondBigg\PartialSecond
-      \let\PartialSecondbigg\PartialSecond
-      \let\PartialMixSecondBigg\PartialMixSecond
-      \let\PartialMixSecondbigg\PartialMixSecond
+        {Package~amsmath~not~loaded;~load~to~make~PartialBigg~and~friends
+            ~work~correctly}%
+      \cs_set_eq:NN \PartialBigg \Partial
+      \cs_set_eq:NN \Partialbigg \Partial
+      \cs_set_eq:NN \PartialSecondBigg \PartialSecond
+      \cs_set_eq:NN \PartialSecondbigg \PartialSecond
+      \cs_set_eq:NN \PartialMixSecondBigg \PartialMixSecond
+      \cs_set_eq:NN \PartialMixSecondbigg \PartialMixSecond
+      \ProvideDocumentCommand{\rvert}{}{|}
+      \ProvideDocumentCommand{\lvert}{}{|}
   }%
 }
 %    \end{macrocode}
 % \end{macro}
+% \changes{v1.01}{2023/09/15}{Added \cs{Partialinline} and friends to
+%   facilitate in-line (non-display-mode) partial derivatives, with
+%   corresponding changes to \cs{Partial} and friends for ease of
+%   implementation. Also added \cs{Partialinlinetext} and friends for
+%   non-expanding delimiters.}
+% \begin{macro}{\Partialinline,\PartialSecondinline,\PartialMixSecondinline}
+% Inline partial derivatives.
+%    \begin{macrocode}
+\NewDocumentCommand{\Partialinline}{}
+{
+  \cs_set:Nn \@@_frac:nn { ##1 \l_@@_Partial_middle_tl / ##2 }
+  \Partial
+}
+\NewDocumentCommand{\PartialSecondinline}{}
+{
+  \cs_set:Nn \@@_frac:nn { ##1 \l_@@_Partial_middle_tl / ##2 }
+  \PartialSecond
+}
+\NewDocumentCommand{\PartialMixSecondinline}{}
+{
+  \cs_set:Nn \@@_frac:nn { ##1 \l_@@_Partial_middle_tl / ##2 }
+  \PartialMixSecond
+}
+%    \end{macrocode}
 % \end{macro}
+% \pagebreak[1]
+% \setmarginparsize{\footnotesize}
+% \begin{macro}{\Partialinlinetext}
+% \begin{macro}{\PartialSecondinlinetext}
+% \begin{macro}{\PartialMixSecondinlinetext}
+% Text-only (non-extensible delimiter) versions of \cs{Partialinline}
+% and friends.
+%^^A TODO: These currently "pollute" other partial derivatives until the end
+%^^A       of the line (i.e., \Partialinline{z}{x}{y} = \Partial{z}{x}{y} will
+%^^A       produce identical things on both sides). For now, it's a "feature."
+%   \begin{macrocode}
+\NewDocumentCommand{\Partialinlinetext}{}
+{ \cs_set_eq:NN \l_@@_Partial_start_tl \l_@@_PartialOpen_tl
+  \cs_set_eq:NN \l_@@_Partial_end_tl \l_@@_PartialClose_tl
+  \cs_set_eq:NN \l_@@_Partial_empty_end_tl \l_@@_PartialEmptyClose_tl
+  \cs_set_eq:NN \l_@@_Partial_middle_tl \relax
+  \Partialinline
+}
+\NewDocumentCommand{\PartialSecondinlinetext}{}
+{ \cs_set_eq:NN \l_@@_Partial_start_tl \l_@@_PartialOpen_tl
+  \cs_set_eq:NN \l_@@_Partial_end_tl \l_@@_PartialClose_tl
+  \cs_set_eq:NN \l_@@_Partial_empty_end_tl \l_@@_PartialEmptyClose_tl
+  \cs_set_eq:NN \l_@@_Partial_middle_tl \relax
+  \PartialSecondinline
+}
+\NewDocumentCommand{\PartialMixSecondinlinetext}{}
+{ \cs_set_eq:NN \l_@@_Partial_start_tl \l_@@_PartialOpen_tl
+  \cs_set_eq:NN \l_@@_Partial_end_tl \l_@@_PartialClose_tl
+  \cs_set_eq:NN \l_@@_Partial_empty_end_tl \l_@@_PartialEmptyClose_tl
+  \cs_set_eq:NN \l_@@_Partial_middle_tl \relax
+  \PartialMixSecondinline
+}
+%    \end{macrocode}
 % \end{macro}
 % \end{macro}
+% \end{macro}
+% \restoremarginparsize
 %
 % \subsection{Local Override of Delimiters}
+% We define several environments that \emph{locally} override the delimiters on
+% partial derivatives generated with \cs{Partial} and friends, the
+% subscript notation for partial derivatives, and/or the definitions of
+% range-oriented macros such as \cs{allNs}. These environments can be nested;
+% the inner-most one will be honored if conflicts occur.
 % \begin{environment}{thermoparentheses}
+% Inside this environment, partial derivatives will have parentheses around
+% them, regardless of package options.
+%    \begin{macrocode}
+\NewDocumentEnvironment{thermoparentheses}{}
+{ \cs_set:Nn \l_@@_PartialOpen_tl {(}
+  \cs_set:Nn \l_@@_PartialClose_tl {)}
+  \cs_set:Nn \l_@@_PartialEmptyClose_tl {)}
+}{}
+%    \end{macrocode}
+% \end{environment}
 % \begin{environment}{thermobrackets}
+% Inside this environment, partial derivatives will have brackets around
+% them, regardless of package options.
+%    \begin{macrocode}
+\NewDocumentEnvironment{thermobrackets}{}
+{ \tl_set:Nn \l_@@_PartialOpen_tl {[}
+  \tl_set:Nn \l_@@_PartialClose_tl {]}
+  \tl_set:Nn \l_@@_PartialEmptyClose_tl {]}
+}{}
+%    \end{macrocode}
+% \end{environment}
 % \begin{environment}{thermobraces}
+% Inside this environment, partial derivatives will have braces around
+% them, regardless of package options.
+%    \begin{macrocode}
+\NewDocumentEnvironment{thermobraces}{}
+{ \tl_set:Nn \l_@@_PartialOpen_tl {\{}
+  \tl_set:Nn \l_@@_PartialClose_tl {\}}
+  \tl_set:Nn \l_@@_PartialEmptyClose_tl {\}}
+}{}
+%    \end{macrocode}
+% \end{environment}
 % \begin{environment}{thermobar}
+% Inside this environment, partial derivatives will have a trailing vertical
+% bar, regardless of package options.
+%    \begin{macrocode}
+\NewDocumentEnvironment{thermobar}{}
+{ \tl_set:Nn \l_@@_PartialOpen_tl {.}
+  \tl_set:Nn \l_@@_PartialClose_tl {\rvert}
+  \tl_set:Nn \l_@@_PartialEmptyClose_tl {.}
+}{}
+%    \end{macrocode}
+% \end{environment}
 % \begin{environment}{thermoplain}
-% We define seven environments that \emph{locally} override the delimiters on
-% partial derivatives generated with \cs{Partial} and friends and/or the
-% subscript notation for partial derivatives.
+% Inside this environment, partial derivatives will have no decorations
+% around them, regardless of package options.
 %    \begin{macrocode}
-\newenvironment*{thermoparentheses}{
-  \renewcommand*{\PartialOpen}{(}%
-  \renewcommand*{\PartialClose}{)}%
-  \renewcommand*{\PartialEmptyClose}{)}%
+\NewDocumentEnvironment{thermoplain}{}
+{ \tl_set:Nn \l_@@_PartialOpen_tl {.}
+  \tl_set:Nn \l_@@_PartialClose_tl {.}
+  \tl_set:Nn \l_@@_PartialEmptyClose_tl {.}
+  \bool_set_false:N \l_@@_subscripted_bool
 }{}
-\newenvironment*{thermobrackets}{%
-  \renewcommand*{\PartialOpen}{[}%
-  \renewcommand*{\PartialClose}{]}%
-  \renewcommand*{\PartialEmptyClose}{]}%
-}{}
-\newenvironment*{thermobraces}{%
-  \renewcommand*{\PartialOpen}{\{}%
-  \renewcommand*{\PartialClose}{\}}%
-  \renewcommand*{\PartialEmptyClose}{\}}%
-}{}
-\newenvironment*{thermobar}{%
-  \renewcommand*{\PartialOpen}{.}%
-  \renewcommand*{\PartialClose}{\rvert}%
-  \renewcommand*{\PartialEmptyClose}{.}%
-}{}
-\newenvironment*{thermoplain}{%
-  \renewcommand*{\PartialOpen}{.}%
-  \renewcommand*{\PartialClose}{.}%
-  \renewcommand*{\PartialEmptyClose}{.}%
-  \@subscriptedfalse
-}{}
-\newenvironment*{thermoNOsubscripts}{\@subscriptedfalse}{}
-\newenvironment*{thermosubscripts}{\@subscriptedtrue}{}
 %    \end{macrocode}
 % \end{environment}
+% \begin{environment}{thermoNOsubscripts}
+% Inside this environment, subscripts will not be displayed to the right of
+% partial derivatives, regardless of package options.
+%    \begin{macrocode}
+\NewDocumentEnvironment{thermoNOsubscripts}{}
+    {\bool_set_false:N \l_@@_subscripted_bool}
+    {}
+%    \end{macrocode}
+% \begin{environment}{thermosubscripts}
+% Inside this environment, subscripts will be displayed to the right of
+% partial derivatives, regardless of package options.
 % \end{environment}
+%    \begin{macrocode}
+\NewDocumentEnvironment{thermosubscripts}{}
+    {\bool_set_true:N \l_@@_subscripted_bool}
+    {}
+%    \end{macrocode}
 % \end{environment}
+% \begin{environment}{thermomolesrange}
+% Inside this environment, the macro \cs{allNs} will expand to
+% $n_1,\dotsc,n_C$ (or equivalent symbols if \cs{Nt} and/or \cs{ncomponents}
+% have been redefined), regardless of package options. Similar expansions will
+% result for \cs{allXs}, \cs{allYs}, \cs{allMs}, and so on.
+% \changes{v2.00}{2023/11/16}{Added environment to invoke the ``moles-range''
+%     definitions of \cs{allNs} and friends locally.}
+%    \begin{macrocode}
+\NewDocumentEnvironment{thermomolesrange}{}
+    { \@@_set_moles_range }
+    {}
+%    \end{macrocode}
 % \end{environment}
+% \begin{environment}{thermointensiveplain}
+% \changes{v2.00}{2023/11/16}{Added environment to invoke the
+%     ``intensive-plain'' option locally.}
+%    \begin{macrocode}
+%    \begin{macrocode}
+\NewDocumentEnvironment{thermointensiveplain}{}
+    { \@@_set_intensive_plain }
+    {}
+%    \end{macrocode}
 % \end{environment}
+% \begin{environment}{thermoextensiveplain}
+% \changes{v2.00}{2023/11/16}{Added environment to invoke the
+%     ``extensive-plain'' option locally.}
+%    \begin{macrocode}
+\NewDocumentEnvironment{thermoextensiveplain}{}
+    { \@@_set_extensive_plain }
+    {}
+%    \end{macrocode}
+% \end{environment}
+% \setmarginparsize{\scriptsize}
+% \begin{environment}{thermointensivelowercase}
+% \changes{v2.00}{2023/11/16}{Added environment to invoke the
+%     ``intensive-lowercase'' option locally.}
+%    \begin{macrocode}
+\NewDocumentEnvironment{thermointensivelowercase}{}
+    {% {
+% \RenewExpandableDocumentCommand{\MacroFont}{}{
+%   \fontencoding\encodingdefault
+%   \fontfamily\ttdefault
+%   \fontseries\mddefault
+%   \fontshape\shapedefault
+%   \footnotesize}
+
+      \@@_set_intensive_lowercase
+      \@@_set_lowercase_pms
+    }
+    {}
+%    \end{macrocode}
+% \end{environment}
+% \begin{environment}{thermoextensivesuperscript}
+% \changes{v2.00}{2023/11/16}{Added environment to invoke the
+%     ``extensive-superscript'' option locally.}
+%    \begin{macrocode}
+\NewDocumentEnvironment{thermoextensivesuperscript}{}
+    {
+      \@@_set_extensive_superscripts
+    }
+    {}
+%    \end{macrocode}
+% \end{environment}
+% \restoremarginparsize
 %
 % \subsection{User-Interface Macros to Define Symbols}
-% \begin{macro}{\DeclareSubscrSymbol}
-% First, we define a (messy!)\ command that serves to create ``subscripted''
+% \begin{macro}{\NewSubscriptedSymbol}
+% First, we define a command that serves to create ``subscripted''
 % symbols; for example, typing \verb"\cP_i" should yield $C_{P,i}$ rather
 % than $C_{Pi}$, ${C_P}_i$, or ${C_{P_i}}$. Superscripts are also handled
 % properly and can be in either order.
+% \changes{v2.00}{2023/11/16}{Deleted \cs{DeclareSubscriptedSymbol} in favor
+%   of \pkg{xparse}-based \cs{NewSubscriptedSymbol} and
+%   \cs{RenewSubscriptedSymbol}.}
 %    \begin{macrocode}
-\newcommand*{\DeclareSubscrSymbol}[3]{%
-  \expandafter\def\csname #1\endcsname{%
-    \@ifnextchar^{\csname @#1\endcsname}
-                 {\@ifnextchar_{\csname @@#1\endcsname}{{#2}_{#3}}}
+\cs_new:Npn \@@_check_definable:nN #1#2
+{
+  \bool_set_true:N \l_@@_arg_legal_bool
+  \tl_trim_spaces_apply:nN {#1} \tl_if_single_token:nTF
+  {
+    \str_set:Nx \l_tmp_str {\tl_to_str:n {#1}}
+    \int_compare:nNnT {\str_count:N \l_tmp_str} = 1
+    { \PackageError{thermodynamics}
+        {First~argument~of~'\tl_trim_spaces:o {\tl_to_str:n {#2}}'~
+         must~be~a~command}
+        {The~first~argument~of~'\tl_trim_spaces:o {\tl_to_str:n {#2}}'~
+         should~be~the~macro~that~will~be~used~to~refer~to~the~symbol.~
+         The~provided~argument~'\tl_trim_spaces:o {\tl_to_str:n {#1}}'~
+         is~a~single~character.
+         \MessageBreak Perhaps~a~backslash~is~missing?}
+    }
   }
-  \expandafter\def\csname @#1\endcsname ##1##2{%
-    {#2}^{##2}\@ifnextchar_{\csname @@@#1\endcsname}{_{#3}}%
+  { \PackageError{thermodynamics}
+      {First~argument~of~'\tl_trim_spaces:o {\tl_to_str:n {#2}}'~
+       must~be~a~command}
+      {The~first~argument~of~'\tl_trim_spaces:o {\tl_to_str:n {#2}}'~
+       should~be~the~macro~that~will~be~used~to~refer~to~the~symbol.~
+       The~provided~argument~'\tl_trim_spaces:o {\tl_to_str:n {#1}}'~
+       contains~more~than~one~token.
+       \MessageBreak Perhaps~a~backslash~is~missing?}
   }
-  \expandafter\def\csname @@#1\endcsname ##1##2{{#2}_{#3,##2}}
-  \expandafter\def\csname @@@#1\endcsname ##1##2{_{#3,##2}}
 }
+\NewDocumentCommand{\NewSubscriptedSymbol}{m m m}
+{
+  \@@_check_definable:nN {#1} \NewSubscriptedSymbol
+  \cs_if_exist:NT #1
+  { \PackageError{thermodynamics}
+      {Command~'\tl_trim_spaces:o {\tl_to_str:n {#1}}'~already~defined}
+      {You~have~used~
+       '\tl_trim_spaces:o {\tl_to_str:n {\NewSubscriptedSymbol}}'~
+       with~a~command~that~already~has~a~definition}
+  }
+  \cs_new:cpn {\cs_to_str:N #1_one:n} ##1
+  {
+    {#2}\c_math_superscript_token{##1}
+    \peek_catcode_remove:NTF \c_math_subscript_token
+    { \use:c {\cs_to_str:N #1_three:n} }
+    { \c_math_subscript_token{#3} }
+  }
+
+  \cs_new:cpn {\cs_to_str:N #1_two:n} ##1
+  { {#2}\c_math_subscript_token{#3,##1} }
+
+  \cs_new:cpn {\cs_to_str:N #1_three:n} ##1
+  { \c_math_subscript_token{#3,##1} }
+
+  \NewDocumentCommand{#1}{}
+  {% @branch
+    \peek_catcode_remove:NTF \c_math_superscript_token
+    { \use:c {\cs_to_str:N #1_one:n} }
+    { \peek_catcode_remove:NTF \c_math_subscript_token
+      { \use:c {\cs_to_str:N #1_two:n} }
+      { {#2}\c_math_subscript_token{#3} }
+    }
+  }
+}
+\NewDocumentCommand{\RenewSubscriptedSymbol}{m m m}
+{
+  \@@_check_definable:nN {#1} \RenewSubscriptedSymbol
+  \cs_if_exist:NF #1
+  { \PackageError{thermodynamics}
+      {Command~'\tl_trim_spaces:o {\tl_to_str:n {#1}}'~not~defined}
+      {You~have~used~
+       '\tl_trim_spaces:o {\tl_to_str:n {\RenewSubscriptedSymbol}}'~
+       with~a~command~that~does~not~have~a~definition}
+  }
+  \cs_set:cpn {\cs_to_str:N #1_one:n} ##1
+  {
+    {#2}\c_math_superscript_token{##1}
+    \peek_catcode_remove:NTF \c_math_subscript_token
+    { \use:c {\cs_to_str:N #1_three:n} }
+    { \c_math_subscript_token{#3} }
+  }
+
+  \cs_set:cpn {\cs_to_str:N #1_two:n} ##1
+  { {#2}\c_math_subscript_token{#3,##1} }
+
+  \cs_set:cpn {\cs_to_str:N #1_three:n} ##1
+  { \c_math_subscript_token{#3,##1} }
+
+  \RenewDocumentCommand{#1}{}
+  {% @branch
+    \peek_catcode_remove:NTF \c_math_superscript_token
+    { \use:c {\cs_to_str:N #1_one:n} }
+    { \peek_catcode_remove:NTF \c_math_subscript_token
+      { \use:c {\cs_to_str:N #1_two:n} }
+      { {#2}\c_math_subscript_token{#3} }
+    }
+  }
+  
+}
 %    \end{macrocode}
 % \end{macro}
-% \begin{macro}{\heatcapacitysymbol}
-% \begin{macro}{\compressibilitysymbol}
-% \begin{macro}{\expansivitysymbol}
+% \begin{macro}{\NewSuperscriptedSymbol}
+% \changes{v2.00}{2023/11/16}{Created \cs{NewSuperscriptedSymbol} to handle
+%   superscripted excess and residual properties without intervention.}
+%    \begin{macrocode}
+\NewDocumentCommand{\NewSuperscriptedSymbol}{m m m}
+{
+  \@@_check_definable:nN {#1} \NewSuperscriptedSymbol
+  \cs_if_exist:NT #1
+  { \PackageError{thermodynamics}
+      {Command~'\tl_trim_spaces:o {\tl_to_str:n {#1}}'~already~defined}
+      {You~have~used~
+       '\tl_trim_spaces:o {\tl_to_str:n {\NewSuperscriptedSymbol}}'~
+       with~a~command~that~already~has~a~definition}
+  }
+  \cs_new:cpn {\cs_to_str:N #1_one:n} ##1
+  {
+    {#2}\c_math_subscript_token{#1}
+    \peek_catcode_remove:NTF \c_math_superscript_token
+    { \use:c {\cs_to_str:N #1_one:n} }
+    { \c_math_subscript_token{#3} }
+  }
+
+  \cs_new:cpn {\cs_to_str:N #1_two:n} ##1
+  { {#2}\c_math_superscript_token{#3,##1} }
+
+  \cs_new:cpn {\cs_to_str:N #1_three:n} ##1
+  { {#2}\c_math_superscript_token{#3,##1} }
+
+  \NewDocumentCommand{#1}{}
+  {
+    \peek_catcode_remove:NTF \c_math_subscript_token
+    { \use:c {\cs_to_str:N #1_one:n} }
+    { \peek_catcode_remove:NTF \c_math_superscript_token
+      { \use:c {\cs_to_str:N #1_two:n} }
+      { {#2}\c_math_superscript_token{#3} }
+    }
+  }
+}
+\NewDocumentCommand{\RenewSuperscriptedSymbol}{m m m}
+{
+  \@@_check_definable:nN {#1} \RenewSuperscriptedSymbol
+  \cs_if_exist:NF #1
+  { \PackageError{thermodynamics}
+      {Command~'\tl_trim_spaces:o {\tl_to_str:n {#1}}'~not~defined}
+      {You~have~used~
+       '\tl_trim_spaces:o {\tl_to_str:n {\RenewSuperscriptedSymbol}}'~
+       with~a~command~that~does~not~have~a~definition}
+  }
+  \cs_set:cpn {\cs_to_str:N #1_one:n} ##1
+  {
+    {#2}\c_math_subscript_token{##1}
+    \peek_catcode_remove:NTF \c_math_superscript_token
+    { \use:c {\cs_to_str:N #1_three:n} }
+    { \c_math_superscript_token{#3} }
+  }
+
+  \cs_set:cpn {\cs_to_str:N #1_two:n} ##1
+  { {#2}\c_math_superscript_token{#3,##1} }
+
+  \cs_set:cpn {\cs_to_str:N #1_three:n} ##1
+  { \c_math_superscript_token{#3,##1} }
+
+  \RenewDocumentCommand{#1}{}
+  {% @branch
+    \peek_catcode_remove:NTF \c_math_subscript_token
+    { \use:c {\cs_to_str:N #1_one:n} }
+    { \peek_catcode_remove:NTF \c_math_superscript_token
+      { \use:c {\cs_to_str:N #1_two:n} }
+      { {#2}\c_math_superscript_token{#3} }
+    }
+  }
+}
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\heatcapacitysymbol,\compressibilitysymbol,\expansivitysymbol}
 % Now we define symbols for the heat capacities, compressibilities, and
 % so forth.
 %    \begin{macrocode}
-\newcommand*{\heatcapacitysymbol}{C}
-\newcommand*{\compressibilitysymbol}{\kappa}
-\newcommand*{\expansivitysymbol}{\alpha}
+\NewExpandableDocumentCommand{\heatcapacitysymbol}{}{C}
+\NewExpandableDocumentCommand{\compressibilitysymbol}{}{\kappa}
+\NewExpandableDocumentCommand{\expansivitysymbol}{}{\alpha}
+\NewExpandableDocumentCommand{\JTsymbol}{}{\mu}
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
-% \end{macro}
-% \begin{macro}{\cV}
-% \begin{macro}{\cP}
+% \begin{macro}{\cV,\cP}
 % The heat capacities are molar by default; we also declare extensive and
 % specific heat capacities.
 % The heat capacities themselves are defined to be ``smart'': \verb"\cV_i" will
@@ -2601,150 +3236,121 @@
 % ${C_V}_i$ or some other unintended symbol. Superscripts are also handled
 % appropriately and can be in either order.
 %    \begin{macrocode}
-\DeclareSubscrSymbol{cV}{\@intensive\heatcapacitysymbol}{\volume at symbol}
-\DeclareSubscrSymbol{cP}{\@intensive\heatcapacitysymbol}{\pressure at symbol}
+\NewSubscriptedSymbol{\cV}{\@@_intensive:n \heatcapacitysymbol}
+    {\g_@@_volume_symbol}
+\NewSubscriptedSymbol{\cP}{\@@_intensive:n \heatcapacitysymbol}
+    {\g_@@_pressure_symbol}
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
-% \begin{macro}{\cVt}
-% \begin{macro}{\cPt}
+% \begin{macro}{\cVt,\cPt}
 % We also introduce \emph{extensive} (rather than molar) heat capacity macros.
 %    \begin{macrocode}
-\DeclareSubscrSymbol{cVt}{\@extensive\heatcapacitysymbol}{\volume at symbol}
-\DeclareSubscrSymbol{cPt}{\@extensive\heatcapacitysymbol}{\pressure at symbol}
+\NewSubscriptedSymbol{\cVt}{\@@_extensive:n \heatcapacitysymbol}
+    {\g_@@_volume_symbol}
+\NewSubscriptedSymbol{\cPt}{\@@_extensive:n \heatcapacitysymbol}
+    {\g_@@_pressure_symbol}
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
-% \begin{macro}{\cPs}
-% \begin{macro}{\cVs}
+% \begin{macro}{\cVs,\cPs}
 % \cs{cPs} and \cs{cVs} are the specific heat capacities.
 %    \begin{macrocode}
-\DeclareSubscrSymbol{cVs}{\@specific\heatcapacitysymbol}{\volume at symbol}
-\DeclareSubscrSymbol{cPs}{\@specific\heatcapacitysymbol}{\pressure at symbol}
+\NewSubscriptedSymbol{\cVs}{\@@_specific:n \heatcapacitysymbol}
+    {\g_@@_volume_symbol}
+\NewSubscriptedSymbol{\cPs}{\@@_specific:n \heatcapacitysymbol}
+    {\g_@@_pressure_symbol}
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
 %
-% \begin{macro}{\kappaT}
-% \begin{macro}{\kappaS}
+% \begin{macro}{\kappaT,\kappaS}
 % The isothermal and adiabatic compressibilities are defined similarly, but
 % those do not have extensive versions for obvious reasons.
 %    \begin{macrocode}
-\DeclareSubscrSymbol{kappaT}{\compressibilitysymbol}{\temperature at symbol}
-\DeclareSubscrSymbol{kappaS}{\compressibilitysymbol}{\entropy at symbol}
+\NewSubscriptedSymbol{\kappaT}{\compressibilitysymbol}
+    {\g_@@_temperature_symbol}
+\NewSubscriptedSymbol{\kappaS}{\compressibilitysymbol}
+    {\g_@@_entropy_symbol}
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
-% \begin{macro}{\alphaP}
-% \begin{macro}{\alphaS}
+% \begin{macro}{\alphaP,\alphaS}
 % The macro \cs{alphaP} is intended to refer to the isobaric volume
 % expansivity, while \cs{alphaS} is the isentropic volume expansivity.
 %    \begin{macrocode}
-\DeclareSubscrSymbol{alphaP}{\expansivitysymbol}{\pressure at symbol}
-\DeclareSubscrSymbol{alphaS}{\expansivitysymbol}{\entropy at symbol}
+\NewSubscriptedSymbol{\alphaP}{\expansivitysymbol}{\g_@@_pressure_symbol}
+\NewSubscriptedSymbol{\alphaS}{\expansivitysymbol}{\g_@@_entropy_symbol}
 %    \end{macrocode}
 % \end{macro}
+% \begin{macro}{\muJT}
+% The macro \cs{muJT} renders the Joule--Thomson coefficient.
+%    \begin{macrocode}
+\NewSubscriptedSymbol{\muJT}{\JTsymbol}{JT}
+%    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\Psat}
-% \begin{macro}{\Pvap}
+% \begin{macro}{\Psat,\Pvap,\phisat,\fsat,\sat}
 % The \cs{Psat} macro (and its clone, the \cs{Pvap} macro) should be used for
 % the saturation pressure.
-% \begin{macro}{\phisat}
-% \begin{macro}{\fsat}
-% \begin{macro}{\sat}
 % Similarly, a \cs{phisat} macro typesets the fugacity coefficient at
 % saturation. The \cs{fsat} macro similarly renders the fugacity at saturation.
 % Other saturation properties should use \verb"M^\sat" or similar, preferably
 % by defining another macro such as \verb"\Gmsat".
 %    \begin{macrocode}
-\newcommand*{\sat}{{\text{sat}}}
-\newcommand*{\Psat}{P^\sat}
-\let\Pvap\Psat
-\newcommand*{\phisat}{\phi^\sat}
-\newcommand*{\fsat}{f^\sat}
+\NewDocumentCommand{\sat}{}{{\text{sat}}}
+\NewDocumentCommand{\Psat}{}{P\c_math_superscript_token\sat}
+\NewDocumentCommand{\Pvap}{}{\Psat}
+\NewDocumentCommand{\phisat}{}{\phi\c_math_superscript_token\sat}
+\NewDocumentCommand{\fsat}{}{\fpure\c_math_superscript_token\sat}
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \begin{macro}{std}
-% \begin{macro}{Pstd}
-% \begin{macro}{fstd}
+% \begin{macro}{\std,\Pstd,\fstd}
 % The \cs{std} macro denotes standard properties. \cs{Pstd} and \cs{fstd} are
 % defined for convenience and for consistency across textbooks.
 %    \begin{macrocode}
-\let\std\circ
-\newcommand*{\Pstd}{P^\std}
-\newcommand*{\fstd}{f^\std}
+\NewDocumentCommand{\std}{}{\circ}
+\NewDocumentCommand{\Pstd}{}{P\c_math_superscript_token \std}
+\NewDocumentCommand{\fstd}{}{f\c_math_superscript_token \std}
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
-% \end{macro}
 %
-% \begin{macro}{\Deltamix}
-% \begin{macro}{\mixing}
-% Mixing properties, such as $\Delta G_\text{mix}$, should be accessed using
+% \begin{macro}{\Deltamix,\mixing}
+% Mixing properties, such as $\Deltamix\Gm$, should be accessed using
 % \verb"\Deltamix\Gm" and similar constructions---this construct will typeset
-% as $\Delta_{MIX}G$ using the \verb"Thompson" package option, for example,
-% and as $\Delta_\text{mix}G$ using the \verb"Sandler" package option.
+% as $\Delta_{MIX}G$ using the |Thompson| package option, for example,
+% and as $\Delta_\text{mix}\Gt$ using the |Sandler| package option.
 %    \begin{macrocode}
-\newcommand*{\mixing}{{\text{mix}}}
-\newcommand*{\Deltamix}[1]{\Delta{#1}_\mixing}
+\NewDocumentCommand{\mixing}{}{{\text{mix}}}
+\NewDocumentCommand{\Deltamix}{m}
+    {\Delta{#1}\c_math_subscript_token\mixing}
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
 %
-% \begin{macro}{\Deltafus}
-% \begin{macro}{\fusion}
-% \begin{macro}{\Deltavap}
-% \begin{macro}{\vaporization}
-% \begin{macro}{\Deltasub}
-% \begin{macro}{\sublimation}
-% \begin{macro}{\Deltarxn}
-% \begin{macro}{\reaction}
+% \pagebreak[2]%
+% \begin{macro}{\Deltafus,\fusion,\Deltavap,\vaporization}
+% \begin{macro}{\Deltasub,\sublimation,\Deltarxn,\reaction}
 % Similar entities for property changes on fusion, reaction, sublimation, and
-% vaporization are defined. The heat of reaction is handled differently if
-% \cs{cP} is its argument: one must typeset $\Delta C_{P,\text{rxn}}$ and
-% $\Delta C_{P,\text{rxn}}^\circ$ rather than
-% $\Delta{C_P}_\text{rxn}$ and $\Delta{C_P}^\circ_\text{rxn}$.
+% vaporization are defined.
 %    \begin{macrocode}
-\newcommand*{\fusion}{{\text{fus}}}
-\newcommand*{\reaction}{{\text{rxn}}}
-\newcommand*{\sublimation}{{\text{sub}}}
-\newcommand*{\vaporization}{{\text{vap}}}
-\newcommand*{\formation}{f}
-\newcommand*{\Deltafus}[1]{\Delta{#1}^\fusion}
-\newcommand*{\Deltasub}[1]{\Delta{#1}^\sublimation}
-\newcommand*{\Deltavap}[1]{\Delta{#1}^\vaporization}
-% TODO It would be nice not to have to handle \cP in a special way....
-\let\Delta at rxn@sym\relax
-\DeclareSubscrSymbol{@DeltarxncP}{\Delta at rxn@sym}{\pressure at symbol,\reaction}
-\DeclareSubscrSymbol{@Deltarxn}{\Delta at rxn@sym}{\reaction}
-\newcommand*{\Deltarxn}[1]{%
-    \def\tmp at arg{#1}%
-    \def\tmp@@arg{\cP}%
-    \ifx\tmp at arg\tmp@@arg\relax
-      \def\@command{\def\Delta at rxn@sym{\Delta\@intensive\heatcapacitysymbol}%
-                    \@DeltarxncP}
-    \else
-      \def\@command{\def\Delta at rxn@sym{\Delta{#1}}\@Deltarxn}
-    \fi
-    \@command
+\NewDocumentCommand{\fusion}{}{{\text{fus}}}
+\NewDocumentCommand{\reaction}{}{{\text{rxn}}}
+\NewDocumentCommand{\sublimation}{}{{\text{sub}}}
+\NewDocumentCommand{\vaporization}{}{{\text{vap}}}
+\NewDocumentCommand{\formation}{}{f}
+\NewDocumentCommand{\Deltafus}{m}
+    {\Delta #1\c_math_superscript_token\fusion}
+\NewDocumentCommand{\Deltasub}{m}
+    {\Delta #1\c_math_superscript_token\sublimation}
+\NewDocumentCommand{\Deltavap}{m}
+    {\Delta #1\c_math_superscript_token\vaporization}
+\NewDocumentCommand{\Deltarxn}{m}
+    {\Delta #1\c_math_subscript_token\reaction}
+\tl_new:N \l_@@_Deltaf_sym_tl
+\NewSubscriptedSymbol{\@@_Deltaf}{\l_@@_Deltaf_sym_tl}{f}
+\NewDocumentCommand{\Deltaf}{m}
+{ \tl_set:Nn \l_@@_Deltaf_sym_tl {\Delta #1}
+  \@@_Deltaf
 }
-\let\Delta at f@sym\relax
-\DeclareSubscrSymbol{@Deltaf}{\Delta at f@sym}{f}
-\newcommand*{\Deltaf}[1]{\def\Delta at f@sym{\Delta{#1}}\@Deltaf}
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
 %
 % \begin{macro}{\fmix}
 % The \cs{fmix} command is intended to describe fugacities in mixtures.
@@ -2753,7 +3359,7 @@
 % just $f_i$, and this command creates a consistent way to change between
 % such options.
 %    \begin{macrocode}
-\newcommand*{\fmix}{\hat{f}}
+\NewDocumentCommand{\fmix}{}{\hat{f}}
 %    \end{macrocode}
 % \end{macro}
 % \begin{macro}{\phimix}
@@ -2760,7 +3366,7 @@
 % A similar command, \cs{phimix}, renders $\hat\phi$ by default to represent
 % the fugacity coefficient in the mixture.
 %    \begin{macrocode}
-\newcommand*{\phimix}{\hat\phi}
+\NewDocumentCommand{\phimix}{}{\hat\phi}
 %    \end{macrocode}
 % \end{macro}
 % \begin{macro}{\fpure}
@@ -2771,16 +3377,16 @@
 % creates a consistent way to change between the these options. A similar
 % command for $\phi$ is given, \cs{phipure}, for fugacity coefficients.
 %    \begin{macrocode}
-\newcommand*{\fpure}{f}
-\let\phipure\phi
+\NewDocumentCommand{\fpure}{}{f}
+\NewDocumentCommand{\phipure}{}{\phi}
 %    \end{macrocode}
 % \end{macro}
 %
 % \subsection{Partial Molar Quantities}
 % \begin{macro}{\partialmolar}
-% Partial molar quantities appear as $\thermooverline{G_i}$ or,
-% for residual properties, $\thermooverline{G_i^R}$, rather than something like
-% $\thermooverline{G}_i$ or $\thermooverline{G}_i^R$, which looks better but
+% Partial molar quantities with superscripts appear as $\Gpm[\IG]{i}$ or
+% $\GRpm{i}$, rather than something like
+% $\overline{G}^\IG_i$ or $\overline{G}_i^R$; the former looks better but
 % is harder to implement for obvious reasons. Their definitions allow them to
 % be used as symbols, something like \verb"\Gpm_i", \verb"\Gpm^{\IGM}_i",
 % \verb"\Gpm^{\IGM}_i", and even \verb"\Gpm_i^{\IGM}";
@@ -2789,439 +3395,295 @@
 % The macro \cs{partialmolar} can be used to create an arbitrary partial
 % molar symbol.
 %    \begin{macrocode}
-\let\pm at symbol\relax
-\newcommand*{\partialmolar}[1]{\gdef\pm at symbol{#1}\generic at pm}
-% if nextchar is _
-\def\generic at pm{\@ifnextchar_\@generic at pm\@@generic at pm}
-% then store the argument
-\def\@generic at pm#1#2{%
-    \gdef\pm at arg{#2}%
-    % if nextchar after argument is ^
-    \@ifnextchar^\@@@generic at pm\@@@@generic at pm
+\tl_new:N \l_@@_pm_symbol_tl
+\tl_new:N \l_@@_pm_arg_tl
+\NewDocumentCommand{\partialmolar}{m}
+{
+  \tl_set:Nn \l_@@_pm_symbol_tl {#1}
+  \@@_generic_pm:
 }
-% then print it this way
-\def\@@@generic at pm#1#2{\thermo at overline{\pm at symbol^{#2}_{\pm at arg}}}
-% else do it this way
-\def\@@@@generic at pm{\thermo at overline{\pm at symbol_{\pm at arg}}}
-% else, check whether there is also a ^ coming, otherwise assume
-% it's [] or {}
-\def\@@generic at pm{\@ifnextchar^\@@@@@generic at pm\@pm at bracket@check}
-\def\@@@@@generic at pm#1#2#3#4{\thermo at overline{\pm at symbol^{#2}_{#4}}}
-\def\@pm at bracket@check{\@ifnextchar[\@pm at bracket@yes\@pm at bracket@no}
-\def\@pm at bracket@yes[#1]#2{\thermo at overline{\pm at symbol^{#1}_{#2}}}
-\def\@pm at bracket@no#1{\thermo at overline{\pm at symbol_{#1}}}
+%% cases to consider:
+%% (1) \Mpm{i}
+%% (2) \Mpm[S]{i}
+%% (3) \Mpm^S_i
+%% (4) \Mpm_i^S
+%% (5) \Mpm_i
+%% note that \Mpm^S with no subscript makes no sense and is thus forbidden
+\cs_new:Nn \@@_generic_pm:
+{
+  \peek_catcode_remove:NTF \c_math_subscript_token
+  {% case 4 or case 5
+    \@@_pm_case_four_or_five
+  }
+  {% look for superscript token
+    \peek_catcode_remove:NTF \c_math_superscript_token
+    {% case 3: \Mpm^{#1}_{#2} or \Mpm^{#1}{#2}
+      \@@_pm_case_three
+    }
+    {% Look for optional argument [...]
+      \peek_charcode:NTF [
+      {% case 2: \Mpm[S]{i}
+        \@@_pm_case_two
+      }
+      {% case 1: \Mpm{i}
+        \@@_pm_case_one
+      }
+    }
+  }
+}
+\cs_new:Npn \@@_pm_case_one #1
+{
+  \@@_overline:n {\l_@@_pm_symbol_tl\c_math_subscript_token{#1}}
+}
+\cs_new:Npn \@@_pm_case_two [#1]#2
+{
+  \@@_overline:n {\l_@@_pm_symbol_tl
+    \c_math_superscript_token{#1}\c_math_subscript_token{#2}}
+}
+\cs_new:Npn \@@_pm_case_three #1
+{
+  \tl_set:Nn \l_@@_pm_arg_tl {#1}
+  \peek_catcode_remove:NTF \c_math_subscript_token
+  { \@@_pm_case_three_part_two }
+  { \@@_pm_case_three_part_two }
+}
+\cs_new:Npn \@@_pm_case_three_part_two #1
+{
+  \@@_overline:n {\l_@@_pm_symbol_tl
+    \c_math_superscript_token{\l_@@_pm_arg_tl}
+    \c_math_subscript_token{#1}}
+}
+\cs_new:Npn \@@_pm_case_four_or_five #1
+{
+  \tl_set:Nn \l_@@_pm_arg_tl {#1}
+  \peek_catcode_remove:NTF \c_math_superscript_token
+  { \@@_pm_case_four }
+  { \@@_pm_case_five }
+}
+\cs_new:Npn \@@_pm_case_four #1
+{
+  \@@_overline:n {\l_@@_pm_symbol_tl\c_math_superscript_token{#1}
+    \c_math_subscript_token{\l_@@_pm_arg_tl}}
+}
+\cs_new:Npn \@@_pm_case_five
+{
+  \@@_overline:n {\l_@@_pm_symbol_tl
+    \c_math_subscript_token{\l_@@_pm_arg_tl}}
+}
 %    \end{macrocode}
 % \end{macro}
 %
 % \subsection{Symbol Definitions}
 % These macros define the user interface to the symbols for energy, volume,
-% and so forth. We define the ``extra'' symbols \cs{Bt} and \cs{Mt} to
-% represent arbitrary properties.
-% \begin{macro}{\Nt}
-% \begin{macro}{\Et}
-% \begin{macro}{\Ut}
-% \begin{macro}{\Ft}
-% \begin{macro}{\Gt}
-% \begin{macro}{\Ht}
-% \begin{macro}{\Lt}
-% \begin{macro}{\At}
-% \begin{macro}{\St}
-% \begin{macro}{\Vt}
-% \begin{macro}{\Qt}
-% \begin{macro}{\Wt}
-% \begin{macro}{\Mt}
-% \begin{macro}{\Bt}
-% \penalty-600%
-% First, the extensive properties.
-%    \begin{macrocode}
-\newcommand*{\Nt}{\mole at symbol}
-\newcommand*{\Et}{\@extensive\totalenergy at symbol}
-\newcommand*{\Ut}{\@extensive\internalenergy at symbol}
-\newcommand*{\Ft}{\@extensive\Helmholtz at symbol}
-\newcommand*{\Gt}{\@extensive\Gibbs at symbol}
-\newcommand*{\Ht}{\@extensive\enthalpy at symbol}
-\newcommand*{\Lt}{\@extensive\Landau at symbol}
-\newcommand*{\At}{\@extensive\area at symbol}
-\newcommand*{\St}{\@extensive\entropy at symbol}
-\newcommand*{\Vt}{\@extensive\volume at symbol}
-\newcommand*{\Qt}{\@extensive\heat at symbol}
-\newcommand*{\Wt}{\@extensive\work at symbol}
-\newcommand*{\Mt}{\@extensive M}
-\newcommand*{\Bt}{\@extensive B}
-%    \end{macrocode}
+% and so forth. There are five commands that define thermodynamic properties.
+%
+% \begin{macro}{\NewExtensiveProperty}
+% The command \cs{NewExtensiveProperty} declares macros for a total, molar, and
+% specific version of the symbol; for example, a second heat-like property
+% could be defined via
+% \begin{verbatim}
+%  \NewExtensiveProperty{R}{\mathcal{Q}}
+%\end{verbatim}
+% \NewExtensiveProperty{R}{\mathcal{Q}}\relax
+% The command above would declare the macros \cs{Rt}, \cs{Rm}, and \cs{Rs}
+% that expand to $\Rt$, $\Rm$, and $\Rs$, respectively, using the default
+% package options.
 % \end{macro}
+%
+% \begin{macro}{\NewPartialMolarProperty}
+% The command \cs{NewPartialMolarProperty} declares a macro for the partial
+% molar quantity. For example,
+% \begin{verbatim}
+%  \NewPartialMolarProperty{I}{\Psi}
+%\end{verbatim}
+% \NewPartialMolarProperty{I}{\Psi}\relax
+% would create the command \cs{Ipm}, which would typeset a partial molar
+% command with the base symbol $\Psi$, yielding $\Ipm{i}$.
 % \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
 %
-% \begin{macro}{\Em}
-% \begin{macro}{\Um}
-% \begin{macro}{\Fm}
-% \begin{macro}{\Gm}
-% \begin{macro}{\Hm}
-% \begin{macro}{\Lm}
-% \begin{macro}{\Am}
-% \begin{macro}{\Sm}
-% \begin{macro}{\Vm}
-% \begin{macro}{\Qm}
-%^^A \penalty-600%
-% Then the molar properties.
+% \begin{macro}{\NewThermodynamicProperty}
+% Declaring a new potential is handled by the
+% \cs{NewThermodynamicProperty} macro, which takes two arguments. The first
+% is the base of the name, and the second is the base of the symbol. This
+% declares four new commands for the extensive, molar, specific, and partial
+% molar properties. These commands consist of the first argument followed by
+% \verb"t", \verb"m", \verb"s", and \verb"pm", respectively. For example, one
+% might define the entropy via
+% \begin{verbatim}
+%  \NewThermodynamicProperty{S}{S}
+%\end{verbatim}
+% and it would define the macros \cs{St}, \cs{Sm}, \cs{Ss}, and \cs{Spm} that
+% yield, respectively, $\St$, S, $\hat S$, and $\Spm{i}$ (assuming the
+% subscript to the partial molar quantity was $i$).
+% It would also declare residual and excess properties for that base symbol.
+% Note that the actual definition of the entropy and the other standard
+% properties is slightly more complicated so as to allow for different symbols
+% to be used in different textbooks.
 %    \begin{macrocode}
-\newcommand*{\Em}{\@intensive\totalenergy at symbol}
-\newcommand*{\Um}{\@intensive\internalenergy at symbol}
-\newcommand*{\Fm}{\@intensive\Helmholtz at symbol}
-\newcommand*{\Gm}{\@intensive\Gibbs at symbol}
-\newcommand*{\Hm}{\@intensive\enthalpy at symbol}
-\newcommand*{\Lm}{\@intensive\Landau at symbol}
-\newcommand*{\Am}{\@intensive\area at symbol}
-\newcommand*{\Sm}{\@intensive\entropy at symbol}
-\newcommand*{\Vm}{\@intensive\volume at symbol}
-\newcommand*{\Qm}{\@intensive\heat at symbol}
+\NewDocumentCommand{\NewThermodynamicProperty}{m m}
+{
+  \NewExtensiveProperty{#1}{#2}
+  \NewPartialMolarProperty{#1}{#2}
+  \NewResidualProperty{#1}{#2}
+  \NewExcessProperty{#1}{#2}
+}
+\NewDocumentCommand{\NewExtensiveProperty}{m m}
+{
+  % Extensive property
+  \exp_after:wN \NewDocumentCommand \exp_after:wN
+    {\cs:w #1t\cs_end:}{}{\@@_extensive:n {#2}}
+  % Molar property
+  \exp_after:wN \NewDocumentCommand \exp_after:wN
+    {\cs:w #1m\cs_end:}{}{\@@_intensive:n {#2}}
+  % Specific property
+  \exp_after:wN \NewDocumentCommand \exp_after:wN
+    {\cs:w #1s\cs_end:}{}{\@@_specific:n {#2}}
+}
+\NewDocumentCommand{\NewPartialMolarProperty}{m m}
+{
+  % Partial molar property
+  \exp_after:wN \NewDocumentCommand \exp_after:wN
+    {\cs:w #1pm\cs_end:}{}{\partialmolar{#2}}
+}
+\NewDocumentCommand{\NewExcessProperty}{m m}
+{
+  \exp_after:wN \NewSuperscriptedSymbol \exp_after:wN
+    {\cs:w #1 Et\cs_end:}{\@@_extensive:n{#2}}{\excess}
+  \exp_after:wN \NewSuperscriptedSymbol \exp_after:wN
+    {\cs:w #1 E\cs_end:}{\@@_intensive:n{#2}}{\excess}
+  \exp_after:wN \NewSuperscriptedSymbol \exp_after:wN
+    {\cs:w #1 Es\cs_end:}{\@@_specific:n{#2}}{\excess}
+
+  %^^A TODO: make super- or subscripted partial molar quantities work
+  % Excess partial molar property
+  \exp_after:wN \NewDocumentCommand \exp_after:wN
+    {\cs:w #1Epm\cs_end:}{}{\partialmolar{#2}
+       \c_math_superscript_token\excess}
+}
+\NewDocumentCommand{\NewResidualProperty}{m m}
+{
+  \exp_after:wN \NewSuperscriptedSymbol \exp_after:wN
+    {\cs:w #1 Rt\cs_end:}{\@@_extensive:n{#2}}{\residual}
+  \exp_after:wN \NewSuperscriptedSymbol \exp_after:wN
+    {\cs:w #1 R\cs_end:}{\@@_intensive:n{#2}}{\residual}
+  \exp_after:wN \NewSuperscriptedSymbol \exp_after:wN
+    {\cs:w #1 Rs\cs_end:}{\@@_specific:n{#2}}{\residual}
+
+  % Residual partial molar property
+  \exp_after:wN \NewDocumentCommand \exp_after:wN
+    {\cs:w #1Rpm\cs_end:}{}{\partialmolar{#2}
+        \c_math_superscript_token\residual}
+}
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \begin{macro}{\Wm}
-% \begin{macro}{\Mm}
-% \begin{macro}{\Bm}
-% More molar properties.
-%    \begin{macrocode}
-\newcommand*{\Wm}{\@intensive\work at symbol}
-\newcommand*{\Mm}{\@intensive M}
-\newcommand*{\Bm}{\@intensive B}
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\Es}
-% \begin{macro}{\Us}
-% \begin{macro}{\Fs}
-% \begin{macro}{\Gs}
-% \begin{macro}{\Hs}
-% \begin{macro}{\Ls}
-% \begin{macro}{\As}
-% \begin{macro}{\Ss}
-% \begin{macro}{\Vs}
-% \begin{macro}{\Qs}
-% \begin{macro}{\Ws}
-% \begin{macro}{\Ms}
-% \begin{macro}{\Bs}
+% \begin{macro}{\Nt,\Et,\Em,\Es,\Epm}
 % \penalty-600%
-% Now the specific (per unit mass) properties.
+% We define \cs{Nt} as the number of moles, as that changes between books a
+% lot, but it does not have extensive, molar, and specific equivalents.
+% Heat and work are defined, but lack partial molar properties. Area does not
+% have excess or residual properties.
 %    \begin{macrocode}
-\newcommand*{\Us}{\@specific\internalenergy at symbol}
-\newcommand*{\Es}{\@specific\totalenergy at symbol}
-\newcommand*{\Fs}{\@specific\Helmholtz at symbol}
-\newcommand*{\Gs}{\@specific\Gibbs at symbol}
-\newcommand*{\Hs}{\@specific\enthalpy at symbol}
-\newcommand*{\Ls}{\@specific\Landau at symbol}
-\newcommand*{\As}{\@specific\area at symbol}
-\newcommand*{\Ss}{\@specific\entropy at symbol}
-\newcommand*{\Vs}{\@specific\volume at symbol}
-\newcommand*{\Qs}{\@specific\heat at symbol}
-\newcommand*{\Ws}{\@specific\work at symbol}
-\newcommand*{\Ms}{\@specific M}
-\newcommand*{\Bs}{\@specific B}
+\NewDocumentCommand{\Nt}{}{\g_@@_mole_symbol}
+\NewThermodynamicProperty{E}{\g_@@_total_energy_symbol}
+\NewThermodynamicProperty{U}{\g_@@_internal_energy_symbol}
+\NewThermodynamicProperty{F}{\g_@@_Helmholtz_symbol}
+\NewThermodynamicProperty{G}{\g_@@_Gibbs_symbol}
+\NewThermodynamicProperty{H}{\g_@@_enthalpy_symbol}
+\NewThermodynamicProperty{L}{\g_@@_Landau_symbol}
+\NewThermodynamicProperty{V}{\g_@@_volume_symbol}
+\NewThermodynamicProperty{S}{\g_@@_entropy_symbol}
+\NewExtensiveProperty{A}{\g_@@_area_symbol}
+\NewPartialMolarProperty{A}{\g_@@_area_symbol}
+\NewExtensiveProperty{Q}{\g_@@_heat_symbol}
+\NewExtensiveProperty{W}{\g_@@_work_symbol}
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
 %
-% \begin{macro}{\Epm}
-% \begin{macro}{\Upm}
-% \begin{macro}{\Hpm}
-% \begin{macro}{\Fpm}
-% \begin{macro}{\Gpm}
-% \begin{macro}{\Apm}
-% \begin{macro}{\Spm}
-% \begin{macro}{\Vpm}
-% \begin{macro}{\Lpm}
-% \begin{macro}{\Mpm}
-% \begin{macro}{\Bpm}
-% Now the partial molar properties.
-%    \begin{macrocode}
-\newcommand*{\Epm}{\partialmolar{\totalenergy at symbol}}
-\newcommand*{\Upm}{\partialmolar{\internalenergy at symbol}}
-\newcommand*{\Hpm}{\partialmolar{\enthalpy at symbol}}
-\newcommand*{\Fpm}{\partialmolar{\Helmholtz at symbol}}
-\newcommand*{\Gpm}{\partialmolar{\Gibbs at symbol}}
-\newcommand*{\Apm}{\partialmolar{\area at symbol}}
-\newcommand*{\Spm}{\partialmolar{\entropy at symbol}}
-\newcommand*{\Vpm}{\partialmolar{\volume at symbol}}
-\newcommand*{\Lpm}{\partialmolar{\Omega}}
-\newcommand*{\Mpm}{\partialmolar{M}}
-\newcommand*{\Bpm}{\partialmolar{B}}
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\cPpm}
-% \begin{macro}{\cVpm}
+% \begin{macro}{\cVpm,\cPpm}
 % Partial molar heat capacities are \emph{hard}, but the following
 % implementation seems to work flawlessly\dots so far.
 %    \begin{macrocode}
-\newcommand*{\cPpm}{%
-  \def\@@@generic at pm##1##2{%
-    \thermo at overline{\pm at symbol^{##2}_{\pressure at symbol,\pm at arg}}}%
-  \def\@@@@generic at pm{\thermo at overline{\pm at symbol_{\pressure at symbol,\pm at arg}}}%
-  \def\@@@@@generic at pm##1##2##3##4{%
-    \thermo at overline{\pm at symbol^{##2}_{\pressure at symbol,##4}}}%
-  \def\@pm at bracket@yes[##1]##2{%
-    \thermo at overline{\pm at symbol^{##1}_{\pressure at symbol,##2}}}%
-  \def\@pm at bracket@no##1{\thermo at overline{\pm at symbol_{\pressure at symbol,##1}}}%
-  \partialmolar{\heatcapacitysymbol}%
+\NewDocumentCommand{\cPpm}{}
+{
+  \cs_set:Npn \@@_pm_case_one ##1
+  {
+    \@@_overline:n {\l_@@_pm_symbol_tl\c_math_subscript_token
+        {\g_@@_pressure_symbol,##1}}
+  }
+  \cs_set:Npn \@@_pm_case_two [##1]##2
+  {
+    \@@_overline:n {\l_@@_pm_symbol_tl\c_math_superscript_token{##1}
+        \c_math_subscript_token{\g_@@_pressure_symbol,##2}}
+  }
+  \cs_set:Npn \@@_pm_case_three_part_two ##1
+  {
+    \@@_overline:n {\l_@@_pm_symbol_tl
+        \c_math_superscript_token{\l_@@_pm_arg_tl}
+        \c_math_subscript_token{\g_@@_pressure_symbol,##1}}
+  }
+  \cs_set:Npn \@@_pm_case_four ##1
+  {
+    \@@_overline:n {\l_@@_pm_symbol_tl
+        \c_math_superscript_token{##1}\c_math_subscript_token
+      {\g_@@_pressure_symbol,\l_@@_pm_arg_tl}}
+  }
+  \cs_set:Npn \@@_pm_case_five
+  {
+    \@@_overline:n {\l_@@_pm_symbol_tl\c_math_subscript_token
+        {\g_@@_pressure_symbol,\l_@@_pm_arg_tl}}
+  }
+  \partialmolar{\heatcapacitysymbol}
 }
-\newcommand*{\cVpm}{%
-  \def\@@@generic at pm##1##2{%
-    \thermo at overline{\pm at symbol^{##2}_{\volume at symbol,\pm at arg}}}%
-  \def\@@@@generic at pm{\thermo at overline{\pm at symbol_{\volume at symbol,\pm at arg}}}%
-  \def\@@@@@generic at pm##1##2##3##4{%
-    \thermo at overline{\pm at symbol^{##2}_{\volume at symbol,##4}}}%
-  \def\@pm at bracket@yes[##1]##2{%
-    \thermo at overline{\pm at symbol^{##1}_{\volume at symbol,##2}}}%
-  \def\@pm at bracket@no##1{\thermo at overline{\pm at symbol_{\volume at symbol,##1}}}%
-  \partialmolar{\heatcapacitysymbol}%
+\NewDocumentCommand{\cVpm}{}
+{
+  \cs_set:Npn \@@_pm_case_one ##1
+  {
+    \@@_overline:n {\l_@@_pm_symbol_tl\c_math_subscript_token
+        {\g_@@_volume_symbol,##1}}
+  }
+  \cs_set:Npn \@@_pm_case_two [##1]##2
+  {
+    \@@_overline:n {\l_@@_pm_symbol_tl
+            \c_math_superscript_token{##1}\c_math_subscript_token
+        {\g_@@_volume_symbol,##2}}
+  }
+  \cs_set:Npn \@@_pm_case_three_part_two ##1
+  {
+    \@@_overline:n {\l_@@_pm_symbol_tl
+        \c_math_superscript_token{\l_@@_pm_arg_tl}
+        \c_math_subscript_token{\g_@@_volume_symbol,##1}}
+  }
+  \cs_set:Npn \@@_pm_case_four ##1
+  {
+    \@@_overline:n {\l_@@_pm_symbol_tl
+        \c_math_superscript_token{##1}
+        \c_math_subscript_token
+      {\g_@@_volume_symbol,\l_@@_pm_arg_tl}}
+  }
+  \cs_set:Npn \@@_pm_case_five
+  {
+    \@@_overline:n {\l_@@_pm_symbol_tl\c_math_subscript_token
+        {\g_@@_volume_symbol,\l_@@_pm_arg_tl}}
+  }
+  \partialmolar{\heatcapacitysymbol}
 }
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
 %
 % \subsection{Residual and Excess Properties}
-% \begin{macro}{\residual}
-% \begin{macro}{\excess}
-% Macros are defined for residual properties (departure from non-ideal gases)
+% \begin{macro}{\residual,\excess}
+% Macros are defined for residual properties (departure from ideal gases)
 % and excess properties (departure from ideal solutions). We begin with two
 % macros to use for defining generic residual and excess properties that are
 % not already defined.
 %    \begin{macrocode}
-\newcommand*{\residual}{R}
-\newcommand*{\excess}{E}
+\NewDocumentCommand{\residual}{}{R}
+\NewDocumentCommand{\excess}{}{E}
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
 %
-% \begin{macro}{\UR}
-% \begin{macro}{\HR}
-% \begin{macro}{\FR}
-% \begin{macro}{\GR}
-% \begin{macro}{\VR}
-% \begin{macro}{\SR}
-% The ordinary residual properties are molar.
-%    \begin{macrocode}
-\newcommand*{\UR}{\Um^\residual}
-\newcommand*{\HR}{\Hm^\residual}
-\newcommand*{\FR}{\Fm^\residual}
-\newcommand*{\GR}{\Gm^\residual}
-\newcommand*{\VR}{\Vm^\residual}
-\newcommand*{\SR}{\Sm^\residual}
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% 
-% \pagebreak[3]%
-% \begin{macro}{\URt}
-% \begin{macro}{\HRt}
-% \begin{macro}{\FRt}
-% \begin{macro}{\GRt}
-% \begin{macro}{\VRt}
-% \begin{macro}{\SRt}
-% We define similar macros for the extensive residual properties. These are
-% appended by a \verb"t" (for ``total'').
-%    \begin{macrocode}
-\newcommand*{\URt}{\Ut^\residual}
-\newcommand*{\HRt}{\Ht^\residual}
-\newcommand*{\FRt}{\Ft^\residual}
-\newcommand*{\GRt}{\Gt^\residual}
-\newcommand*{\VRt}{\Vt^\residual}
-\newcommand*{\SRt}{\St^\residual}
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\URs}
-% \begin{macro}{\HRs}
-% \begin{macro}{\FRs}
-% \begin{macro}{\GRs}
-% \begin{macro}{\VRs}
-% \begin{macro}{\SRs}
-% Similar macros are declared for the specific residual properties.
-% These are appended by an \verb"s".
-%    \begin{macrocode}
-\newcommand*{\URs}{\Us^\residual}
-\newcommand*{\HRs}{\Hs^\residual}
-\newcommand*{\FRs}{\Fs^\residual}
-\newcommand*{\GRs}{\Gs^\residual}
-\newcommand*{\VRs}{\Vs^\residual}
-\newcommand*{\SRs}{\Ss^\residual}
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \penalty-500
-% \begin{macro}{\URpm}
-% \begin{macro}{\HRpm}
-% \begin{macro}{\FRpm}
-% \begin{macro}{\GRpm}
-% \begin{macro}{\VRpm}
-% \begin{macro}{\SRpm}
-% Now for the partial molar residual properties.
-% These are appended by \verb"pm".
-%    \begin{macrocode}
-\newcommand*{\URpm}{\partialmolar{\internalenergy at symbol^\residual}}
-\newcommand*{\HRpm}{\partialmolar{\enthalpy at symbol^\residual}}
-\newcommand*{\FRpm}{\partialmolar{\Helmholtz at symbol^\residual}}
-\newcommand*{\GRpm}{\partialmolar{\Gibbs at symbol^\residual}}
-\newcommand*{\VRpm}{\partialmolar{\volume at symbol^\residual}}
-\newcommand*{\SRpm}{\partialmolar{\entropy at symbol^\residual}}
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\UE}
-% \begin{macro}{\HE}
-% \begin{macro}{\FE}
-% \begin{macro}{\GE}
-% \begin{macro}{\VE}
-% \begin{macro}{\SE}
-% Now for the excess molar properties.
-%    \begin{macrocode}
-\newcommand*{\UE}{\Um^\excess}
-\newcommand*{\FE}{\Fm^\excess}
-\newcommand*{\HE}{\Hm^\excess}
-\newcommand*{\GE}{\Gm^\excess}
-\newcommand*{\SE}{\Sm^\excess}
-\newcommand*{\VE}{\Vm^\excess}
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\UEt}
-% \begin{macro}{\HEt}
-% \begin{macro}{\FEt}
-% \begin{macro}{\GEt}
-% \begin{macro}{\VEt}
-% \begin{macro}{\SEt}
-% Similarly, the extensive excess properties.
-%    \begin{macrocode}
-\newcommand*{\UEt}{\Ut^\excess}
-\newcommand*{\FEt}{\Ft^\excess}
-\newcommand*{\HEt}{\Ht^\excess}
-\newcommand*{\GEt}{\Gt^\excess}
-\newcommand*{\SEt}{\St^\excess}
-\newcommand*{\VEt}{\Vt^\excess}
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\UEs}
-% \begin{macro}{\HEs}
-% \begin{macro}{\FEs}
-% \begin{macro}{\GEs}
-% \begin{macro}{\VEs}
-% \begin{macro}{\SEs}
-% Now for the specific excess properties.
-%    \begin{macrocode}
-\newcommand*{\UEs}{\Us^\excess}
-\newcommand*{\FEs}{\Fs^\excess}
-\newcommand*{\HEs}{\Hs^\excess}
-\newcommand*{\GEs}{\Gs^\excess}
-\newcommand*{\SEs}{\Ss^\excess}
-\newcommand*{\VEs}{\Vs^\excess}
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \pagebreak[3]%
-% \begin{macro}{\UEpm}
-% \begin{macro}{\HEpm}
-% \begin{macro}{\FEpm}
-% \begin{macro}{\GEpm}
-% \begin{macro}{\VEpm}
-% \begin{macro}{\SEpm}
-% Finally, the excess partial molar quantities.
-%    \begin{macrocode}
-\newcommand*{\UEpm}{\partialmolar{\internalenergy at symbol^\excess}}
-\newcommand*{\HEpm}{\partialmolar{\enthalpy at symbol^\excess}}
-\newcommand*{\FEpm}{\partialmolar{\Helmholtz at symbol^\excess}}
-\newcommand*{\GEpm}{\partialmolar{\Gibbs at symbol^\excess}}
-\newcommand*{\VEpm}{\partialmolar{\volume at symbol^\excess}}
-\newcommand*{\SEpm}{\partialmolar{\entropy at symbol^\excess}}
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\prodall}
-% \begin{macro}{\sumall}
-% \begin{macro}{\sumallbutlast}
+% \pagebreak[1]%
+% \begin{macro}{\prodall,\sumall,\summallbutlast}
 % The \cs{sumall} command and its cousin, \cs{sumallbutlast}, simplify the
 % typesetting of commonly-used sums; the command \cs{prodall} does the same
 % thing for products, viz.,
@@ -3235,102 +3697,194 @@
 %      K = \exp\left(\frac{-\Delta G_\text{rxn}^\circ}{RT}\right)
 %        = \prod_{i=1}^C a_i^{\nu_i} \]
 %    \begin{macrocode}
-\newcommand*{\sumall}{\@ifnextchar_\@sumall\@@sumall}
-\def\@sumall#1#2{\sum_{#2=1}^{\ncomponents}}
-\def\@@sumall#1{\sum_{#1=1}^{\ncomponents}}
-\newcommand*{\sumallbutlast}{\@ifnextchar_\@sumallbutlast\@@sumallbutlast}
-\def\@sumallbutlast#1#2{\sum_{#2=1}^{\ncomponents-1}}
-\def\@@sumallbutlast#1{\sum_{#1=1}^{\ncomponents-1}}
-\newcommand*{\prodall}{\@ifnextchar_\@prodall\@@prodall}
-\def\@prodall#1#2{\prod_{#2=1}^{\ncomponents}}
-\def\@@prodall#1{\prod_{#1=1}^{\ncomponents}}
+\NewDocumentCommand{\sumall}{m m}
+  { \sum\c_math_subscript_token{#2=1}
+      \c_math_superscript_token{\ncomponents} }
+\NewDocumentCommand{\sumallbutlast}{m m}
+  { \sum\c_math_subscript_token{#2=1}
+      \c_math_superscript_token{\ncomponents-1} }
+\NewDocumentCommand{\prodall}{m m}
+  { \prod\c_math_subscript_token{#2=1}
+       \c_math_superscript_token{\ncomponents} }
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
-% \end{macro}
 %
-% \begin{macro}{\IG}
-% \begin{macro}{\IGM}
-% \begin{macro}{\IS}
+% \begin{macro}{\IG,\IGM,\IS}
 % The \cs{IG}, \cs{IGM}, and \cs{IS} macros (meaning ``ideal gas,'' ``ideal
 % gas mixture,'' and ``ideal solution,'' respectively) should be used to
-% make clean transitions between textbooks---some use ``IM'' rather than ``IS''
-% for example.
+% make clean transitions between textbooks---some use ``IM'' or ``ID'' rather
+% than ``IS,'' for example.
 %    \begin{macrocode}
-\newcommand*{\IG}{{\text{IG}}}
-\newcommand*{\IGM}{{\text{IGM}}}
-\newcommand*{\IS}{{\text{IS}}}
+\NewDocumentCommand{\IG}{}{{\text{IG}}}
+\NewDocumentCommand{\IGM}{}{{\text{IGM}}}
+\NewDocumentCommand{\IS}{}{{\text{IS}}}
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
-% \end{macro}
 %
-% \begin{macro}{\Henryrat}
-% \begin{macro}{\Henrymol}
+% \begin{macro}{\Henryrat,\Henrymol}
 % The Henry's Law constants for the rational basis ($y_i P = x_i h_i$) and
 % the molal basis ($y_i P = C_i \mathcal{H}_i$) are given by the macros
 % \cs{Henryrat} and \cs{Henrymol}, respectively. Using them this way
 % consistently allows for easy switching back and forth.
 %    \begin{macrocode}
-\newcommand*{\Henryrat}{h}
-\newcommand*{\Henrymol}{{\mathcal{H}}}
+\NewDocumentCommand{\Henryrat}{}{h}
+\NewDocumentCommand{\Henrymol}{}{\mathcal{H}}
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
 %
-% \begin{macro}{\gammarat}
-% \begin{macro}{\gammamol}
+% \begin{macro}{\gammarat,\gammamol}
 % The ordinary activity coefficient is universally denoted $\gamma$, so I
-% have not defined a special macro for that. However, the Henry's Law activity
-% coefficients are far from universal, so I have defined macros to make their
-% use consistent. The defaults render \cs{gammarat} as $\gamma^\ast$ and
-% \cs{gammamol} as $\gamma^\square$.
+% have not defined a special macro for that. However, symbols for the Henry's
+% Law activity coefficients are far from universal, so I have defined macros to
+% make their use consistent. The defaults render \cs{gammarat} as $\gamma^\ast$
+% and \cs{gammamol} as $\gamma^\square$.
 % \cs{gammamol} will use \cs{square} from packages if it is defined; if not,
-% it ``fakes it'' with the definition below (based on the \textsf{amsthm}
-% package).
-%^^A Code for \square ripped off from amsthm.sty with tweaks
+% it ``fakes it'' with the definition below.
+%^^A Backup for \square adapted from amsthm.sty with tweaks to make it
+%^^A look reasonably similar to that from newpx (i.e., smaller than the
+%^^A amsfonts) version
 %    \begin{macrocode}
 \AtBeginDocument{%
   \providecommand*{\square}{%
     \text{\leavevmode
-      \hbox to.77778em{%
+      \hbox to.65em{%
       \hfil\vrule
-      \vbox to.6em{\hrule width.6em\vfil\hrule}%
+      \vbox to.53em{\hrule width.45em\vfil\hrule}%
       \vrule\hfil}%
     }%
   }%
 }
-\newcommand*{\gammarat}{\gamma^\ast}
-\newcommand*{\gammamol}{\gamma^\square}
+\NewDocumentCommand{\gammarat}{}{\gamma\c_math_superscript_token\ast}
+\NewDocumentCommand{\gammamol}{}{\gamma\c_math_superscript_token\square}
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
+% \begin{environment}{thermovmatrix}
+% This is a non-user-interface wrapper environment used to detect, in
+% effect, whether \pkg{amsmath} has been loaded. If so, it uses its
+% \env{vmatrix} environment for Jacobians; if not, it fakes it with
+% \env{array} (which does not look nearly as good).
+%    \begin{macrocode}
+\NewDocumentEnvironment{thermovmatrix}{}
+{ \cs_if_exist:NTF \vmatrix
+  { \begin{vmatrix} }
+  { \left|\begin{array}{c c c c c c c c c c} }
+}
+{ \cs_if_exist:NTF \endvmatrix
+  {  \end{vmatrix} }
+  {  \end{array}\right| }
+}
+%    \end{macrocode}
+% \end{environment}
 % \begin{macro}{Jacobian}
-% The \cs{Jacobian} command typesets the Jacobian, viz.,
-% \begin{verbatim}
-% \[ \Jacobian{K}{L}{X}{Y} =
-%   \begin{vmatrix}
-%     \displaystyle \Partial{K}{X}{Y} & \displaystyle \Partial{K}{Y}{X}
-%   \\[2ex]
-%     \displaystyle \Partial{L}{X}{Y} & \displaystyle \Partial{L}{Y}{X}
-%   \end{vmatrix}
-% \]
-%\end{verbatim}
-% produces
-% \[ \left(\frac{\partial(K,L)}{\partial(X,Y)}\right) =
-%   \begin{vmatrix}
-%     \displaystyle \left(\frac{\partial K}{\partial X}\right)_Y
-%     & \displaystyle \left(\frac{\partial K}{\partial Y}\right)_X \\[2ex]
-%     \displaystyle \left(\frac{\partial L}{\partial X}\right)_Y
-%     & \displaystyle \left(\frac{\partial L}{\partial Y}\right)_X
-%   \end{vmatrix}
-% \]
-% This macro is defined purely for convenience.
+% The \cs{Jacobian} command typesets the Leibnitz notation for the Jacobian
+% determinant.
+% \changes{v2.00}{2023/11/16}{Reimplemented \cs{Jacobian} to handle an
+%     arbitary number of variables and implemented \cs{Jacobiandet} to
+%     handle the matrix representation of the Jacobian.}
 %    \begin{macrocode}
-\newcommand*{\Jacobian}[4]{\frac{\partial{(#1,#2)}}{\partial{(#3,#4)}}}%
+\NewDocumentCommand{\Jacobian}{m m}
+    {\@@_frac:nn{\partial(#1)}{\partial{(#2)}}}
 %    \end{macrocode}
 % \end{macro}
+% \begin{macro}{Jacobiandet}
+% Similarly, the \cs{Jacobiandet} macro typesets the actual determinant that
+% the Jacobian notation represents.
+%    \begin{macrocode}
+\NewDocumentCommand{\Jacobiandet}{O{} O{} m m}
+{
+  \@@_Jacobian_set_ncomponents:nn {#3} {#4}
+  \begin{thermovmatrix}
+    \@@_Jacobianmatrix:nnnn {#1} {#2} {#3} {#4}
+  \end{thermovmatrix}
+}
+\seq_new:N \l_@@_row_seq
+\seq_new:N \l_@@_matrix_seq
+\clist_new:N \l_@@_other_vars_clist
+\clist_new:N \l_@@_other_vars_copy_clist
+\tl_new:N \l_@@_Jacobian_x_tl
+\tl_new:N \l_@@_Jacobian_n_tl
+\tl_new:N \l_@@_Jacobian_temp_tl
+\bool_new:N \l_@@_found_dots_bool
+\cs_new:Nn \@@_Jacobian_set_ncomponents:nn
+{
+  % If any entry is \dots, we assume the Jacobian is of the form
+  % d(f_1,\dots,f_n)/d(x_1,\dots,x_n) where f is some function
+  % (any symbol) and x is some variable (any symbol).
+  \tl_if_in:nnTF {#1} {\dots}
+  {% Has dots
+    \bool_set_true:N \l_@@_found_dots_bool
+    % look for what "x" is
+    \tl_set:Nn \l_@@_Jacobian_x_tl {\tl_head:n {#2}}
+    % look for what "n" is and set \ncomponents to it
+    \tl_set:Nx \l_@@_Jacobian_n_tl {\tl_item:nn {#2} {-1}}
+    \RenewExpandableDocumentCommand{\ncomponents}{}{\l_@@_Jacobian_n_tl}
+  }
+  {% Does not have dots; proceed accordingly
+    \bool_set_false:N \l_@@_found_dots_bool
+  }
+}
+\cs_new_protected:Nn \@@_Jacobianmatrix:nnnn
+{
+  \seq_clear:N \l_@@_matrix_seq
+  \clist_set:Nn \l_@@_other_vars_clist {#4}
+  \clist_set_eq:NN \l_@@_other_vars_copy_clist \l_@@_other_vars_clist
+
+  \clist_map_inline:nn {#3}
+  {
+    \seq_clear:N \l_@@_row_seq
+    \tl_if_in:nnTF {##1} {\dots}
+    {% The current row has "dots" => row is \vdots && \vdots
+      \seq_put_right:Nn \l_@@_matrix_seq
+        { \vdots \c_alignment_token \c_alignment_token \vdots }
+    }
+    {% Ordinary row
+      \clist_map_inline:nn {#4}
+      {
+        \tl_if_in:nnTF {####1} {\dots}
+        {% this column has "dots" in it
+          \seq_put_right:Nn \l_@@_row_seq \dots
+        }
+        {% Normal column
+          \clist_set_eq:NN \l_@@_other_vars_clist
+                           \l_@@_other_vars_copy_clist
+          \clist_remove_all:Nn \l_@@_other_vars_clist {####1}
+          \bool_if:NTF \l_@@_found_dots_bool
+          { \tl_set:Nn \l_@@_Jacobian_temp_tl {\tl_item:nn {####1} {-1}}
+            \seq_put_right:Nx \l_@@_row_seq
+            {
+              #1\Partial{##1}{####1}
+                  {\allbut{\l_@@_Jacobian_temp_tl}{\l_@@_Jacobian_x_tl}}
+            }
+          }
+          { \seq_put_right:Nx \l_@@_row_seq
+            {
+              #1\Partial{##1}{####1}
+                        {\clist_use:Nn \l_@@_other_vars_clist ,}
+            }
+          }
+        }
+      }
+      \seq_put_right:Nx \l_@@_matrix_seq
+      {
+        \seq_use:Nn \l_@@_row_seq { \c_alignment_token }
+      }
+    }
+  }
+  \tl_if_empty:nTF {#2}
+  {
+    \tl_if_eq:nnTF {#1} {\displaystyle}
+    { \seq_use:Nn \l_@@_matrix_seq { \\[2.75ex] } }
+    { \seq_use:Nn \l_@@_matrix_seq { \\[1.25ex] } }
+  }
+  {
+    \seq_use:Nn \l_@@_matrix_seq { \\[#2] }
+  }
+}
+%    \end{macrocode}
+% \end{macro}
+%^^X\end{implementation}
 %
+% \Finale
 % \iffalse
 %</package>
 %<*example>
@@ -3342,6 +3896,7 @@
 \author{Karl D. Hammond}
 \date{}
 \begin{document}
+\NewThermodynamicProperty{B}{B}
 \maketitle\noindent
 The combined laws:
 \begin{align*}
@@ -3377,6 +3932,33 @@
     = -\Partial*{\St}{\Nt_i}{T,P,\allNsbut{i}}
     = -\Spm_i
 \end{gather*}
+Temporary changes of derivative delimiters:
+\begin{gather*}
+  \begin{thermobrackets}
+    \Partial*{\Vt}{T}{P,\allNs}
+  \end{thermobrackets}
+  \begin{thermobar}
+    = \PartialMixSecond*{\Gt}{T}{P}{\allNs}
+  \end{thermobar}
+  \begin{thermomolesrange}
+    = \PartialMixSecond*{\Gt}{P}{T}{\allNs}
+  \end{thermomolesrange}
+  \begin{thermobraces}
+      = -\Partial*{\St}{P}{T,\allNs}
+    \begin{thermoNOsubscripts}
+      \begin{thermomolesrange}
+        = -\Partial{\St}{P}{T,\allNs}
+      \end{thermomolesrange}
+    \end{thermoNOsubscripts}
+  \end{thermobraces}
+\end{gather*}
+Inline derivatives:
+\begin{gather*}
+  \mu_i = \Partialinline{\Gt}{\Nt_i}{T,P,\allNsbut{i}}
+        = \Partialinline{\Ft}{\Nt_i}{T,\Vt,\allNsbut{i}}
+        = \Partialinline{\Ht}{\Nt_i}{\St,P,\allNsbut{i}}
+        = \Partialinline{\Ut}{\Nt_i}{\St,\Vt,\allNsbut{i}}
+\end{gather*}
 The heat capacities:
 \begin{gather*}
   \cV = T \Partial*{\Sm}{T}{\Vm,\allXs} = \Partial*{\Um}{T}{\Vm,\allXs}
@@ -3449,7 +4031,7 @@
   \\
   a_i = \frac{\fmix_i}{\fstd_i}
       = x_i \gamma_i
-                \exp\left(\frac{1}{RT} \int_{\Pstd}^P \Vm_i(T,p) dp\right)
+                \exp\left(\frac{1}{RT} \int_{\Pstd}^P \Vm_i(T,p)\,dp\right)
       \approx x_i \gamma_i
   \\
   \begin{split}
@@ -3458,9 +4040,9 @@
            = x_i \gammarat_i \Henryrat_i
            = C_i \gammamol_i \Henrymol_i
            = x_i \gamma_i \fsat_i
-                 \exp\left(\frac{1}{RT} \int_{\Psat_i}^P \Vm_i(T,p) dp\right)
+                 \exp\left(\frac{1}{RT} \int_{\Psat_i}^P \Vm_i(T,p)\,dp\right)
        \\ &= x_i \gamma_i \Psat_i \phisat_i
-                \exp\left(\frac{1}{RT} \int_{\Psat_i}^P \Vm_i(T,p) dp\right)
+                \exp\left(\frac{1}{RT} \int_{\Psat_i}^P \Vm_i(T,p)\,dp\right)
           \approx x_i \gamma_i \Psat_i
   \end{split}
 \end{gather*}
@@ -3518,6 +4100,19 @@
   \SE &= \Sm - \Sm^\IS &
   \VRpm_k &= \Vpm_k - \Vpm_k^\IGM
 \end{align*}
+Jacobians:
+\begin{gather*}
+  \Jacobian{\St,\Vt}{T,P} = \Jacobiandet{\St,\Vt}{T,P} \\
+  \Jacobian{f,g,h}{x,y,z} = \Jacobiandet[\displaystyle]{f,g,h}{x,y,z} \\
+  \Jacobian{h_1,\dots,h_k}{z_1,\dots,z_k} =
+      \Jacobiandet{h_1,\dots,h_k}{z_1,\dots,z_k} \\
+  \cP = T\Partial{\Sm}{T}{P}
+      = T\Jacobian{\Sm,P}{T,P}
+      = -T\Jacobian{\Sm,P}{T,\Vm} \Jacobian{T,\Vm}{T,P}
+      = -T\Jacobian{P,\Sm}{\Vm,\Sm} \Jacobian{\Vm,\Sm}{T,\Vm}
+          \Jacobian{T,\Vm}{T,P}
+      = \gamma \cV
+\end{gather*}
 \end{document}
 %</example>
 % \fi

Modified: trunk/Master/texmf-dist/source/latex/thermodynamics/thermodynamics.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/thermodynamics/thermodynamics.ins	2023-11-17 22:02:41 UTC (rev 68880)
+++ trunk/Master/texmf-dist/source/latex/thermodynamics/thermodynamics.ins	2023-11-17 22:02:57 UTC (rev 68881)
@@ -1,4 +1,4 @@
-%% File: thermodynamics.ins Copyright (C) 2021 Karl D. Hammond
+%% File: thermodynamics.ins Copyright (C) 2022-2023 Karl D. Hammond
 %%
 %% Karl D. Hammond,
 %% Department of Chemical Engineering
@@ -14,14 +14,15 @@
 %% version 2005/12/01 or later.
 %%
 %% This work has the LPPL maintenance status `maintained'.
-%% 
+%%
 %% The Current Maintainer of this work is K. D. Hammond.
 %%
 %% This work consists of the files thermodynamics.dtx and thermodynamics.ins
-%% and the derived files thermodynamics.sty and thermodynamics.pdf.
+%% and the derived files thermodynamics.sty, thermodynamics.pdf,
+%% thermodynamics-examples.tex, and thermodynamics-examples.pdf.
 %% \fi
 
-\input{docstrip}
+\input{l3docstrip}
 \keepsilent
 \usedir{tex/latex/thermodynamics}
 
@@ -29,13 +30,13 @@
 
 This is a generated file.
 
-Copyright (C) 2017-2018 by Karl D. Hammond
+Copyright (C) 2022-2023 by Karl D. Hammond
 
 Karl D. Hammond,
 Department of Chemical Engineering
 University of Missouri
 Contact: hammondkd at missouri.edu
-                                                                   
+
 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.

Modified: trunk/Master/texmf-dist/tex/latex/thermodynamics/thermodynamics.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/thermodynamics/thermodynamics.sty	2023-11-17 22:02:41 UTC (rev 68880)
+++ trunk/Master/texmf-dist/tex/latex/thermodynamics/thermodynamics.sty	2023-11-17 22:02:57 UTC (rev 68881)
@@ -8,7 +8,7 @@
 %% 
 %% This is a generated file.
 %% 
-%% Copyright (C) 2017-2018 by Karl D. Hammond
+%% Copyright (C) 2022-2023 by Karl D. Hammond
 %% 
 %% Karl D. Hammond,
 %% Department of Chemical Engineering
@@ -23,983 +23,1523 @@
 %% and version 1.3 or later is part of all distributions of LaTeX
 %% version 2005/12/01 or later.
 \NeedsTeXFormat{LaTeX2e}
+\RequirePackage{expl3}
 \ProvidesPackage{thermodynamics}
-    [2022/04/29 v1.00 thermodynamics package]
+    [2023/11/16 v2.00 thermodynamics notation]
+%%^^A            = C_i \gammamol_i \Henrymol_i
+\ExplSyntaxOn
+\cs_generate_variant:Nn \tl_if_eq:nnTF { xxTF }
 \RequirePackage{amstext}
 \AtBeginDocument{
     \@ifpackageloaded{pxfonts}{%
-        \providecommand*{\dbar}{{\mkern5mu\mathchar'26\mkern-10mu d}}%
+        \ProvideDocumentCommand{\dbar}{}
+            {\mkern5mu\mathchar'26\mkern-10mu d}
     }{}
     \@ifpackageloaded{newpxmath}{%
-        \providecommand*{\dbar}{{\mkern5mu\mathchar'26\mkern-10mu d}}%
+        \ProvideDocumentCommand{\dbar}{}
+            {\mkern5mu\mathchar'26\mkern-10mu d}
     }{}
     \@ifpackageloaded{txfonts}{%
-        \providecommand*{\dbar}{{\mkern5mu\mathchar'26\mkern-11mu d}}%
+        \ProvideDocumentCommand{\dbar}{}
+            {\mkern5mu\mathchar'26\mkern-11mu d}
     }{}
     \@ifpackageloaded{mathptmx}{%
-        \providecommand*{\dbar}{{\mkern5mu\mathchar'26\mkern-10mu d}}%
+        \ProvideDocumentCommand{\dbar}{}
+            {\mkern5mu\mathchar'26\mkern-10mu d}
     }{}
     \@ifpackageloaded{newtxmath}{%
-        \providecommand*{\dbar}{{\mkern5mu\mathchar'26\mkern-12mu d}}%
+        \ProvideDocumentCommand{\dbar}{}
+            {\mkern5mu\mathchar'26\mkern-11mu d}
     }{}
     \@ifpackageloaded{mathdesign}{%
-        \def\@charter{mdbch}%
-        \def\@utopia{mdput}%
-        \def\@garamond{mdugm}%
-        \ifx\MD at default@family\@utopia
-            \providecommand*{\dbar}{{\mkern8mu\mathchar'26\mkern-20mu d}}%
-        \fi
-        \ifx\MD at default@family\@charter
-            \providecommand*{\dbar}{{\mkern5mu\mathchar'26\mkern-15mu d}}%
-        \fi
-        \ifx\MD at default@family\@garamond
-            \providecommand*{\dbar}{{\mkern5mu\mathchar'26\mkern-17mu d}}%
-        \fi
+        \tl_const:Nn \c__thermodynamics_charter_tl {mdbch}
+        \tl_const:Nn \c__thermodynamics_utopia_tl {mdput}
+        \tl_const:Nn \c__thermodynamics_garamond_tl {mdugm}
+        \tl_if_eq:NNT \MD at default@family \c__thermodynamics_utopia_tl
+        { \ProvideDocumentCommand{\dbar}{}
+            {\mkern5mu\mathchar'26\mkern-20mu d}
+        }
+        \tl_if_eq:NNT \MD at default@family \c__thermodynamics_charter_tl
+        { \ProvideDocumentCommand{\dbar}{}
+            {\mkern5mu\mathchar'26\mkern-15mu d}
+        }
+        \tl_if_eq:NNT \MD at default@family \c__thermodynamics_garamond_tl
+        { \ProvideDocumentCommand{\dbar}{}
+            {\mkern5mu\mathchar'26\mkern-17mu d}
+        }
     }{}
     % Defaults to Computer Modern
-    \providecommand*{\dbar}{{\mkern3mu\mathchar'26\mkern-12mu d}}
+    \ProvideDocumentCommand{\dbar}{}
+        {\mkern3mu\mathchar'26\mkern-12mu d}
 }
-\newcommand*{\totalenergy at symbol}{E}
-\newcommand*{\internalenergy at symbol}{U}
-\newcommand*{\Helmholtz at symbol}{A}
-\newcommand*{\Gibbs at symbol}{G}
-\newcommand*{\Landau at symbol}{\Omega}
-\newcommand*{\enthalpy at symbol}{H}
-\newcommand*{\entropy at symbol}{S}
-\newcommand*{\area at symbol}{a}
-\newcommand*{\volume at symbol}{V}
-\newcommand*{\mole at symbol}{n}
-\newcommand*{\heat at symbol}{Q}
-\newcommand*{\work at symbol}{W}
-\newcommand*{\temperature at symbol}{T}
-\newcommand*{\pressure at symbol}{P}
-\newcommand*{\thermo at underline}[1]{%
-  \mkern1mu\underline{\mkern-1mu #1\mkern-4mu}\mkern4mu%
-}
-\newcommand*{\thermo at overline}[1]{%
-  \mkern2mu\overline{\mkern-2mu #1\mkern-1mu}\mkern1mu%
-}
-\newcommand*{\PartialOpen}{(}
-\newcommand*{\PartialClose}{)}
-\newcommand*{\PartialEmptyClose}{)}
+\tl_new:N \g__thermodynamics_total_energy_symbol
+\tl_new:N \g__thermodynamics_internal_energy_symbol
+\tl_new:N \g__thermodynamics_Helmholtz_symbol
+\tl_new:N \g__thermodynamics_Gibbs_symbol
+\tl_new:N \g__thermodynamics_Landau_symbol
+\tl_new:N \g__thermodynamics_enthalpy_symbol
+\tl_new:N \g__thermodynamics_entropy_symbol
+\tl_new:N \g__thermodynamics_area_symbol
+\tl_new:N \g__thermodynamics_volume_symbol
+\tl_new:N \g__thermodynamics_mole_symbol
+\tl_new:N \g__thermodynamics_heat_symbol
+\tl_new:N \g__thermodynamics_work_symbol
+\tl_new:N \g__thermodynamics_temperature_symbol
+\tl_new:N \g__thermodynamics_pressure_symbol
+
+\tl_gset:Nn \g__thermodynamics_total_energy_symbol E
+\tl_gset:Nn \g__thermodynamics_internal_energy_symbol U
+\tl_gset:Nn \g__thermodynamics_Helmholtz_symbol A
+\tl_gset:Nn \g__thermodynamics_Gibbs_symbol G
+\tl_gset:Nn \g__thermodynamics_Landau_symbol \Omega
+\tl_gset:Nn \g__thermodynamics_enthalpy_symbol H
+\tl_gset:Nn \g__thermodynamics_entropy_symbol S
+\tl_gset:Nn \g__thermodynamics_area_symbol a
+\tl_gset:Nn \g__thermodynamics_volume_symbol V
+\tl_gset:Nn \g__thermodynamics_mole_symbol n
+\tl_gset:Nn \g__thermodynamics_heat_symbol Q
+\tl_gset:Nn \g__thermodynamics_work_symbol W
+\tl_gset:Nn \g__thermodynamics_temperature_symbol T
+\tl_gset:Nn \g__thermodynamics_pressure_symbol P
+\cs_new:Nn \__thermodynamics_underline:n
+{ \mkern1mu\underline{\mkern-1mu #1\mkern-4mu}\mkern4mu }
+\cs_new:Nn \__thermodynamics_overline:n
+{ \mkern2mu\overline{\mkern-2mu #1\mkern-1mu}\mkern1mu }
+\tl_new:N \l__thermodynamics_PartialOpen_tl
+\tl_new:N \l__thermodynamics_PartialEmptyClose_tl
+\tl_new:N \l__thermodynamics_PartialClose_tl
+
+\tl_set:Nn \l__thermodynamics_PartialOpen_tl {(}
+\tl_set:Nn \l__thermodynamics_PartialClose_tl {)}
+\tl_set:Nn \l__thermodynamics_PartialEmptyClose_tl {)}
 \DeclareOption{EUAGHan}{}% the default
-\DeclareOption{EUAGHaN}{\renewcommand*{\mole at symbol}{N}}%
+\DeclareOption{EUAGHaN}{\tl_gset:Nn \g__thermodynamics_mole_symbol N}%
 \DeclareOption{EUHAGan}{\ExecuteOptions{EUAGHan}}
 \DeclareOption{EUHAGaN}{\ExecuteOptions{EUAGHaN}}
-\DeclareOption{EUFGHAn}{% this is my favorite set of symbols
-  \renewcommand*{\Helmholtz at symbol}{F}%
-  \renewcommand*{\area at symbol}{A}%
+\DeclareOption{EUFGHAn}{%
+  \tl_gset:Nn \g__thermodynamics_Helmholtz_symbol F
+  \tl_gset:Nn \g__thermodynamics_area_symbol A
 }
-\DeclareOption{EUFGHAN}{% this is my second favorite set of symbols
-  \renewcommand*{\Helmholtz at symbol}{F}%
-  \renewcommand*{\area at symbol}{A}%
-  \renewcommand*{\mole at symbol}{N}%
+\DeclareOption{EUFGHAN}{%
+  \tl_gset:Nn \g__thermodynamics_Helmholtz_symbol F
+  \tl_gset:Nn \g__thermodynamics_area_symbol A
+  \tl_gset:Nn \g__thermodynamics_mole_symbol N
 }
-\DeclareOption{EEFGHAn}{% this treats all energy the same way(?)
-  \renewcommand*{\internalenergy at symbol}{E}%
-  \renewcommand*{\Helmholtz at symbol}{F}%
-  \renewcommand*{\area at symbol}{A}%
+\DeclareOption{EEFGHAn}{%
+  \tl_gset:Nn \g__thermodynamics_total_energy_symbol {\mathcal{E}}
+  \tl_gset:Nn \g__thermodynamics_internal_energy_symbol E
+  \tl_gset:Nn \g__thermodynamics_Helmholtz_symbol F
+  \tl_gset:Nn \g__thermodynamics_area_symbol A
 }
-\DeclareOption{EEFGHAN}{% this treats all energy the same way(?)
-  \renewcommand*{\internalenergy at symbol}{E}%
-  \renewcommand*{\Helmholtz at symbol}{F}%
-  \renewcommand*{\area at symbol}{A}%
-  \renewcommand*{\mole at symbol}{N}%
+\DeclareOption{EEFGHAN}{%
+  \tl_gset:Nn \g__thermodynamics_total_energy_symbol {\mathcal{E}}
+  \tl_gset:Nn \g__thermodynamics_internal_energy_symbol E
+  \tl_gset:Nn \g__thermodynamics_Helmholtz_symbol F
+  \tl_gset:Nn \g__thermodynamics_area_symbol A
+  \tl_gset:Nn \g__thermodynamics_mole_symbol N
 }
 \DeclareOption{EEFGHan}{%
-  \renewcommand*{\internalenergy at symbol}{E}%
-  \renewcommand*{\Helmholtz at symbol}{F}
+  \tl_gset:Nn \g__thermodynamics_total_energy_symbol {\mathcal{E}}
+  \tl_gset:Nn \g__thermodynamics_internal_energy_symbol E
+  \tl_gset:Nn \g__thermodynamics_Helmholtz_symbol F
 }
 \DeclareOption{EEFGHaN}{%
-  \renewcommand*{\internalenergy at symbol}{E}%
-  \renewcommand*{\Helmholtz at symbol}{F}
-  \renewcommand*{\mole at symbol}{N}%
+  \tl_gset:Nn \g__thermodynamics_total_energy_symbol {\mathcal{E}}
+  \tl_gset:Nn \g__thermodynamics_internal_energy_symbol E
+  \tl_gset:Nn \g__thermodynamics_Helmholtz_symbol F
+  \tl_gset:Nn \g__thermodynamics_mole_symbol N
 }
 \DeclareOption{EEAGHan}{%
-  \renewcommand*{\internalenergy at symbol}{E}%
+  \tl_gset:Nn \g__thermodynamics_total_energy_symbol {\mathcal{E}}
+  \tl_gset:Nn \g__thermodynamics_internal_energy_symbol E
 }
 \DeclareOption{EEAGHaN}{%
-  \renewcommand*{\internalenergy at symbol}{E}%
-  \renewcommand*{\mole at symbol}{N}%
+  \tl_gset:Nn \g__thermodynamics_total_energy_symbol {\mathcal{E}}
+  \tl_gset:Nn \g__thermodynamics_internal_energy_symbol E
+  \tl_gset:Nn \g__thermodynamics_mole_symbol N
 }
-\DeclareOption{EUAGHAn}{% Helmholtz free energy and area look the same here
-  \renewcommand*{\area at symbol}{A}%
+\DeclareOption{EUAGHAn}{%
+  \tl_gset:Nn \g__thermodynamics_area_symbol {\mathcal{A}}
 }
-\DeclareOption{EUAGHAN}{% Helmholtz free energy and area look the same here
-  \renewcommand*{\area at symbol}{A}%
-  \renewcommand*{\mole at symbol}{N}%
+\DeclareOption{EUAGHAN}{%
+  \tl_gset:Nn \g__thermodynamics_area_symbol {\mathcal{A}}
+  \tl_gset:Nn \g__thermodynamics_mole_symbol N
 }
 \DeclareOption{EUFGHan}{%
-  \renewcommand*{\Helmholtz at symbol}{F}%
+  \tl_gset:Nn \g__thermodynamics_Helmholtz_symbol F
 }
 \DeclareOption{EUFGHaN}{%
-  \renewcommand*{\Helmholtz at symbol}{F}%
-  \renewcommand*{\mole at symbol}{N}%
+  \tl_gset:Nn \g__thermodynamics_Helmholtz_symbol F
+  \tl_gset:Nn \g__thermodynamics_mole_symbol N
 }
-\DeclareOption{delta}{\let\dbar\delta}
-\let\@extensive\relax
-\let\@intensive\relax
-\let\@specific\hat
-\DeclareOption{extensive-plain}{%
-    \let\@extensive\relax
-    \let\@intensive\thermo at underline
+\DeclareOption{delta}{ \cs_set_eq:NN \dbar \delta }
+\cs_new:Nn \__thermodynamics_extensive:n {#1}
+\cs_new:Nn \__thermodynamics_intensive:n {#1}
+\cs_new:Nn \__thermodynamics_specific:n {\hat{#1}}
+
+\cs_new:Npn \__thermodynamics_set_intensive_plain
+{
+  \cs_set:Nn \__thermodynamics_extensive:n {\__thermodynamics_underline:n{##1}}
+  \cs_set:Nn \__thermodynamics_intensive:n {##1}
 }
-\DeclareOption{intensive-plain}{% the default
-    \let\@extensive\thermo at underline
-    \let\@intensive\relax
+\cs_new:Npn \__thermodynamics_set_extensive_plain
+{
+  \cs_set:Nn \__thermodynamics_extensive:n {##1}
+  \cs_set:Nn \__thermodynamics_intensive:n {\__thermodynamics_underline:n{##1}}
 }
+\cs_new:Npn \__thermodynamics_set_lowercase_pms
+{
+  \RenewDocumentCommand{\partialmolar}{m}
+  {
+    \tl_set:Nn \l__thermodynamics_pm_symbol_tl {\text_lowercase:n {##1}}
+    \__thermodynamics_generic_pm:
+  }
+}
+\cs_new:Npn \__thermodynamics_set_intensive_lowercase
+{
+  \cs_set:Nn \__thermodynamics_extensive:n {\text_uppercase:n {##1}}
+  \cs_set:Nn \__thermodynamics_intensive:n {\text_lowercase:n {##1}}
+  \cs_set:Nn \__thermodynamics_specific:n {\hat{\text_lowercase:n {##1}}}
+}
+\cs_new:Npn \__thermodynamics_set_extensive_superscripts
+{
+  \cs_set:Nn \__thermodynamics_extensive:n {{##1}\c_math_superscript_token t}
+  \cs_set:Nn \__thermodynamics_intensive:n {##1}
+}
+\DeclareOption{extensive-plain}{\__thermodynamics_set_extensive_plain}
+\DeclareOption{intensive-plain}{\__thermodynamics_set_intensive_plain} % the default
 \DeclareOption{intensive-lowercase}{% PLEASE don't use this!
-    \let\@extensive\MakeUppercase
-    \let\@intensive\MakeLowercase
-    \def\@specific#1{\MakeLowercase{\hat #1}}
-    \AtEndOfPackage{
-        \renewcommand*{\partialmolar}[1]{%
-            \gdef\pm at symbol{\MakeLowercase #1}\generic at pm}
-        \renewcommand*{\heatcapacitysymbol}{c}
-    }
+  \__thermodynamics_set_intensive_lowercase
+  \AtEndOfPackage{
+    \__thermodynamics_set_lowercase_pms
+    \RenewDocumentCommand{\heatcapacitysymbol}{}{c}
+  }
 }
 \DeclareOption{extensive-superscript}{%
-    \gdef\@extensive#1{{#1}^t}%
-    \let\@intensive\relax%
-    \AtEndOfPackage{%
-      \renewcommand*{\URt}{\internalenergy at symbol^{\residual,t}}
-      \renewcommand*{\HRt}{\enthalpy at symbol^{\residual,t}}
-      \renewcommand*{\FRt}{\Helmholtz at symbol^{\residual,t}}
-      \renewcommand*{\GRt}{\Gibbs at symbol^{\residual,t}}
-      \renewcommand*{\VRt}{\volume at symbol^{\residual,t}}
-      \renewcommand*{\SRt}{\entropy at symbol^{\residual,t}}
-      \renewcommand*{\UEt}{\internalenergy at symbol^{\excess,t}}
-      \renewcommand*{\HEt}{\enthalpy at symbol^{\excess,t}}
-      \renewcommand*{\FEt}{\Helmholtz at symbol^{\excess,t}}
-      \renewcommand*{\GEt}{\Gibbs at symbol^{\excess,t}}
-      \renewcommand*{\VEt}{\volume at symbol^{\excess,t}}
-      \renewcommand*{\SEt}{\entropy at symbol^{\excess,t}}
-    }
+  \__thermodynamics_set_extensive_superscripts
+  \AtEndOfPackage{%
+    \RenewDocumentCommand{\URt}{}{\g__thermodynamics_internal_energy_symbol
+      \c_math_superscript_token{\residual,t}}
+    \RenewDocumentCommand{\HRt}{}{\g__thermodynamics_enthalpy_symbol
+      \c_math_superscript_token{\residual,t}}
+    \RenewDocumentCommand{\FRt}{}{\g__thermodynamics_Helmoholtz_symbol
+      \c_math_superscript_token{\residual,t}}
+    \RenewDocumentCommand{\GRt}{}{\g__thermodynamics_Gibbs_symbol
+      \c_math_superscript_token{\residual,t}}
+    \RenewDocumentCommand{\VRt}{}{\g__thermodynamics_volume_symbol
+      \c_math_superscript_token{\residual,t}}
+    \RenewDocumentCommand{\SRt}{}{\g__thermodynamics_entropy_symbol
+      \c_math_superscript_token{\residual,t}}
+    \RenewDocumentCommand{\UEt}{}{\g__thermodynamics_internal_energy_symbol
+      \c_math_superscript_token{\excess,t}}
+    \RenewDocumentCommand{\HEt}{}{\g__thermodynamics_enthalpy_symbol
+      \c_math_superscript_token{\excess,t}}
+    \RenewDocumentCommand{\FEt}{}{\g__thermodynamics_Helmoholtz_symbol
+      \c_math_superscript_token{\excess,t}}
+    \RenewDocumentCommand{\GEt}{}{\g__thermodynamics_Gibbs_symbol
+      \c_math_superscript_token{\excess,t}}
+    \RenewDocumentCommand{\VEt}{}{\g__thermodynamics_volume_symbol
+      \c_math_superscript_token{\excess,t}}
+    \RenewDocumentCommand{\SEt}{}{\g__thermodynamics_entropy_symbol
+      \c_math_superscript_token{\excess,t}}
+  }
 }
-\newif\if at subscripted
-\@subscriptedtrue
-\DeclareOption{subscripts}{\@subscriptedtrue}
-\DeclareOption{nosubscripts}{\@subscriptedfalse}
+%%^^A \[ \left(\frac{\partial U}{\partial S}\right)_V \quad\text{versus}\quad
+%%^^A    \left(\frac{\partial U(S,V)}{\partial S}\right) \]
+\bool_new:N \l__thermodynamics_subscripted_bool
+\bool_set_true:N \l__thermodynamics_subscripted_bool
+\DeclareOption{subscripts}{\bool_set_true:N \l__thermodynamics_subscripted_bool}
+\DeclareOption{nosubscripts}{\bool_set_false:N \l__thermodynamics_subscripted_bool}
 \DeclareOption{parentheses}{}
 \DeclareOption{brackets}{%
-  \renewcommand*{\PartialOpen}{[}%
-  \renewcommand*{\PartialClose}{]}%
-  \renewcommand*{\PartialEmptyClose}{]}%
+  \tl_set:Nn \l__thermodynamics_PartialOpen_tl {[}
+  \tl_set:Nn \l__thermodynamics_PartialClose_tl {]}
+  \tl_set:Nn \l__thermodynamics_PartialEmptyClose_tl {]}
 }
 \DeclareOption{braces}{%
-  \renewcommand*{\PartialOpen}{\{}%
-  \renewcommand*{\PartialClose}{\}}%
-  \renewcommand*{\PartialEmptyClose}{\}}%
+  \tl_set:Nn \l__thermodynamics_PartialOpen_t1 {\{}
+  \tl_set:Nn \l__thermodynamics_PartialClose_t1 {\}}
+  \tl_set:Nn \l__thermodynamics_PartialEmptyClose_tl {\}}
 }
 \DeclareOption{bar}{%
-  \renewcommand*{\PartialOpen}{.}%
-  \renewcommand*{\PartialClose}{\rvert}%
-  \renewcommand*{\PartialEmptyClose}{.}%
+  \tl_set:Nn \l__thermodynamics_PartialOpen_tl {.}
+  \tl_set:Nn \l__thermodynamics_PartialClose_tl {\rvert}
+  \tl_set:Nn \l__thermodynamics_PartialEmptyClose_tl {.}
 }
 \DeclareOption{plain-derivatives}{% This implies dU(S,V,N)/dS notation
-  \renewcommand*{\PartialOpen}{.}%
-  \renewcommand*{\PartialClose}{.}%
-  \renewcommand*{\PartialEmptyClose}{.}%
-  \ExecuteOptions{nosubscripts}%
+  \tl_set:Nn \l__thermodynamics_PartialOpen_tl {.}
+  \tl_set:Nn \l__thermodynamics_PartialClose_tl {.}
+  \tl_set:Nn \l__thermodynamics_PartialEmptyClose_tl {.}
+  \ExecuteOptions{nosubscripts}
 }
-\newcommand*{\ncomponents}{C}
-\newcommand*{\allNs}{\allcomponents{\Nt}}
-\newcommand*{\allXs}{\allcomponents{x}}
-\newcommand*{\allYs}{\allcomponents{y}}
-\newcommand*{\allmus}{\allcomponents{\mu}}
-\newcommand*{\allMs}{\allcomponents{m}}
-\newcommand*{\allWs}{\allcomponents{w}}%
-\newcommand*{\allNsbut}[2][j]{\allbut[#1]{#2}{\Nt}}
-\newcommand*{\allXsbut}[2][j]{\allbutlastand[#1]{#2}{x}}
-\newcommand*{\allYsbut}[2][j]{\allbutlastand[#1]{#2}{y}}
-\newcommand*{\allmusbut}[2][j]{\allbut[#1]{#2}{\mu}}
-\newcommand*{\allMsbut}[2][j]{\allbut[#1]{#2}{m}}
-\newcommand*{\allWsbut}[2][j]{\allbutlastand[#1]{#2}{w}}%
-\newcommand*{\allcomponents}[1]{\vec{#1}}
-\newcommand*{\allbut}[3][j]{%
-  \def\tmp at arg{#2}%
-  \def\tmp@@arg{#1}%
-  \ifx\tmp at arg\tmp@@arg
-    {#3}_{k\neq #2}%
-  \else
-    {#3}_{#1\neq #2}%
-  \fi
+\NewExpandableDocumentCommand \ncomponents {} {C}
+\NewDocumentCommand{\allNs}{O{i}}{\allcomponents[#1]{\Nt}}
+\NewDocumentCommand{\allXs}{O{i}}{\allcomponents[#1]{x}}
+\NewDocumentCommand{\allYs}{O{i}}{\allcomponents[#1]{y}}
+\NewDocumentCommand{\allmus}{O{i}}{\allcomponents[#1]{\mu}}
+\NewDocumentCommand{\allMs}{O{i}}{\allcomponents[#1]{m}}
+\NewDocumentCommand{\allWs}{O{i}}{\allcomponents[#1]{w}}
+\NewDocumentCommand{\allNsbut}{O{j} m} {\allbut[#1]{#2}{\Nt}}
+\NewDocumentCommand{\allXsbut}{O{j} m} {\allbutlastand[#1]{#2}{x}}
+\NewDocumentCommand{\allYsbut}{O{j} m} {\allbutlastand[#1]{#2}{y}}
+\NewDocumentCommand{\allmusbut}{O{j} m} {\allbut[#1]{#2}{\mu}}
+\NewDocumentCommand{\allMsbut}{O{j} m} {\allbut[#1]{#2}{m}}
+\NewDocumentCommand{\allWsbut}{O{j} m} {\allbutlastand[#1]{#2}{w}}
+\NewDocumentCommand{\allcomponents}{O{} m}{\vec{#2}}
+\NewDocumentCommand{\allbut}{O{j} m m}
+{ \tl_if_eq:nnTF {#1} {#2}
+  { {#3}\c_math_subscript_token{k \neq #2} }
+  { {#3}\c_math_subscript_token{#1 \neq #2} }
 }
-\newcommand*{\allbutlastand}[3][j]{%
-  \edef\tmp at arg{#1}%
-  \edef\tmp@@arg{#2}%
-  \ifx\tmp@@arg\ncomponents
-    {#3}_{#1 \neq #2}%
-  \else
-    \ifx\tmp at arg\tmp@@arg
-      {#3}_{k \neq #2,\ncomponents}%
-    \else
-      {#3}_{#1 \neq #2,\ncomponents}%
-    \fi
-  \fi
+\NewDocumentCommand{\allbutlastand}{O{j} m m}
+{ \tl_if_eq:xxTF {#2} {\ncomponents}
+  { {#3}\c_math_subscript_token{#1 \neq #2} }
+  { \tl_if_eq:nnTF {#1} {#2}
+    { {#3}\c_math_subscript_token{k \neq #2,\ncomponents} }
+    { {#3}\c_math_subscript_token{#1 \neq #2,\ncomponents} }
+  }
 }
 \DeclareOption{moles-index}{}
-\DeclareOption{moles-range}{%
-  \renewcommand*{\allcomponents}[1]{{#1}_1,\dots,{#1}_{\ncomponents}}
-  \renewcommand*{\allbut}[3][j]{%
-    \def\@one{1}%
-    \edef\tmp at arg{#2}%
-    \ifx\tmp at arg\@one
-      {#3}_2,\dots,{#3}_{\ncomponents}%
-    \else
-      \ifx\tmp at arg\ncomponents
-        {#3}_1,\dots,{#3}_{\ncomponents-1}%
-      \else
-        {#3}_1,\dots,[{#3}_{#2}],\dots,{#3}_{\ncomponents}%
-      \fi
-    \fi
+\DeclareOption{moles-range}{ \__thermodynamics_set_moles_range }
+\cs_new:Npn \__thermodynamics_set_moles_range {%
+  \RenewDocumentCommand{\allcomponents}{O{} m}
+  { {##2}\c_math_subscript_token 1,\dots,
+        {##2}\c_math_subscript_token{\ncomponents} }
+  \RenewDocumentCommand{\allbut}{O{j} m m}
+  { \tl_if_eq:nnTF {##2} {1}
+    { {##3}\c_math_subscript_token 2,\dots,
+        {##3}\c_math_subscript_token{\ncomponents} }
+    { \tl_if_eq:xxTF {##2} {\ncomponents}
+      { {##3}\c_math_subscript_token 1,\dots,
+          {##3}\c_math_subscript_token{\ncomponents-1} }
+      { {##3}\c_math_subscript_token 1,\dots,
+            [{##3}\c_math_subscript_token{##2}],
+            \dots,{##3}\c_math_subscript_token{\ncomponents} }
+    }
   }
-  \renewcommand*{\allbutlastand}[3][j]{%
-    \def\@one{1}%
-    \edef\tmp at arg{#2}%
-    \edef\@ncminusone{\ncomponents-1}%
-    \ifx\tmp at arg\@one
-      {#3}_2,\dots,{#3}_{\ncomponents-1}%
-    \else
-      \ifx\tmp at arg\@ncminusone
-        {#3}_1,\dots,{#3}_{\ncomponents-2}%
-      \else
-        \ifx\tmp at arg\ncomponents
-          {#3}_1,\dots,{#3}_{\ncomponents-1}%
-      \else
-          {#3}_1,\dots,[{#3}_{#2}],\dots,{#3}_{\ncomponents}%
-        \fi
-      \fi
-    \fi
+  \RenewDocumentCommand{\allbutlastand}{O{j} m m}
+  { \tl_if_eq:nnTF {##2} {1}
+    { {##3}\c_math_subscript_token 2,\dots,
+        {##3}\c_math_subscript_token{\ncomponents-1} }
+    { \tl_if_eq:xxTF {##2} {\ncomponents}
+      { {##3}\c_math_subscript_token 1,\dots,
+        {##3}\c_math_subscript_token{\ncomponents-1}
+      }
+      { \tl_if_eq:xxTF {##2} {\ncomponents-1}
+        { {##3}\c_math_subscript_token 1,\dots,
+          {##3}\c_math_subscript_token{\ncomponents-2} }
+        {
+          {##3}\c_math_subscript_token 1,\dots,
+          [{##3}\c_math_subscript_token{##2}],\dots,
+           {##3}\c_math_subscript_token{\ncomponents-1}
+        }
+      }
+    }
   }
 }
 \DeclareOption{Bejan}{
   \ExecuteOptions{EUFGHAN,intensive-lowercase,delta}
-  \let\@specific\MakeLowercase
-  \def\@intensive#1{\MakeLowercase{\bar #1}}
-  \AtEndOfPackage{
-    \DeclareSubscrSymbol{cV}{\bar\heatcapacitysymbol}{v}
-    \DeclareSubscrSymbol{cVs}{\heatcapacitysymbol}{v}
-    \DeclareSubscrSymbol{cVt}{\Nt\heatcapacitysymbol}{v}
-    \renewcommand*{\expansivitysymbol}{\beta}
-    \renewcommand*{\ncomponents}{n}
-  }
+  \cs_set:Nn \__thermodynamics_specific:n {\text_lowercase:n {#1}}
+  \cs_set:Nn \__thermodynamics_intensive:n {\bar{\text_lowercase:n {#1}}}
+  \tl_gset:Nn \g__thermodynamics_volume_symbol v
 }
 \DeclareOption{CBK}{
   \ExecuteOptions{EUAGHAN,intensive-lowercase}
   \AtEndOfPackage{
-    \let\thermo at overline\widetilde
-    \let\@specific\MakeLowercase
-    \renewcommand*{\@intensive}[1]{\MakeLowercase{\bar{#1}}}
-    \renewcommand*{\pressure at symbol}{p}
-    \renewcommand*{\Deltarxn}[1]{#1_R}
-    \renewcommand*{\compressibilitysymbol}{\beta}
-    \renewcommand*{\expansivitysymbol}{\alpha}
+    \cs_set:Nn \__thermodynamics_overline:n {\widetilde{#1}}
+    \cs_set:Nn \__thermodynamics_specific:n {\text_lowercase:n {#1}}
+    \cs_set:Nn \__thermodynamics_intensive:n {\bar{\text_lowercase:n{#1}}}
+    \tl_gset:Nn \g__thermodynamics_pressure_symbol p
+    \RenewDocumentCommand{\Deltarxn}{m}{{#1}\c_math_subscript_token R}
+    \RenewDocumentCommand{\compressibilitysymbol}{}{\beta}
+    \RenewDocumentCommand{\expansivitysymbol}{}{\alpha}
   }
 }
 \DeclareOption{ElliottLira}{
   \AtEndOfPackage{
-    \renewcommand*{\allcomponents}[1]{#1}
-    \renewcommand*{\Deltarxn}[1]{\Delta #1}
+    \RenewDocumentCommand{\allcomponents}{O{} m}{#2}
+    \RenewDocumentCommand{\Deltarxn}{m}{\Delta #1}
+    \RenewDocumentCommand{\IG}{}{{\text{ig}}}
+    \RenewDocumentCommand{\IGM}{}{{\text{ig}}}
+    \RenewDocumentCommand{\IS}{}{{\text{is}}}
   }
 }
 \DeclareOption{Koretsky}{
   \ExecuteOptions{EUAGHAn,brackets,intensive-lowercase,delta}
   \AtEndOfPackage{
-    \renewcommand*{\partialmolar}[1]{\gdef\pm at symbol{#1}\generic at pm}
-    \renewcommand*{\expansivitysymbol}{\beta}
-    \renewcommand*{\IS}{{\text{ideal}}}
-    \renewcommand*{\residual}{{\text{dep}}}
-    \renewcommand*{\IG}{{\text{ideal}}}
-    \renewcommand*{\IGM}{{\text{ideal}}}
-    \renewcommand*{\Deltafus}[1]{\Delta{#1}_\fusion}
-    \renewcommand*{\Deltasub}[1]{\Delta{#1}_\sublimation}
-    \renewcommand*{\Deltavap}[1]{\Delta{#1}_\vaporization}
-    \renewcommand*{\Henryrat}{{\mathcal{H}}}
-    \renewcommand*{\gammarat}{\gamma^\text{Henry's}}
-    \let\phipure\varphi
-    \renewcommand*{\phimix}{\hat\varphi}
-    \renewcommand*{\phisat}{\varphi^\sat}
-    \let\Delta at fus@sym\relax
-    \DeclareSubscrSymbol{@Deltafus}{\Delta at fus@sym}{\fusion}
-    \renewcommand*{\Deltafus}[1]{\def\Delta at fus@sym{\Delta #1}\@Deltafus}
-    \let\Delta at vap@sym\relax
-    \DeclareSubscrSymbol{@Deltavap}{\Delta at vap@sym}{\vaporization}
-    \renewcommand*{\Deltasub}[1]{\def\Delta at sub@sym{\Delta #1}\@Deltasub}
-    \let\Delta at sub@sym\relax
-    \DeclareSubscrSymbol{@Deltasub}{\Delta at sub@sym}{\sublimation}
-    \renewcommand*{\Deltasub}[1]{\def\Delta at sub@sym{\Delta #1}\@Deltasub}
+    %^^A Undo part of intensive-lowercase
+    \RenewDocumentCommand{\partialmolar}{m}
+    { \tl_set:Nn \l__thermodynamics_pm_symbol_tl {#1}
+      \__thermodynamics_generic_pm:
+    }
+    \RenewDocumentCommand{\expansivitysymbol}{}{\beta}
+    \RenewDocumentCommand{\IS}{}{{\text{ideal}}}
+    \RenewDocumentCommand{\residual}{}{{\text{dep}}}
+    \RenewDocumentCommand{\IG}{}{{\text{ideal}}}
+    \RenewDocumentCommand{\IGM}{}{{\text{ideal}}}
+    \RenewDocumentCommand{\Henryrat}{}{{\mathcal{H}}}
+    \RenewDocumentCommand{\gammarat}{}
+        {\gamma\c_math_superscript_token\text{Henry's}}
+    \RenewDocumentCommand{\phipure}{}{\varphi}
+    \RenewDocumentCommand{\phimix}{}{\hat\varphi}
+    \RenewDocumentCommand{\phisat}{}{\varphi\c_math_superscript_token\sat}
+    \cs_new:Npn \Delta_fus_sym {} {}
+    \NewSubscriptedSymbol{\Delta_fus}{\Delta_fus_sym}{\fusion}
+    \RenewDocumentCommand{\Deltafus}{m}{
+      \cs_set:Npn \Delta_fus_sym {} { \Delta #1 }
+      \Delta_fus
+    }
+    \cs_new:Npn \Delta_vap_sym {} {}
+    \NewSubscriptedSymbol{\Delta_vap}{\Delta_vap_sym}{\vaporization}
+    \RenewDocumentCommand{\Deltavap}{m}{
+      \cs_set:Npn \Delta_vap_sym {} { \Delta #1 }
+      \Delta_vap
+    }
+    \cs_new:Npn \Delta_sub_sym {} {}
+    \NewSubscriptedSymbol{\Delta_sub}{\Delta_sub_sym}{\sublimation}
+    %^^A Undo part of intensive-lowercase
+    \RenewDocumentCommand{\Deltasub}{m}{
+      \cs_set:Npn \Delta_sub_sym {} { \Delta #1 }
+      \Delta_sub
+    }
   }
 }
 \DeclareOption{MSBB}{
   \ExecuteOptions{EUFGHAn,intensive-lowercase,delta}
   \AtEndOfPackage{
-    \renewcommand*{\IGM}{\ast}
-    \renewcommand*{\IG}{\ast}
-    \renewcommand*{\expansivitysymbol}{\beta}
-    \renewcommand*{\allcomponents}[1]{#1}
-    \renewcommand*{\allbut}[3][j]{%
-      \def\tmp at arg{#2}%
-      \def\tmp@@arg{#1}%
-      \ifx\tmp at arg\tmp@@arg
-        {#3}_{k}%
-      \else
-        {#3}_{#1}%
-      \fi
+    \RenewDocumentCommand{\IGM}{}{\ast}
+    \RenewDocumentCommand{\IG}{}{\ast}
+    \RenewDocumentCommand{\expansivitysymbol}{}{\beta}
+    \RenewDocumentCommand{\allcomponents}{O{} m}{#2}
+    \RenewDocumentCommand{\allbut}{O{j} m m}
+    {
+      \tl_if_eq:nnTF {#1} {#2}
+      { {#3}\c_math_subscript_token k }
+      { {#3}\c_math_subscript_token{#1} }
     }
-    \let\Helmholtz at symbol\psi
-    \renewcommand*{\Ft}{\Psi}
-    \def\@intensive#1{\MakeLowercase{\thermo at overline #1}}
-    \let\@specific\MakeLowercase
-    \renewcommand*{\partialmolar}[1]{\gdef\pm at symbol{#1}\generic at pm}
-    \renewcommand*{\fmix}{\bar f}
-    \renewcommand*{\phimix}{\bar\phi}
-    \renewcommand*{\pressure at symbol}{p}
+    \tl_gset_eq:NN \g__thermodynamics_Helmholtz_symbol \psi
+    \RenewDocumentCommand{\Ft}{}{\Psi}
+    \cs_set:Nn \__thermodynamics_intensive:n {\__thermodynamics_overline:n{\text_lowercase:n{#1}}}
+    \cs_set:Nn \__thermodynamics_specific:n {\text_lowercase:n{#1}}
+    \RenewDocumentCommand{\fmix}{}{\bar f}
+    \RenewDocumentCommand{\phimix}{}{\bar\phi}
+    \RenewDocumentCommand{\phimix}{}{\bar\phi}
+    \tl_gset:Nn \g__thermodynamics_pressure_symbol p
+    \RenewDocumentCommand{\partialmolar}{m}
+    {
+      \tl_set:Nn \l__thermodynamics_pm_symbol_tl {#1}
+      \__thermodynamics_generic_pm:
+    }
   }
 }
 \DeclareOption{Prausnitz}{
   \ExecuteOptions{intensive-lowercase}
   \AtEndOfPackage{
-    \renewcommand*{\fmix}{f}
-    \let\phimix\phi
-    \renewcommand*{\fsat}{\fpure^\sat}
-    \DeclareSubscrSymbol{fpure}{f}{{\text{pure}}}
-    \DeclareSubscrSymbol{phipure}{\phi}{{\text{pure}}}
-    \renewcommand*{\residual}{{{\mathcal{R}}}}
-    \renewcommand*{\allcomponents}[1]{{#1}_i}
-    \renewcommand*{\allbut}[3][j]{%
-      \def\tmp at arg{#2}%
-      \def\tmp@@arg{#1}%
-      \ifx\tmp at arg\tmp@@arg
-        {#3}_{k}%
-      \else
-        {#3}_{#1}%
-      \fi
+    \RenewDocumentCommand{\fmix}{}{f}
+    \RenewDocumentCommand{\phimix}{}{\phi}
+    \RenewDocumentCommand{\fsat}{}{\fpure\c_math_superscript_token\sat}
+    % TODO: this should pick up H_2 and make it into H_{2,1} (assuming the
+    % solvent is always 1...?)
+    \RenewDocumentCommand{\Henryrat}{}{H}
+    \RenewDocumentCommand{\residual}{}{{{\mathcal{R}}}}
+    \RenewDocumentCommand{\allcomponents}{O{i} m}
+      { {#2}\c_math_subscript_token{#1} }
+    \RenewDocumentCommand{\allbut}{O{i} m m}
+    { \tl_if_eq:nnTF {#1} {#2}
+        { {#3}\c_math_subscript_token k }
+        { {#3}\c_math_subscript_token{#1} }
     }
+    \RenewSubscriptedSymbol{\fpure}{f}{{\text{pure}}}
+    \RenewSubscriptedSymbol{\phipure}{\phi}{{\text{pure}}}
   }
 }
 \DeclareOption{Sandler}{
   \ExecuteOptions{EUAGHaN,extensive-plain}
   \AtEndOfPackage{
-    \renewcommand*{\sat}{{\text{vap}}}
-    \renewcommand*{\excess}{{\text{{ex}}}}
-    \renewcommand*{\residual}{{\text{r}}}
-    \renewcommand*{\ncomponents}{\mathcal{C}}
-    \renewcommand*{\fmix}{\bar f}
-    \renewcommand*{\fstd}{\bar f^\circ}
-    \renewcommand*{\phimix}{\bar\phi}
-    \renewcommand*{\allcomponents}[1]{\thermo at underline{#1}}
-    \renewcommand*{\IG}{{\text{IG}}}
-    \renewcommand*{\IGM}{{\text{IGM}}}
-    \renewcommand*{\IS}{{\text{IM}}}
-    \renewcommand*{\Deltamix}[1]{\Delta_\mixing #1}
-    \renewcommand*{\Deltarxn}[1]{\Delta_\reaction #1}
-    \renewcommand*{\Deltasub}[1]{\Delta_\sublimation #1}
-    \renewcommand*{\Deltafus}[1]{\Delta_\fusion #1}
-    \renewcommand*{\Deltavap}[1]{\Delta_\vaporization #1}
-    \renewcommand*{\Henryrat}{H}
-    \DeclareSubscrSymbol{cV}{\heatcapacitysymbol}{\volume at symbol}
-    \DeclareSubscrSymbol{cP}{\heatcapacitysymbol}{\pressure at symbol}
-    \DeclareSubscrSymbol{cVt}{\Nt\heatcapacitysymbol}{\volume at symbol}
-    \DeclareSubscrSymbol{cPt}{\Nt\heatcapacitysymbol}{\pressure at symbol}
+    \RenewDocumentCommand{\sat}{}{{\text{vap}}}
+    \RenewDocumentCommand{\excess}{}{{\text{ex}}}
+    \RenewDocumentCommand{\residual}{}{{\text{r}}}
+    \RenewExpandableDocumentCommand{\ncomponents}{}{\mathcal{C}}
+    \RenewDocumentCommand{\fmix}{}{\bar f}
+    \RenewDocumentCommand{\fstd}{}{\bar f\c_math_superscript_token\std}
+    \RenewDocumentCommand{\phimix}{}{\bar\phi}
+    \RenewDocumentCommand{\allcomponents}{O{} m}{\__thermodynamics_underline:n{#2}}
+    \RenewDocumentCommand{\IG}{}{{\text{IG}}}
+    \RenewDocumentCommand{\IGM}{}{{\text{IGM}}}
+    \RenewDocumentCommand{\IS}{}{{\text{IM}}}
+    \RenewDocumentCommand{\Deltamix}{m}
+        {\Delta\c_math_subscript_token\mixing #1}
+    \RenewDocumentCommand{\Deltarxn}{m}
+        {\Delta\c_math_subscript_token\reaction #1}
+    \RenewDocumentCommand{\Deltasub}{m}
+        {\Delta\c_math_subscript_token\sublimation #1}
+    \RenewDocumentCommand{\Deltafus}{m}
+        {\Delta\c_math_subscript_token\fusion #1}
+    \RenewDocumentCommand{\Deltavap}{m}
+        {\Delta\c_math_subscript_token\vaporization #1}
+    \RenewDocumentCommand{\Henryrat}{}{H}
+    \RenewSubscriptedSymbol{\cV}
+        {\heatcapacitysymbol}{\g__thermodynamics_volume_symbol}
+    \RenewSubscriptedSymbol{\cP}
+        {\heatcapacitysymbol}{\g__thermodynamics_pressure_symbol}
+    \RenewSubscriptedSymbol{\cVt}
+        {\Nt\heatcapacitysymbol}{\g__thermodynamics_volume_symbol}
+    \RenewSubscriptedSymbol{\cPt}
+        {\Nt\heatcapacitysymbol}{\g__thermodynamics_pressure_symbol}
   }
 }
 \DeclareOption{SVNAS}{
   \ExecuteOptions{extensive-superscript}
   \AtEndOfPackage{
-    \renewcommand*{\allcomponents}[1]{#1}
-    \renewcommand*{\allbut}[3][j]{%
-      \def\tmp at arg{#2}%
-      \def\tmp@@arg{#1}%
-      \ifx\tmp at arg\tmp@@arg
-        {#3}_{k}%
-      \else
-        {#3}_{#1}%
-      \fi
+    \RenewDocumentCommand{\allcomponents}{O{} m}{#2}
+    \RenewDocumentCommand{\allbut}{O{j} m m}
+    {
+      \tl_if_eq:nnTF {#1} {#2}
+      { {#3}\c_math_subscript_token k }
+      { {#3}\c_math_subscript_token{#1} }
     }
-    \renewcommand*{\IG}{{ig}}
-    \renewcommand*{\IGM}{{ig}}
-    \renewcommand*{\IS}{{id}}
-    \renewcommand*{\expansivitysymbol}{\beta}
-    \renewcommand*{\Deltarxn}[1]{\Delta #1}
-    \DeclareSubscrSymbol{cVt}{\Nt\heatcapacitysymbol}{\volume at symbol}
-    \DeclareSubscrSymbol{cPt}{\Nt\heatcapacitysymbol}{\pressure at symbol}
+    \RenewDocumentCommand{\IG}{}{{ig}}
+    \RenewDocumentCommand{\IGM}{}{{ig}}
+    \RenewDocumentCommand{\IS}{}{{id}}
+    \RenewDocumentCommand{\expansivitysymbol}{}{\beta}
+    \RenewDocumentCommand{\Deltarxn}{m}{\Delta #1}
+    \RenewSubscriptedSymbol{\cVt}
+        {\Nt\heatcapacitysymbol}{\g__thermodynamics_volume_symbol}
+    \RenewSubscriptedSymbol{\cPt}
+        {\Nt\heatcapacitysymbol}{\g__thermodynamics_pressure_symbol}
   }
 }
 \DeclareOption{TesterModell}{
   \ExecuteOptions{EUAGHaN,delta}
   \AtEndOfPackage{
-    \renewcommand*{\ncomponents}{n}
-    \renewcommand*{\allcomponents}[1]{{#1}_i}
-    \renewcommand*{\allbut}[3][j]{%
-      \def\tmp at arg{#2}%
-      \def\tmp@@arg{#1}%
-      \ifx\tmp at arg\tmp@@arg
-        {#3}_k\relax[#2]
-      \else
-        {#3}_{#1}\relax[#2]
-      \fi
+    \RenewExpandableDocumentCommand{\ncomponents}{}{n}
+    \RenewDocumentCommand{\allcomponents}{O{i} m}
+    {
+      {#2}\c_math_subscript_token{#1}
     }
-    \renewcommand*{\allbutlastand}[3][j]{%
-      \edef\tmp at arg{#1}%
-      \edef\tmp@@arg{#2}%
-      \ifx\tmp@@arg\ncomponents
-        {#3}_{#1}\relax[#2]%
-      \else
-        \ifx\tmp at arg\tmp@@arg
-          {#3}\relax[#2,\ncomponents]%
-        \else
-          {#3}\relax[#2,\ncomponents]%
-        \fi
-      \fi
+    \RenewDocumentCommand{\allbut}{O{i} m m}
+    { \tl_if_eq:nnTF {#1} {#2}
+      { {#3}\c_math_subscript_token{k}[#2] }
+      { {#3}\c_math_subscript_token{#1}[#2] }
     }
-    \renewcommand*{\IG}{{ig}}
-    \renewcommand*{\IGM}{{igm}}
-    \renewcommand*{\IS}{{ID}}
-    \renewcommand*{\excess}{{EX}}%
-    \renewcommand*{\reaction}{{rx}}
-    \renewcommand*{\Henryrat}{f^{\ast\ast}}
-    \renewcommand*{\Henrymol}{f^\ast}
-    \renewcommand*{\gammarat}{\gamma^{\ast\ast}}
-    \renewcommand*{\gammamol}{\gamma^\ast}
+    \RenewDocumentCommand{\allbutlastand}{O{j} m m}
+    { \tl_if_eq:xxTF {#2} {\ncomponents}
+      { {#3}\c_math_subscript_token{#1}\relax[#2] }
+      { \tl_if_eq:nnTF {#1} {#2}
+        { {#3}\c_math_subscript_token{k}[#2,\ncomponents] }
+        { {#3}\c_math_subscript_token{#1}[#2,\ncomponents] }
+      }
+    }
+    \RenewDocumentCommand{\IG}{}{{o}}
+    \RenewDocumentCommand{\IGM}{}{{o}}
+    \RenewDocumentCommand{\IS}{}{{ID}}
+    \RenewDocumentCommand{\excess}{}{{EX}}
+    \RenewDocumentCommand{\reaction}{}{{rx}}
+    \RenewDocumentCommand{\Henryrat}{}
+        {f\c_math_superscript_token{\ast\ast}}
+    \RenewDocumentCommand{\Henrymol}{}{f\c_math_superscript_token\ast}
+    \RenewDocumentCommand{\gammarat}{}
+        {\gamma\c_math_superscript_token{\ast\ast}}
+    \RenewDocumentCommand{\gammamol}{}
+        {\gamma\c_math_superscript_token\ast}
+    \RenewExpandableDocumentCommand{\JTsymbol}{}{\alpha}
+    \RenewSubscriptedSymbol{\muJT}{\JTsymbol}{H}
   }
 }
 \DeclareOption{Thompson}{
   \ExecuteOptions{EUAGHAn,delta}
-  \AtEndOfPackage{
-    \renewcommand*{\excess}{{EX}}
-    \renewcommand*{\residual}{{R}}
-    \renewcommand*{\allcomponents}[1]{{#1}_j}
-    \renewcommand*{\ncomponents}{c}
-    \renewcommand*{\IS}{{IS}}
-    \renewcommand*{\IG}{{IG}}
-    \let\IGM\IG
-    \def\@fpure_#1{f_{#1}\@ifnextchar^{}{^\bullet}}
-    \renewcommand*{\fpure}{\@ifnextchar_{\@fpure}{f}}
-    \def\@phi at pure_#1{\phi_{#1}\@ifnextchar^{}{^\bullet}}
-    \renewcommand*{\phipure}{\@ifnextchar_{\@phi at pure}{\phi}}
-    \renewcommand*{\mixing}{{MIX}}
-    \renewcommand*{\Deltamix}[1]{\Delta_\mixing #1}
-    \renewcommand*{\Deltarxn}[1]{\Delta #1}
-    \def\@@intensive_#1{_{#1}\@ifnextchar^{}{^\bullet}}
-    \newcommand*{\@intensive}[1]{#1\@ifnextchar_{\@@intensive}{}}
-    \renewcommand*{\allbut}[3][j]{%
-      \def\tmp at arg{#2}%
-      \def\tmp@@arg{#1}%
-      \ifx\tmp at arg\tmp@@arg
-        {#3}_{k}\neq{#3}_{#2}%
-      \else
-        {#3}_{#1}\neq{#3}_{#2}%
-      \fi
+  \AtEndOfPackage
+  {
+    \RenewDocumentCommand{\excess}{}{{EX}}
+    \RenewDocumentCommand{\residual}{}{{R}}
+    %^^A He uses k_H for both types of Henry's constant, but I changed
+    %^^A the rational basis one just so there is SOME difference
+    \RenewSubscriptedSymbol{\Henryrat}{k}{h}
+    \RenewSubscriptedSymbol{\Henrymol}{k}{H}
+    \RenewDocumentCommand{\allcomponents}{O{j} m}
+    {
+      {#2}\c_math_subscript_token{#1}
     }
+    \RenewDocumentCommand{\allNs}{O{j}}{\allcomponents[#1]{\Nt}}
+    \RenewDocumentCommand{\allXs}{O{j}}{\allcomponents[#1]{x}}
+    \RenewDocumentCommand{\allYs}{O{j}}{\allcomponents[#1]{y}}
+    \RenewDocumentCommand{\allmus}{O{j}}{\allcomponents[#1]{\mu}}
+    \RenewDocumentCommand{\allMs}{O{j}}{\allcomponents[#1]{m}}
+    \RenewDocumentCommand{\allWs}{O{j}}{\allcomponents[#1]{w}}
+    \RenewExpandableDocumentCommand{\ncomponents}{}{c}
+    \RenewDocumentCommand{\IS}{}{{IS}}
+    \RenewDocumentCommand{\IG}{}{{IG}}
+    \RenewDocumentCommand{\IGM}{}{{IG}}
+    \cs_new:Nn \__thermodynamics_fpure_one:n
+    {
+      f\c_math_subscript_token{#1}
+      \peek_catcode_remove:NF \c_math_superscript_token
+      { \c_math_superscript_token\bullet }
+    }
+    \RenewDocumentCommand{\fpure}{}
+    {
+      \peek_catcode_remove:NTF \c_math_subscript_token
+      { \__thermodynamics_fpure_one:n }
+      { f }
+    }
+    \cs_new:Nn \__thermodynamics_intensive_two:n
+    {
+      \c_math_subscript_token{#1}
+      \peek_catcode:NF \c_math_superscript_token
+      {
+        \c_math_superscript_token\bullet
+      }
+    }
+    \cs_set:Nn \__thermodynamics_intensive:n
+    { #1
+      \peek_catcode_remove:NT \c_math_subscript_token
+      { \__thermodynamics_intensive_two:n }
+    }
+    \cs_new:Nn \__thermodynamics_phipure_one:n
+    {
+      \phi\c_math_subscript_token{#1}
+      \peek_catcode:NF \c_math_superscript_token
+      { \c_math_superscript_token\bullet }
+    }
+    \RenewDocumentCommand{\phipure}{}
+    {
+      \peek_catcode_remove:NTF \c_math_subscript_token
+      {
+        \__thermodynamics_phipure_one:n
+      }
+      {\phi}
+    }
+    \RenewDocumentCommand{\mixing}{}{{MIX}}
+    \RenewDocumentCommand{\Deltamix}{m}
+        {\Delta\c_math_subscript_token\mixing #1}
+    \RenewDocumentCommand{\Deltarxn}{m}{\Delta #1}
+    \RenewDocumentCommand{\allbut}{O{j} m m}
+    { \tl_if_eq:nnTF {#1} {#2}
+      {
+        {#3}\c_math_subscript_token k\neq{#3}\c_math_subscript_token{#2}
+      }
+      {
+        {#3}\c_math_subscript_token{#1}\neq{#3}\c_math_subscript_token{#2}
+      }
+    }
   }
 }
 \ExecuteOptions{EUAGHan,subscripts,parentheses,intensive-plain,moles-index}
 \ProcessOptions
-\newlength{\Partial at const@width}
-\newlength{\operator at width}
-\settowidth{\operator at width}{=}
-\newlength{\adjust at width}
-\setlength{\adjust at width}{0.1\operator at width}
-\addtolength{\operator at width}{\adjust at width}
-\def\Partial at start{\left\PartialOpen}
-\def\Partial at end{\right\PartialClose}
-\def\Partial at empty@end{\right\PartialEmptyClose}
-\def\Partial{\@ifstar\Partial at star\Partial at nostar}
-\newif\iftwo at has@Nt
-\two at has@Ntfalse
-\newif\iftwo at has@xory
-\two at has@xoryfalse
-\newif\ifthree at has@Nt
-\three at has@Ntfalse
-\newif\ifthree at has@xory
-\three at has@xoryfalse
-\AtEndOfPackage{%
-  \edef\thermo at Nt{\Nt}%
-  \edef\thermo at x{x}%
-  \edef\thermo at y{y}%
+\tl_const:Nn \c__thermodynamics_sort_order_tl
+    {\Et\Em\Es\Ut\Um\Us\Ht\Hm\Hs\Ft\Fm\Fs\Gt\Gm\Gs\Lt\Lm\Ls T\St\Sm\Ss
+        P\Vt\Vm\Vs\mu\Nt mwxyz\At\Am\As\sigma
+        ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklnopqrstuvwxyz}
+\clist_new:N \l__thermodynamics_in_list_clist
+\clist_new:N \l__thermodynamics_sorted_list_clist
+\clist_new:N \l__thermodynamics_remaining_list_clist
+\cs_new:Nn \__thermodynamics_sort_clist:n
+{% Sort the list in the order of \c__thermodynamics_sort_order_tl
+
+  % Wipe out any remnants from the last sort
+  \clist_clear:N \l__thermodynamics_in_list_clist
+  \clist_clear:N \l__thermodynamics_sorted_list_clist
+
+  % Make a copy of the list
+  \clist_set:Nn \l__thermodynamics_remaining_list_clist {#1}
+
+  % Make a list of everything that's in the known sort order list
+  % and put everything else in the "not in sort order list" list.
+  \tl_map_inline:Nn \c__thermodynamics_sort_order_tl
+  {
+    \clist_if_in:NnT \l__thermodynamics_remaining_list_clist {##1}
+    { \clist_put_right:Nn \l__thermodynamics_in_list_clist {##1} }
+
+    \clist_remove_all:Nn \l__thermodynamics_remaining_list_clist {##1}
+  }
+
+  % Then merge the lists back together again.
+  \clist_if_empty:NF \l__thermodynamics_in_list_clist
+  {
+    \clist_put_right:Nn \l__thermodynamics_sorted_list_clist \l__thermodynamics_in_list_clist
+  }
+  \clist_if_empty:NF \l__thermodynamics_remaining_list_clist
+  {
+    \clist_put_right:Nn \l__thermodynamics_sorted_list_clist \l__thermodynamics_remaining_list_clist
+  }
+  \clist_use:Nn \l__thermodynamics_sorted_list_clist ,
 }
-\def\thermo at parse@two#1\relax{%
-  \@tfor\@i:=#1\do{%
-    \edef\@@i{\@i}%
-    \ifx\@@i\thermo at Nt
-      \two at has@Nttrue
-      \@break at tfor
-    \fi
-    \ifx\@@i\thermo at x
-      \two at has@xorytrue
-      \@break at tfor
-    \fi
-    \ifx\@@i\thermo at y
-      \two at has@xorytrue
-      \@break at tfor
-    \fi
+\dim_new:N \l__thermodynamics_Partial_const_dim
+\dim_new:N \l__thermodynamics_operator_width_dim
+\dim_new:N \l__thermodynamics_adjust_width_dim
+\settowidth{\l__thermodynamics_operator_width_dim}{=}
+\dim_set:Nn \l__thermodynamics_adjust_width_dim {0.1\l__thermodynamics_operator_width_dim}
+\dim_add:Nn \l__thermodynamics_operator_width_dim \l__thermodynamics_adjust_width_dim
+\tl_new:N \l__thermodynamics_Partial_start_tl
+\tl_new:N \l__thermodynamics_Partial_end_tl
+\tl_new:N \l__thermodynamics_Partial_empty_end_tl
+\tl_new:N \l__thermodynamics_Partial_middle_tl
+\tl_set:Nn \l__thermodynamics_Partial_start_tl {\left\l__thermodynamics_PartialOpen_tl}
+\tl_set:Nn \l__thermodynamics_Partial_end_tl {\right\l__thermodynamics_PartialClose_tl}
+\tl_set:Nn \l__thermodynamics_Partial_empty_end_tl {\right\l__thermodynamics_PartialEmptyClose_tl}
+\tl_set:Nn \l__thermodynamics_Partial_middle_tl {\middle}
+\cs_set_eq:NN \__thermodynamics_frac:nn \frac
+\NewDocumentCommand{\Partial}{s m m m}
+{ \bool_if:nTF {#1}
+  {% Starred form (recursive)
+    \settowidth{\l__thermodynamics_Partial_const_dim}{\ensuremath{#4}}%
+    \dim_add:Nn \l__thermodynamics_Partial_const_dim {-0.20\l__thermodynamics_Partial_const_dim}%
+    \Partial{#2}{#3}{#4}%
+    \bool_if:NT \l__thermodynamics_subscripted_bool
+    { \dim_compare:nNnTF \l__thermodynamics_operator_width_dim
+                       < \l__thermodynamics_Partial_const_dim
+      { \kern -\l__thermodynamics_operator_width_dim }
+      { \kern -\l__thermodynamics_Partial_const_dim }
+    }
   }
+  {% Unstarred form
+    \bool_if:NTF \l__thermodynamics_subscripted_bool
+    {% Handle case of empty variables held constant
+      \tl_if_eq:nnTF {#4} {}
+      { \l__thermodynamics_Partial_start_tl
+        \__thermodynamics_frac:nn{\partial #2}{\partial #3}\l__thermodynamics_Partial_empty_end_tl
+      }
+      { \l__thermodynamics_Partial_start_tl\__thermodynamics_frac:nn{\partial #2}
+                                         {\partial #3}\l__thermodynamics_Partial_end_tl
+        \c_math_subscript_token{#4}%
+      }
+    }
+    {% Check whether #4 contains \allNsbut{i} and #3 is \Nt_i
+      \tl_if_in:nnTF {#3} {\Nt}
+      { \RenewDocumentCommand{\allbut}{O{j} m m}{\allcomponents{##3}}
+        \l__thermodynamics_Partial_start_tl
+        \__thermodynamics_frac:nn{\partial #2(\__thermodynamics_sort_clist:n{#4})}
+                   {\partial #3}\l__thermodynamics_Partial_end_tl
+      }
+      { \l__thermodynamics_Partial_start_tl
+        \__thermodynamics_frac:nn{\partial #2(\__thermodynamics_sort_clist:n{#3,#4})}
+                   {\partial #3}\l__thermodynamics_Partial_end_tl
+      }
+    }
+  }
 }
-\newcommand*{\Partial at nostar}[3]{%
-  \def\tmp at arg{#3}%
-  \if at subscripted
-    % Handles situation of empty variables held constant
-    \ifx\tmp at arg\@empty
-      \ensuremath{\Partial at start\frac{\partial #1}
-                                     {\partial #2}\Partial at empty@end}%
-    \else
-      \ensuremath{\Partial at start\frac{\partial #1}
-                                     {\partial #2}\Partial at end_{#3}}%
-    \fi
-  \else
-    % If not subscripted, we put the arguments (if any) in the derivative
-    \ifx\tmp at arg\@empty
-      \ensuremath{\Partial at start\frac{\partial #1}
-                                     {\partial #2}\Partial at empty@end}%
-    \else
-      % Check for whether #3 contains \allNsbut{i}/etc. and #2 is \Nt_i/etc.
-      \thermo at parse@two#2\relax
-      \iftwo at has@Nt
-        \renewcommand*{\allbut}[3][j]{\allcomponents{##3}}%
-        \ensuremath{\Partial at start\frac{\partial #1(#3)}
-                                       {\partial #2}\Partial at end}%
-      \else
-        \iftwo at has@xory
-          \renewcommand*{\allbutlastand}[3][j]{\allbut{\ncomponents}{##3}}%
-          \ensuremath{\Partial at start\frac{\partial #1(#3)}
-                                         {\partial #2}\Partial at end}%
-        \else
-          \ensuremath{\Partial at start\frac{\partial #1(#2,#3)}
-                                         {\partial #2}\Partial at end}%
-        \fi
-      \fi
-    \fi
-  \fi
+\NewDocumentCommand{\PartialBigg}{}
+  { \tl_set:Nn \l__thermodynamics_Partial_start_tl {\Biggl\l__thermodynamics_PartialOpen_tl}
+    \tl_set:Nn \l__thermodynamics_Partial_end_tl {\Biggr\l__thermodynamics_PartialClose_tl}
+    \tl_set:Nn \l__thermodynamics_Partial_Empty_end_tl
+        {\Biggr\l__thermodynamics_PartialEmptyClose_tl}
+    \Partial
+  }
+\NewDocumentCommand{\Partialbigg}{}
+  { \tl_set:Nn \l__thermodynamics_Partial_start_tl {\biggl\l__thermodynamics_PartialOpen_tl}
+    \tl_set:Nn \l__thermodynamics_Partial_end_tl {\biggr\l__thermodynamics_PartialClose_tl}
+    \tl_set:Nn \l__thermodynamics_Partial_empty_end_tl
+        {\biggr\l__thermodynamics_PartialEmptyClose_tl}
+    \Partial
+  }
+\NewDocumentCommand{\PartialSecond}{s m m m}
+{
+  \bool_if:nTF {#1}
+  {% Starred form
+    \settowidth{\l__thermodynamics_Partial_const_dim}{\ensuremath{#4}}%
+    \dim_add:Nn \l__thermodynamics_Partial_const_dim {-0.20\l__thermodynamics_Partial_const_dim}
+    \PartialSecond{#2}{#3}{#4}%
+    \bool_if:nT \l__thermodynamics_subscripted_bool
+    {  \dim_compare:nNnTF {\l__thermodynamics_operator_width_dim}
+                        < {\l__thermodynamics_Partial_const_dim}
+      { \kern -\l__thermodynamics_operator_width_dim }
+      { \kern -\l__thermodynamics_Partial_const_dim }
+    }
+  }
+  {% Unstarred form
+    \bool_if:NTF \l__thermodynamics_subscripted_bool
+    {% Handles case of empty variables held constant
+      \tl_if_eq:nnTF {#4} {}
+      { \l__thermodynamics_Partial_start_tl
+            \__thermodynamics_frac:nn{\partial\c_math_superscript_token 2 #2}
+        {\partial #3\c_math_superscript_token 2}\l__thermodynamics_Partial_empty_end_tl
+      }
+      { \l__thermodynamics_Partial_start_tl
+        \__thermodynamics_frac:nn{\partial\c_math_superscript_token 2 #2}
+            {\partial #3\c_math_superscript_token 2}\l__thermodynamics_Partial_end_tl
+            \c_math_subscript_token{#4}%
+      }
+    }
+    {% Check whether #4 contains \allNsbut{i} and #3 is \Nt_i
+      \tl_if_in:nnTF {#2} {\Nt}
+      { \RenewDocumentCommand{\allbut}{O{j} m m}{\allcomponents{##3}}
+        \l__thermodynamics_Partial_start_tl
+        \__thermodynamics_frac:nn{\partial\c_math_superscript_token 2 #2(#4)}
+            {\partial\c_math_superscript_token 2 #3}\l__thermodynamics_Partial_end_tl
+      }
+      { \l__thermodynamics_Partial_start_tl
+        \__thermodynamics_frac:nn{\partial\c_math_superscript_token 2
+                      #2(\__thermodynamics_sort_clist:n{#3,#4})}
+            {\partial #3\c_math_superscript_token 2}\l__thermodynamics_Partial_end_tl
+      }
+    }
+  }
 }
-\newcommand*{\Partial at star}[3]{%
-  \settowidth{\Partial at const@width}{\ensuremath{#3}}%
-  \addtolength{\Partial at const@width}{-0.15\Partial at const@width}%
-  \Partial at nostar{#1}{#2}{#3}%
-  \if at subscripted
-    \ifdim\operator at width<\Partial at const@width
-      \kern -\operator at width
-    \else
-      \kern -\Partial at const@width
-    \fi
-  \fi
+\NewDocumentCommand{\PartialSecondBigg}{}
+{ \tl_set:Nn \l__thermodynamics_Partial_start_tl {\biggl\l__thermodynamics_PartialOpen_tl}
+  \tl_set:Nn \l__thermodynamics_Partial_end_tl {\biggl\l__thermodynamics_PartialClose_tl}
+  \tl_set:Nn \l__thermodynamics_Partial_empty_end_tl {\biggl\l__thermodynamics_PartialClose_tl}
+  \PartialSecond
 }
-\def\PartialBigg{%
-  \def\Partial at start{\Biggl\PartialOpen}%
-  \def\Partial at end{\Biggr\PartialClose}%
-  \def\Partial at empty@end{\Biggr\PartialClose}%
-  \Partial%
+\NewDocumentCommand{\PartialSecondbigg}{}
+{ \tl_set:Nn \l__thermodynamics_Partial_start_tl {\biggl\l__thermodynamics_PartialOpen_tl}
+  \tl_set:Nn \l__thermodynamics_Partial_end_tl {\biggl\l__thermodynamics_PartialClose_tl}
+  \tl_set:Nn \l__thermodynamics_Partial_empty_end_tl {\biggl\l__thermodynamics_PartialClose_tl}
+  \PartialSecond
 }
-\def\Partialbigg{%
-  \def\Partial at start{\biggl\PartialOpen}%
-  \def\Partial at end{\biggr\PartialClose}%
-  \def\Partial at empty@end{\biggr\PartialClose}%
-  \Partial%
+\bool_new:N \l__thermodynamics_has_x_or_y_bool
+\NewDocumentCommand{\PartialMixSecond}{s m m m m}
+{
+  \bool_if:nTF {#1}
+  {% Starred version
+    \settowidth{\l__thermodynamics_Partial_const_dim}{\ensuremath{#4}}%
+    \dim_add:Nn \l__thermodynamics_Partial_const_dim {-0.20\l__thermodynamics_Partial_const_dim}
+    \PartialMixSecond{#2}{#3}{#4}{#5}
+    \bool_if:nT \l__thermodynamics_subscripted_bool
+    { \dim_compare:nNnTF {\l__thermodynamics_operator_width_dim}
+                       < {\l__thermodynamics_Partial_const_dim}
+      { \kern -\l__thermodynamics_operator_width_dim }
+      { \kern -\l__thermodynamics_Partial_const_dim }
+    }
+  }
+  {% Unstarred version
+    \bool_if:nTF \l__thermodynamics_subscripted_bool
+    {% subscripted version
+      \tl_if_eq:nnTF {#5} {}
+      {% Handle case of empty variables held constant
+        \l__thermodynamics_Partial_start_tl
+        \__thermodynamics_frac:nn{\partial\c_math_superscript_token 2 #2}
+            {\partial #3\partial #4}\l__thermodynamics_Partial_empty_end_tl
+      }
+      { \l__thermodynamics_Partial_start_tl
+        \__thermodynamics_frac:nn{\partial\c_math_superscript_token 2 #2}
+            {\partial #3\partial #4}\l__thermodynamics_Partial_end_tl
+            \c_math_subscript_token{#5}
+      }
+    }
+    {% not subscripted
+      \tl_if_eq:nnTF {#5} {}
+      {% empty argument
+        \l__thermodynamics_Partial_start_tl
+        \__thermodynamics_frac:nn{\partial\c_math_superscript_token 2
+                        #2(\__thermodynamics_sort_clist:n{#3,#4,#5})}
+                   {\partial #3\partial #4}\l__thermodynamics_Partial_empty_end_tl
+      }
+      {% Check whether #3 OR #4 are \Nt_i/etc.
+        \tl_if_in:nnTF {#3} {\Nt}
+        { \RenewDocumentCommand{\allbut}{O{j} m m}{\allcomponents{##3}}%
+          \l__thermodynamics_Partial_start_tl
+          \__thermodynamics_frac:nn{\partial\c_math_superscript_token 2
+                        #2(\__thermodynamics_sort_clist:n{#4,#5})}
+                     {\partial #3\partial #4}\l__thermodynamics_Partial_end_tl
+        }
+        { \tl_if_in:nnTF {#4} {\Nt}
+          { \RenewDocumentCommand{\allbut}{O{j} m m}{\allcomponents{##3}}%
+            \l__thermodynamics_Partial_start_tl
+            \__thermodynamics_frac:nn{\partial\c_math_superscript_token 2
+                            #2(\__thermodynamics_sort_clist:n{#3,#5})}
+                       {\partial #3\partial #4}\l__thermodynamics_Partial_end_tl
+          }
+          {% Check for x, y, or w
+            \bool_set_false:N \l__thermodynamics_has_x_or_y_bool
+            \tl_if_in:nnT {#3} {x}
+            { \l__thermodynamics_has_x_or_y_bool }
+            \tl_if_in:nnT {#3} {y}
+            { \l__thermodynamics_has_x_or_y_bool }
+            \tl_if_in:nnT {#3} {w}
+            { \l__thermodynamics_has_x_or_y_bool }
+            \bool_if:NTF \l__thermodynamics_has_x_or_y_bool
+            { \RenewDocumentCommand{\allbutlastand}{O{j} m m}
+                {\allcomponents{##3}}
+              \l__thermodynamics_Partial_start_tl
+              \__thermodynamics_frac:nn{\partial\c_math_superscript_token 2
+                            #2(\__thermodynamics_sort_clist:n{#4,#5})}
+                         {\partial #3\partial #4}\l__thermodynamics_Partial_end_tl
+            }
+            {
+              \l__thermodynamics_Partial_start_tl
+              \__thermodynamics_frac:nn{\partial\c_math_superscript_token 2
+                            #2(\__thermodynamics_sort_clist:n{#3,#4,#5})}
+                         {\partial #3\partial #4}\l__thermodynamics_Partial_end_tl
+            }
+          }
+        }
+      }
+    }
+  }
 }
-\def\PartialSecond{\@ifstar\PartialSecond at star\PartialSecond at nostar}
-\newcommand*{\PartialSecond at nostar}[3]{%
-  \def\tmp at arg{#3}%
-  \if at subscripted
-  % Handles situation of empty variables held constant
-    \ifx\tmp at arg\@empty
-        \ensuremath{\Partial at start\frac{\partial^2 #1}
-                                       {\partial #2^2}\Partial at empty@end}%
-    \else
-        \ensuremath{\Partial at start\frac{\partial^2 #1}
-                                       {\partial #2^2}\Partial at end_{#3}}%
-    \fi
-  \else
-    \ifx\tmp at arg\@empty
-        \ensuremath{\Partial at start\frac{\partial^2 #1}
-                                       {\partial #2^2}\Partial at empty@end}%
-    \else
-      % Check for whether #3 contains \allNsbut{i}/etc. and #2 is \Nt_i/etc.
-      \thermo at parse@two#2\relax
-      \iftwo at has@Nt
-        \renewcommand*{\allbut}[3][j]{\allcomponents{##3}}%
-        \ensuremath{\Partial at start\frac{\partial^2 #1(#3)}
-                                       {\partial #2^2}\Partial at end}%
-      \else
-        \iftwo at has@xory
-          \renewcommand*{\allbutlastand}[3][j]{\allbut{\ncomponents}{##3}}%
-          \ensuremath{\Partial at start\frac{\partial^2 #1(#3)}
-                                         {\partial #2^2}\Partial at end}%
-        \else
-          \ensuremath{\Partial at start\frac{\partial^2 #1(#2,#3)}
-                                         {\partial {#2}^2}\Partial at end}%
-        \fi
-      \fi
-    \fi
-  \fi
+\NewDocumentCommand{\PartialMixSecondBigg}{}
+{ \tl_set:Nn \l__thermodynamics_Partial_start_tl {\Biggl\l__thermodynamics_PartialOpen_tl}
+  \tl_set:Nn \l__thermodynamics_Partial_end_tl {\Biggl\l__thermodynamics_PartialClose_tl}
+  \tl_set:Nn \l__thermodynamics_Partial_empty_end_tl {\Biggl\l__thermodynamics_PartialClose_tl}
+  \PartialMixSecond
 }
-\newcommand*{\PartialSecond at star}[3]{%
-    \settowidth{\Partial at const@width}{\ensuremath{#3}}%
-    \addtolength{\Partial at const@width}{-0.15\Partial at const@width}%
-    \PartialSecond at nostar{#1}{#2}{#3}%
-    \if at subscripted
-      \ifdim\operator at width<\Partial at const@width
-        \kern -\operator at width
-      \else
-        \kern -\Partial at const@width
-      \fi
-    \fi
+\NewDocumentCommand{\PartialMixSecondbigg}{}
+{ \tl_set:Nn \l__thermodynamics_Partial_start_tl {\biggl\l__thermodynamics_PartialOpen_tl}
+  \tl_set:Nn \l__thermodynamics_Partial_end_tl {\biggl\l__thermodynamics_PartialClose_tl}
+  \tl_set:Nn \l__thermodynamics_Partial_empty_end_tl {\biggl\l__thermodynamics_PartialClose_tl}
+  \PartialMixSecond
 }
-\def\PartialSecondBigg{%
-  \def\Partial at start{\expandafter\Biggl\PartialOpen}%
-  \def\Partial at end{\expandafter\Biggr\PartialClose}%
-  \PartialSecond%
+\AtBeginDocument{%
+  \@ifpackageloaded{amsmath}{}{%
+      \PackageWarningNoLine{thermodynamics}
+        {Package~amsmath~not~loaded;~load~to~make~PartialBigg~and~friends
+            ~work~correctly}%
+      \cs_set_eq:NN \PartialBigg \Partial
+      \cs_set_eq:NN \Partialbigg \Partial
+      \cs_set_eq:NN \PartialSecondBigg \PartialSecond
+      \cs_set_eq:NN \PartialSecondbigg \PartialSecond
+      \cs_set_eq:NN \PartialMixSecondBigg \PartialMixSecond
+      \cs_set_eq:NN \PartialMixSecondbigg \PartialMixSecond
+      \ProvideDocumentCommand{\rvert}{}{|}
+      \ProvideDocumentCommand{\lvert}{}{|}
+  }%
 }
-\def\PartialSecondbigg{%
-  \def\Partial at start{\expandafter\biggl\PartialOpen}%
-  \def\Partial at end{\expandafter\biggr\PartialClose}%
-  \PartialSecond%
+\NewDocumentCommand{\Partialinline}{}
+{
+  \cs_set:Nn \__thermodynamics_frac:nn { ##1 \l__thermodynamics_Partial_middle_tl / ##2 }
+  \Partial
 }
-\def\PartialMixSecond{\@ifstar\PartialMixSecond at star\PartialMixSecond at nostar}
-\newcommand*{\PartialMixSecond at nostar}[4]{%
-  \def\tmp at arg{#4}%
-  \if at subscripted
-  % Handles situation of empty variables held constant
-    \ifx\tmp at arg\@empty
-      \ensuremath{\Partial at start\frac{\partial^2 #1}
-                           {\partial #2\partial#3}\Partial at empty@end}%
-    \else
-      \ensuremath{\Partial at start\frac{\partial^2 #1}
-                           {\partial #2\partial#3}\Partial at end_{#4}}%
-    \fi
-  \else
-    \ifx\tmp at arg\@empty
-      \ensuremath{\Partial at start\frac{\partial^2 #1(#2,#3)}
-                           {\partial #2\partial#3}\Partial at empty@end}%
-    \else
-      % This time, we check whether #2 OR #3 are \Nt_i/etc.
-      \thermo at parse@two#3\relax
-      \iftwo at has@Nt\three at has@Nttrue\fi
-      \iftwo at has@xory\three at has@xorytrue\fi
-      \two at has@Ntfalse
-      \two at has@xoryfalse
-      \thermo at parse@two#2\relax
-      \iftwo at has@Nt
-        \renewcommand*{\allbut}[3][j]{\allcomponents{##3}}%
-        \ensuremath{\Partial at start\frac{\partial^2 #1(#3,#4)}
-                                       {\partial #2\partial#3}\Partial at end}%
-      \else
-        \iftwo at has@xory
-          \renewcommand*{\allbutlastand}[3][j]{\allbut{\ncomponents}{##3}}%
-          \ensuremath{\Partial at start\frac{\partial^2 #1(#3,#4)}
-                                         {\partial #2\partial#3}\Partial at end}%
-        \else
-          \ifthree at has@Nt
-            \renewcommand*{\allbut}[3][j]{\allcomponents{##3}}%
-            \ensuremath{\Partial at start\frac{\partial^2 #1(#2,#4)}
-                                      {\partial #2\partial#3}\Partial at end}%
-          \else
-            \ifthree at has@xory
-              \PackageWarning{thermodynamics}{GOT HERE}
-              %\renewcommand*{\allbutlastand}[3][j]{\allbut{\ncomponents}{##3}}%
-              \renewcommand*{\allbutlastand}[3][j]{SCREW YOU}%
-              \ensuremath{\Partial at start\frac{\partial^2 #1(#2,#4)}
-                                        {\partial #2\partial#3}\Partial at end}%
-            \else
-              \ensuremath{\Partial at start\frac{\partial^2 #1(#2,#3,#4)}
-                                        {\partial #2\partial#3}\Partial at end}%
-            \fi
-          \fi
-        \fi
-      \fi
-    \fi
-  \fi
+\NewDocumentCommand{\PartialSecondinline}{}
+{
+  \cs_set:Nn \__thermodynamics_frac:nn { ##1 \l__thermodynamics_Partial_middle_tl / ##2 }
+  \PartialSecond
 }
-\newcommand*{\PartialMixSecond at star}[4]{%
-    \settowidth{\Partial at const@width}{\ensuremath{#4}}%
-    \addtolength{\Partial at const@width}{-0.25\Partial at const@width}%
-    \PartialMixSecond at nostar{#1}{#2}{#3}{#4}%
-    \if at subscripted
-      \ifdim\operator at width<\Partial at const@width
-        \kern -\operator at width
-      \else
-        \kern -\Partial at const@width
-      \fi
-    \fi
+\NewDocumentCommand{\PartialMixSecondinline}{}
+{
+  \cs_set:Nn \__thermodynamics_frac:nn { ##1 \l__thermodynamics_Partial_middle_tl / ##2 }
+  \PartialMixSecond
 }
-\def\PartialMixSecondBigg{%
-  \def\Partial at start{\expandafter\Biggl\PartialOpen}%
-  \def\Partial at end{\expandafter\Biggr\PartialClose}%
-  \PartialMixSecond%
+\NewDocumentCommand{\Partialinlinetext}{}
+{ \cs_set_eq:NN \l__thermodynamics_Partial_start_tl \l__thermodynamics_PartialOpen_tl
+  \cs_set_eq:NN \l__thermodynamics_Partial_end_tl \l__thermodynamics_PartialClose_tl
+  \cs_set_eq:NN \l__thermodynamics_Partial_empty_end_tl \l__thermodynamics_PartialEmptyClose_tl
+  \cs_set_eq:NN \l__thermodynamics_Partial_middle_tl \relax
+  \Partialinline
 }
-\def\PartialMixSecondbigg{%
-  \def\Partial at start{\expandafter\biggl\PartialOpen}%
-  \def\Partial at end{\expandafter\biggr\PartialClose}%
-  \PartialMixSecond%
+\NewDocumentCommand{\PartialSecondinlinetext}{}
+{ \cs_set_eq:NN \l__thermodynamics_Partial_start_tl \l__thermodynamics_PartialOpen_tl
+  \cs_set_eq:NN \l__thermodynamics_Partial_end_tl \l__thermodynamics_PartialClose_tl
+  \cs_set_eq:NN \l__thermodynamics_Partial_empty_end_tl \l__thermodynamics_PartialEmptyClose_tl
+  \cs_set_eq:NN \l__thermodynamics_Partial_middle_tl \relax
+  \PartialSecondinline
 }
-\AtBeginDocument{%
-  \@ifpackageloaded{amsmath}{}{%
-      \PackageWarningNoLine{thermodynamics}
-        {Package amsmath not loaded; load to make PartialBigg and friends
-            work correctly}%
-      \let\PartialBigg\Partial
-      \let\Partialbigg\Partial
-      \let\PartialSecondBigg\PartialSecond
-      \let\PartialSecondbigg\PartialSecond
-      \let\PartialMixSecondBigg\PartialMixSecond
-      \let\PartialMixSecondbigg\PartialMixSecond
-  }%
+\NewDocumentCommand{\PartialMixSecondinlinetext}{}
+{ \cs_set_eq:NN \l__thermodynamics_Partial_start_tl \l__thermodynamics_PartialOpen_tl
+  \cs_set_eq:NN \l__thermodynamics_Partial_end_tl \l__thermodynamics_PartialClose_tl
+  \cs_set_eq:NN \l__thermodynamics_Partial_empty_end_tl \l__thermodynamics_PartialEmptyClose_tl
+  \cs_set_eq:NN \l__thermodynamics_Partial_middle_tl \relax
+  \PartialMixSecondinline
 }
-\newenvironment*{thermoparentheses}{
-  \renewcommand*{\PartialOpen}{(}%
-  \renewcommand*{\PartialClose}{)}%
-  \renewcommand*{\PartialEmptyClose}{)}%
+\NewDocumentEnvironment{thermoparentheses}{}
+{ \cs_set:Nn \l__thermodynamics_PartialOpen_tl {(}
+  \cs_set:Nn \l__thermodynamics_PartialClose_tl {)}
+  \cs_set:Nn \l__thermodynamics_PartialEmptyClose_tl {)}
 }{}
-\newenvironment*{thermobrackets}{%
-  \renewcommand*{\PartialOpen}{[}%
-  \renewcommand*{\PartialClose}{]}%
-  \renewcommand*{\PartialEmptyClose}{]}%
+\NewDocumentEnvironment{thermobrackets}{}
+{ \tl_set:Nn \l__thermodynamics_PartialOpen_tl {[}
+  \tl_set:Nn \l__thermodynamics_PartialClose_tl {]}
+  \tl_set:Nn \l__thermodynamics_PartialEmptyClose_tl {]}
 }{}
-\newenvironment*{thermobraces}{%
-  \renewcommand*{\PartialOpen}{\{}%
-  \renewcommand*{\PartialClose}{\}}%
-  \renewcommand*{\PartialEmptyClose}{\}}%
+\NewDocumentEnvironment{thermobraces}{}
+{ \tl_set:Nn \l__thermodynamics_PartialOpen_tl {\{}
+  \tl_set:Nn \l__thermodynamics_PartialClose_tl {\}}
+  \tl_set:Nn \l__thermodynamics_PartialEmptyClose_tl {\}}
 }{}
-\newenvironment*{thermobar}{%
-  \renewcommand*{\PartialOpen}{.}%
-  \renewcommand*{\PartialClose}{\rvert}%
-  \renewcommand*{\PartialEmptyClose}{.}%
+\NewDocumentEnvironment{thermobar}{}
+{ \tl_set:Nn \l__thermodynamics_PartialOpen_tl {.}
+  \tl_set:Nn \l__thermodynamics_PartialClose_tl {\rvert}
+  \tl_set:Nn \l__thermodynamics_PartialEmptyClose_tl {.}
 }{}
-\newenvironment*{thermoplain}{%
-  \renewcommand*{\PartialOpen}{.}%
-  \renewcommand*{\PartialClose}{.}%
-  \renewcommand*{\PartialEmptyClose}{.}%
-  \@subscriptedfalse
+\NewDocumentEnvironment{thermoplain}{}
+{ \tl_set:Nn \l__thermodynamics_PartialOpen_tl {.}
+  \tl_set:Nn \l__thermodynamics_PartialClose_tl {.}
+  \tl_set:Nn \l__thermodynamics_PartialEmptyClose_tl {.}
+  \bool_set_false:N \l__thermodynamics_subscripted_bool
 }{}
-\newenvironment*{thermoNOsubscripts}{\@subscriptedfalse}{}
-\newenvironment*{thermosubscripts}{\@subscriptedtrue}{}
-\newcommand*{\DeclareSubscrSymbol}[3]{%
-  \expandafter\def\csname #1\endcsname{%
-    \@ifnextchar^{\csname @#1\endcsname}
-                 {\@ifnextchar_{\csname @@#1\endcsname}{{#2}_{#3}}}
+\NewDocumentEnvironment{thermoNOsubscripts}{}
+    {\bool_set_false:N \l__thermodynamics_subscripted_bool}
+    {}
+\NewDocumentEnvironment{thermosubscripts}{}
+    {\bool_set_true:N \l__thermodynamics_subscripted_bool}
+    {}
+\NewDocumentEnvironment{thermomolesrange}{}
+    { \__thermodynamics_set_moles_range }
+    {}
+\NewDocumentEnvironment{thermointensiveplain}{}
+    { \__thermodynamics_set_intensive_plain }
+    {}
+\NewDocumentEnvironment{thermoextensiveplain}{}
+    { \__thermodynamics_set_extensive_plain }
+    {}
+\NewDocumentEnvironment{thermointensivelowercase}{}
+    {% {
+
+      \__thermodynamics_set_intensive_lowercase
+      \__thermodynamics_set_lowercase_pms
+    }
+    {}
+\NewDocumentEnvironment{thermoextensivesuperscript}{}
+    {
+      \__thermodynamics_set_extensive_superscripts
+    }
+    {}
+\cs_new:Npn \__thermodynamics_check_definable:nN #1#2
+{
+  \bool_set_true:N \l__thermodynamics_arg_legal_bool
+  \tl_trim_spaces_apply:nN {#1} \tl_if_single_token:nTF
+  {
+    \str_set:Nx \l_tmp_str {\tl_to_str:n {#1}}
+    \int_compare:nNnT {\str_count:N \l_tmp_str} = 1
+    { \PackageError{thermodynamics}
+        {First~argument~of~'\tl_trim_spaces:o {\tl_to_str:n {#2}}'~
+         must~be~a~command}
+        {The~first~argument~of~'\tl_trim_spaces:o {\tl_to_str:n {#2}}'~
+         should~be~the~macro~that~will~be~used~to~refer~to~the~symbol.~
+         The~provided~argument~'\tl_trim_spaces:o {\tl_to_str:n {#1}}'~
+         is~a~single~character.
+         \MessageBreak Perhaps~a~backslash~is~missing?}
+    }
   }
-  \expandafter\def\csname @#1\endcsname ##1##2{%
-    {#2}^{##2}\@ifnextchar_{\csname @@@#1\endcsname}{_{#3}}%
+  { \PackageError{thermodynamics}
+      {First~argument~of~'\tl_trim_spaces:o {\tl_to_str:n {#2}}'~
+       must~be~a~command}
+      {The~first~argument~of~'\tl_trim_spaces:o {\tl_to_str:n {#2}}'~
+       should~be~the~macro~that~will~be~used~to~refer~to~the~symbol.~
+       The~provided~argument~'\tl_trim_spaces:o {\tl_to_str:n {#1}}'~
+       contains~more~than~one~token.
+       \MessageBreak Perhaps~a~backslash~is~missing?}
   }
-  \expandafter\def\csname @@#1\endcsname ##1##2{{#2}_{#3,##2}}
-  \expandafter\def\csname @@@#1\endcsname ##1##2{_{#3,##2}}
 }
-\newcommand*{\heatcapacitysymbol}{C}
-\newcommand*{\compressibilitysymbol}{\kappa}
-\newcommand*{\expansivitysymbol}{\alpha}
-\DeclareSubscrSymbol{cV}{\@intensive\heatcapacitysymbol}{\volume at symbol}
-\DeclareSubscrSymbol{cP}{\@intensive\heatcapacitysymbol}{\pressure at symbol}
-\DeclareSubscrSymbol{cVt}{\@extensive\heatcapacitysymbol}{\volume at symbol}
-\DeclareSubscrSymbol{cPt}{\@extensive\heatcapacitysymbol}{\pressure at symbol}
-\DeclareSubscrSymbol{cVs}{\@specific\heatcapacitysymbol}{\volume at symbol}
-\DeclareSubscrSymbol{cPs}{\@specific\heatcapacitysymbol}{\pressure at symbol}
-\DeclareSubscrSymbol{kappaT}{\compressibilitysymbol}{\temperature at symbol}
-\DeclareSubscrSymbol{kappaS}{\compressibilitysymbol}{\entropy at symbol}
-\DeclareSubscrSymbol{alphaP}{\expansivitysymbol}{\pressure at symbol}
-\DeclareSubscrSymbol{alphaS}{\expansivitysymbol}{\entropy at symbol}
-\newcommand*{\sat}{{\text{sat}}}
-\newcommand*{\Psat}{P^\sat}
-\let\Pvap\Psat
-\newcommand*{\phisat}{\phi^\sat}
-\newcommand*{\fsat}{f^\sat}
-\let\std\circ
-\newcommand*{\Pstd}{P^\std}
-\newcommand*{\fstd}{f^\std}
-\newcommand*{\mixing}{{\text{mix}}}
-\newcommand*{\Deltamix}[1]{\Delta{#1}_\mixing}
-\newcommand*{\fusion}{{\text{fus}}}
-\newcommand*{\reaction}{{\text{rxn}}}
-\newcommand*{\sublimation}{{\text{sub}}}
-\newcommand*{\vaporization}{{\text{vap}}}
-\newcommand*{\formation}{f}
-\newcommand*{\Deltafus}[1]{\Delta{#1}^\fusion}
-\newcommand*{\Deltasub}[1]{\Delta{#1}^\sublimation}
-\newcommand*{\Deltavap}[1]{\Delta{#1}^\vaporization}
-\let\Delta at rxn@sym\relax
-\DeclareSubscrSymbol{@DeltarxncP}{\Delta at rxn@sym}{\pressure at symbol,\reaction}
-\DeclareSubscrSymbol{@Deltarxn}{\Delta at rxn@sym}{\reaction}
-\newcommand*{\Deltarxn}[1]{%
-    \def\tmp at arg{#1}%
-    \def\tmp@@arg{\cP}%
-    \ifx\tmp at arg\tmp@@arg\relax
-      \def\@command{\def\Delta at rxn@sym{\Delta\@intensive\heatcapacitysymbol}%
-                    \@DeltarxncP}
-    \else
-      \def\@command{\def\Delta at rxn@sym{\Delta{#1}}\@Deltarxn}
-    \fi
-    \@command
+\NewDocumentCommand{\NewSubscriptedSymbol}{m m m}
+{
+  \__thermodynamics_check_definable:nN {#1} \NewSubscriptedSymbol
+  \cs_if_exist:NT #1
+  { \PackageError{thermodynamics}
+      {Command~'\tl_trim_spaces:o {\tl_to_str:n {#1}}'~already~defined}
+      {You~have~used~
+       '\tl_trim_spaces:o {\tl_to_str:n {\NewSubscriptedSymbol}}'~
+       with~a~command~that~already~has~a~definition}
+  }
+  \cs_new:cpn {\cs_to_str:N #1_one:n} ##1
+  {
+    {#2}\c_math_superscript_token{##1}
+    \peek_catcode_remove:NTF \c_math_subscript_token
+    { \use:c {\cs_to_str:N #1_three:n} }
+    { \c_math_subscript_token{#3} }
+  }
+
+  \cs_new:cpn {\cs_to_str:N #1_two:n} ##1
+  { {#2}\c_math_subscript_token{#3,##1} }
+
+  \cs_new:cpn {\cs_to_str:N #1_three:n} ##1
+  { \c_math_subscript_token{#3,##1} }
+
+  \NewDocumentCommand{#1}{}
+  {% @branch
+    \peek_catcode_remove:NTF \c_math_superscript_token
+    { \use:c {\cs_to_str:N #1_one:n} }
+    { \peek_catcode_remove:NTF \c_math_subscript_token
+      { \use:c {\cs_to_str:N #1_two:n} }
+      { {#2}\c_math_subscript_token{#3} }
+    }
+  }
 }
-\let\Delta at f@sym\relax
-\DeclareSubscrSymbol{@Deltaf}{\Delta at f@sym}{f}
-\newcommand*{\Deltaf}[1]{\def\Delta at f@sym{\Delta{#1}}\@Deltaf}
-\newcommand*{\fmix}{\hat{f}}
-\newcommand*{\phimix}{\hat\phi}
-\newcommand*{\fpure}{f}
-\let\phipure\phi
-\let\pm at symbol\relax
-\newcommand*{\partialmolar}[1]{\gdef\pm at symbol{#1}\generic at pm}
-\def\generic at pm{\@ifnextchar_\@generic at pm\@@generic at pm}
-\def\@generic at pm#1#2{%
-    \gdef\pm at arg{#2}%
-    % if nextchar after argument is ^
-    \@ifnextchar^\@@@generic at pm\@@@@generic at pm
+\NewDocumentCommand{\RenewSubscriptedSymbol}{m m m}
+{
+  \__thermodynamics_check_definable:nN {#1} \RenewSubscriptedSymbol
+  \cs_if_exist:NF #1
+  { \PackageError{thermodynamics}
+      {Command~'\tl_trim_spaces:o {\tl_to_str:n {#1}}'~not~defined}
+      {You~have~used~
+       '\tl_trim_spaces:o {\tl_to_str:n {\RenewSubscriptedSymbol}}'~
+       with~a~command~that~does~not~have~a~definition}
+  }
+  \cs_set:cpn {\cs_to_str:N #1_one:n} ##1
+  {
+    {#2}\c_math_superscript_token{##1}
+    \peek_catcode_remove:NTF \c_math_subscript_token
+    { \use:c {\cs_to_str:N #1_three:n} }
+    { \c_math_subscript_token{#3} }
+  }
+
+  \cs_set:cpn {\cs_to_str:N #1_two:n} ##1
+  { {#2}\c_math_subscript_token{#3,##1} }
+
+  \cs_set:cpn {\cs_to_str:N #1_three:n} ##1
+  { \c_math_subscript_token{#3,##1} }
+
+  \RenewDocumentCommand{#1}{}
+  {% @branch
+    \peek_catcode_remove:NTF \c_math_superscript_token
+    { \use:c {\cs_to_str:N #1_one:n} }
+    { \peek_catcode_remove:NTF \c_math_subscript_token
+      { \use:c {\cs_to_str:N #1_two:n} }
+      { {#2}\c_math_subscript_token{#3} }
+    }
+  }
+
 }
-\def\@@@generic at pm#1#2{\thermo at overline{\pm at symbol^{#2}_{\pm at arg}}}
-\def\@@@@generic at pm{\thermo at overline{\pm at symbol_{\pm at arg}}}
-\def\@@generic at pm{\@ifnextchar^\@@@@@generic at pm\@pm at bracket@check}
-\def\@@@@@generic at pm#1#2#3#4{\thermo at overline{\pm at symbol^{#2}_{#4}}}
-\def\@pm at bracket@check{\@ifnextchar[\@pm at bracket@yes\@pm at bracket@no}
-\def\@pm at bracket@yes[#1]#2{\thermo at overline{\pm at symbol^{#1}_{#2}}}
-\def\@pm at bracket@no#1{\thermo at overline{\pm at symbol_{#1}}}
-\newcommand*{\Nt}{\mole at symbol}
-\newcommand*{\Et}{\@extensive\totalenergy at symbol}
-\newcommand*{\Ut}{\@extensive\internalenergy at symbol}
-\newcommand*{\Ft}{\@extensive\Helmholtz at symbol}
-\newcommand*{\Gt}{\@extensive\Gibbs at symbol}
-\newcommand*{\Ht}{\@extensive\enthalpy at symbol}
-\newcommand*{\Lt}{\@extensive\Landau at symbol}
-\newcommand*{\At}{\@extensive\area at symbol}
-\newcommand*{\St}{\@extensive\entropy at symbol}
-\newcommand*{\Vt}{\@extensive\volume at symbol}
-\newcommand*{\Qt}{\@extensive\heat at symbol}
-\newcommand*{\Wt}{\@extensive\work at symbol}
-\newcommand*{\Mt}{\@extensive M}
-\newcommand*{\Bt}{\@extensive B}
-\newcommand*{\Em}{\@intensive\totalenergy at symbol}
-\newcommand*{\Um}{\@intensive\internalenergy at symbol}
-\newcommand*{\Fm}{\@intensive\Helmholtz at symbol}
-\newcommand*{\Gm}{\@intensive\Gibbs at symbol}
-\newcommand*{\Hm}{\@intensive\enthalpy at symbol}
-\newcommand*{\Lm}{\@intensive\Landau at symbol}
-\newcommand*{\Am}{\@intensive\area at symbol}
-\newcommand*{\Sm}{\@intensive\entropy at symbol}
-\newcommand*{\Vm}{\@intensive\volume at symbol}
-\newcommand*{\Qm}{\@intensive\heat at symbol}
-\newcommand*{\Wm}{\@intensive\work at symbol}
-\newcommand*{\Mm}{\@intensive M}
-\newcommand*{\Bm}{\@intensive B}
-\newcommand*{\Us}{\@specific\internalenergy at symbol}
-\newcommand*{\Es}{\@specific\totalenergy at symbol}
-\newcommand*{\Fs}{\@specific\Helmholtz at symbol}
-\newcommand*{\Gs}{\@specific\Gibbs at symbol}
-\newcommand*{\Hs}{\@specific\enthalpy at symbol}
-\newcommand*{\Ls}{\@specific\Landau at symbol}
-\newcommand*{\As}{\@specific\area at symbol}
-\newcommand*{\Ss}{\@specific\entropy at symbol}
-\newcommand*{\Vs}{\@specific\volume at symbol}
-\newcommand*{\Qs}{\@specific\heat at symbol}
-\newcommand*{\Ws}{\@specific\work at symbol}
-\newcommand*{\Ms}{\@specific M}
-\newcommand*{\Bs}{\@specific B}
-\newcommand*{\Epm}{\partialmolar{\totalenergy at symbol}}
-\newcommand*{\Upm}{\partialmolar{\internalenergy at symbol}}
-\newcommand*{\Hpm}{\partialmolar{\enthalpy at symbol}}
-\newcommand*{\Fpm}{\partialmolar{\Helmholtz at symbol}}
-\newcommand*{\Gpm}{\partialmolar{\Gibbs at symbol}}
-\newcommand*{\Apm}{\partialmolar{\area at symbol}}
-\newcommand*{\Spm}{\partialmolar{\entropy at symbol}}
-\newcommand*{\Vpm}{\partialmolar{\volume at symbol}}
-\newcommand*{\Lpm}{\partialmolar{\Omega}}
-\newcommand*{\Mpm}{\partialmolar{M}}
-\newcommand*{\Bpm}{\partialmolar{B}}
-\newcommand*{\cPpm}{%
-  \def\@@@generic at pm##1##2{%
-    \thermo at overline{\pm at symbol^{##2}_{\pressure at symbol,\pm at arg}}}%
-  \def\@@@@generic at pm{\thermo at overline{\pm at symbol_{\pressure at symbol,\pm at arg}}}%
-  \def\@@@@@generic at pm##1##2##3##4{%
-    \thermo at overline{\pm at symbol^{##2}_{\pressure at symbol,##4}}}%
-  \def\@pm at bracket@yes[##1]##2{%
-    \thermo at overline{\pm at symbol^{##1}_{\pressure at symbol,##2}}}%
-  \def\@pm at bracket@no##1{\thermo at overline{\pm at symbol_{\pressure at symbol,##1}}}%
-  \partialmolar{\heatcapacitysymbol}%
+\NewDocumentCommand{\NewSuperscriptedSymbol}{m m m}
+{
+  \__thermodynamics_check_definable:nN {#1} \NewSuperscriptedSymbol
+  \cs_if_exist:NT #1
+  { \PackageError{thermodynamics}
+      {Command~'\tl_trim_spaces:o {\tl_to_str:n {#1}}'~already~defined}
+      {You~have~used~
+       '\tl_trim_spaces:o {\tl_to_str:n {\NewSuperscriptedSymbol}}'~
+       with~a~command~that~already~has~a~definition}
+  }
+  \cs_new:cpn {\cs_to_str:N #1_one:n} ##1
+  {
+    {#2}\c_math_subscript_token{#1}
+    \peek_catcode_remove:NTF \c_math_superscript_token
+    { \use:c {\cs_to_str:N #1_one:n} }
+    { \c_math_subscript_token{#3} }
+  }
+
+  \cs_new:cpn {\cs_to_str:N #1_two:n} ##1
+  { {#2}\c_math_superscript_token{#3,##1} }
+
+  \cs_new:cpn {\cs_to_str:N #1_three:n} ##1
+  { {#2}\c_math_superscript_token{#3,##1} }
+
+  \NewDocumentCommand{#1}{}
+  {
+    \peek_catcode_remove:NTF \c_math_subscript_token
+    { \use:c {\cs_to_str:N #1_one:n} }
+    { \peek_catcode_remove:NTF \c_math_superscript_token
+      { \use:c {\cs_to_str:N #1_two:n} }
+      { {#2}\c_math_superscript_token{#3} }
+    }
+  }
 }
-\newcommand*{\cVpm}{%
-  \def\@@@generic at pm##1##2{%
-    \thermo at overline{\pm at symbol^{##2}_{\volume at symbol,\pm at arg}}}%
-  \def\@@@@generic at pm{\thermo at overline{\pm at symbol_{\volume at symbol,\pm at arg}}}%
-  \def\@@@@@generic at pm##1##2##3##4{%
-    \thermo at overline{\pm at symbol^{##2}_{\volume at symbol,##4}}}%
-  \def\@pm at bracket@yes[##1]##2{%
-    \thermo at overline{\pm at symbol^{##1}_{\volume at symbol,##2}}}%
-  \def\@pm at bracket@no##1{\thermo at overline{\pm at symbol_{\volume at symbol,##1}}}%
-  \partialmolar{\heatcapacitysymbol}%
+\NewDocumentCommand{\RenewSuperscriptedSymbol}{m m m}
+{
+  \__thermodynamics_check_definable:nN {#1} \RenewSuperscriptedSymbol
+  \cs_if_exist:NF #1
+  { \PackageError{thermodynamics}
+      {Command~'\tl_trim_spaces:o {\tl_to_str:n {#1}}'~not~defined}
+      {You~have~used~
+       '\tl_trim_spaces:o {\tl_to_str:n {\RenewSuperscriptedSymbol}}'~
+       with~a~command~that~does~not~have~a~definition}
+  }
+  \cs_set:cpn {\cs_to_str:N #1_one:n} ##1
+  {
+    {#2}\c_math_subscript_token{##1}
+    \peek_catcode_remove:NTF \c_math_superscript_token
+    { \use:c {\cs_to_str:N #1_three:n} }
+    { \c_math_superscript_token{#3} }
+  }
+
+  \cs_set:cpn {\cs_to_str:N #1_two:n} ##1
+  { {#2}\c_math_superscript_token{#3,##1} }
+
+  \cs_set:cpn {\cs_to_str:N #1_three:n} ##1
+  { \c_math_superscript_token{#3,##1} }
+
+  \RenewDocumentCommand{#1}{}
+  {% @branch
+    \peek_catcode_remove:NTF \c_math_subscript_token
+    { \use:c {\cs_to_str:N #1_one:n} }
+    { \peek_catcode_remove:NTF \c_math_superscript_token
+      { \use:c {\cs_to_str:N #1_two:n} }
+      { {#2}\c_math_superscript_token{#3} }
+    }
+  }
 }
-\newcommand*{\residual}{R}
-\newcommand*{\excess}{E}
-\newcommand*{\UR}{\Um^\residual}
-\newcommand*{\HR}{\Hm^\residual}
-\newcommand*{\FR}{\Fm^\residual}
-\newcommand*{\GR}{\Gm^\residual}
-\newcommand*{\VR}{\Vm^\residual}
-\newcommand*{\SR}{\Sm^\residual}
-\newcommand*{\URt}{\Ut^\residual}
-\newcommand*{\HRt}{\Ht^\residual}
-\newcommand*{\FRt}{\Ft^\residual}
-\newcommand*{\GRt}{\Gt^\residual}
-\newcommand*{\VRt}{\Vt^\residual}
-\newcommand*{\SRt}{\St^\residual}
-\newcommand*{\URs}{\Us^\residual}
-\newcommand*{\HRs}{\Hs^\residual}
-\newcommand*{\FRs}{\Fs^\residual}
-\newcommand*{\GRs}{\Gs^\residual}
-\newcommand*{\VRs}{\Vs^\residual}
-\newcommand*{\SRs}{\Ss^\residual}
-\newcommand*{\URpm}{\partialmolar{\internalenergy at symbol^\residual}}
-\newcommand*{\HRpm}{\partialmolar{\enthalpy at symbol^\residual}}
-\newcommand*{\FRpm}{\partialmolar{\Helmholtz at symbol^\residual}}
-\newcommand*{\GRpm}{\partialmolar{\Gibbs at symbol^\residual}}
-\newcommand*{\VRpm}{\partialmolar{\volume at symbol^\residual}}
-\newcommand*{\SRpm}{\partialmolar{\entropy at symbol^\residual}}
-\newcommand*{\UE}{\Um^\excess}
-\newcommand*{\FE}{\Fm^\excess}
-\newcommand*{\HE}{\Hm^\excess}
-\newcommand*{\GE}{\Gm^\excess}
-\newcommand*{\SE}{\Sm^\excess}
-\newcommand*{\VE}{\Vm^\excess}
-\newcommand*{\UEt}{\Ut^\excess}
-\newcommand*{\FEt}{\Ft^\excess}
-\newcommand*{\HEt}{\Ht^\excess}
-\newcommand*{\GEt}{\Gt^\excess}
-\newcommand*{\SEt}{\St^\excess}
-\newcommand*{\VEt}{\Vt^\excess}
-\newcommand*{\UEs}{\Us^\excess}
-\newcommand*{\FEs}{\Fs^\excess}
-\newcommand*{\HEs}{\Hs^\excess}
-\newcommand*{\GEs}{\Gs^\excess}
-\newcommand*{\SEs}{\Ss^\excess}
-\newcommand*{\VEs}{\Vs^\excess}
-\newcommand*{\UEpm}{\partialmolar{\internalenergy at symbol^\excess}}
-\newcommand*{\HEpm}{\partialmolar{\enthalpy at symbol^\excess}}
-\newcommand*{\FEpm}{\partialmolar{\Helmholtz at symbol^\excess}}
-\newcommand*{\GEpm}{\partialmolar{\Gibbs at symbol^\excess}}
-\newcommand*{\VEpm}{\partialmolar{\volume at symbol^\excess}}
-\newcommand*{\SEpm}{\partialmolar{\entropy at symbol^\excess}}
-\newcommand*{\sumall}{\@ifnextchar_\@sumall\@@sumall}
-\def\@sumall#1#2{\sum_{#2=1}^{\ncomponents}}
-\def\@@sumall#1{\sum_{#1=1}^{\ncomponents}}
-\newcommand*{\sumallbutlast}{\@ifnextchar_\@sumallbutlast\@@sumallbutlast}
-\def\@sumallbutlast#1#2{\sum_{#2=1}^{\ncomponents-1}}
-\def\@@sumallbutlast#1{\sum_{#1=1}^{\ncomponents-1}}
-\newcommand*{\prodall}{\@ifnextchar_\@prodall\@@prodall}
-\def\@prodall#1#2{\prod_{#2=1}^{\ncomponents}}
-\def\@@prodall#1{\prod_{#1=1}^{\ncomponents}}
-\newcommand*{\IG}{{\text{IG}}}
-\newcommand*{\IGM}{{\text{IGM}}}
-\newcommand*{\IS}{{\text{IS}}}
-\newcommand*{\Henryrat}{h}
-\newcommand*{\Henrymol}{{\mathcal{H}}}
+\NewExpandableDocumentCommand{\heatcapacitysymbol}{}{C}
+\NewExpandableDocumentCommand{\compressibilitysymbol}{}{\kappa}
+\NewExpandableDocumentCommand{\expansivitysymbol}{}{\alpha}
+\NewExpandableDocumentCommand{\JTsymbol}{}{\mu}
+\NewSubscriptedSymbol{\cV}{\__thermodynamics_intensive:n \heatcapacitysymbol}
+    {\g__thermodynamics_volume_symbol}
+\NewSubscriptedSymbol{\cP}{\__thermodynamics_intensive:n \heatcapacitysymbol}
+    {\g__thermodynamics_pressure_symbol}
+\NewSubscriptedSymbol{\cVt}{\__thermodynamics_extensive:n \heatcapacitysymbol}
+    {\g__thermodynamics_volume_symbol}
+\NewSubscriptedSymbol{\cPt}{\__thermodynamics_extensive:n \heatcapacitysymbol}
+    {\g__thermodynamics_pressure_symbol}
+\NewSubscriptedSymbol{\cVs}{\__thermodynamics_specific:n \heatcapacitysymbol}
+    {\g__thermodynamics_volume_symbol}
+\NewSubscriptedSymbol{\cPs}{\__thermodynamics_specific:n \heatcapacitysymbol}
+    {\g__thermodynamics_pressure_symbol}
+\NewSubscriptedSymbol{\kappaT}{\compressibilitysymbol}
+    {\g__thermodynamics_temperature_symbol}
+\NewSubscriptedSymbol{\kappaS}{\compressibilitysymbol}
+    {\g__thermodynamics_entropy_symbol}
+\NewSubscriptedSymbol{\alphaP}{\expansivitysymbol}{\g__thermodynamics_pressure_symbol}
+\NewSubscriptedSymbol{\alphaS}{\expansivitysymbol}{\g__thermodynamics_entropy_symbol}
+\NewSubscriptedSymbol{\muJT}{\JTsymbol}{JT}
+\NewDocumentCommand{\sat}{}{{\text{sat}}}
+\NewDocumentCommand{\Psat}{}{P\c_math_superscript_token\sat}
+\NewDocumentCommand{\Pvap}{}{\Psat}
+\NewDocumentCommand{\phisat}{}{\phi\c_math_superscript_token\sat}
+\NewDocumentCommand{\fsat}{}{\fpure\c_math_superscript_token\sat}
+\NewDocumentCommand{\std}{}{\circ}
+\NewDocumentCommand{\Pstd}{}{P\c_math_superscript_token \std}
+\NewDocumentCommand{\fstd}{}{f\c_math_superscript_token \std}
+\NewDocumentCommand{\mixing}{}{{\text{mix}}}
+\NewDocumentCommand{\Deltamix}{m}
+    {\Delta{#1}\c_math_subscript_token\mixing}
+\NewDocumentCommand{\fusion}{}{{\text{fus}}}
+\NewDocumentCommand{\reaction}{}{{\text{rxn}}}
+\NewDocumentCommand{\sublimation}{}{{\text{sub}}}
+\NewDocumentCommand{\vaporization}{}{{\text{vap}}}
+\NewDocumentCommand{\formation}{}{f}
+\NewDocumentCommand{\Deltafus}{m}
+    {\Delta #1\c_math_superscript_token\fusion}
+\NewDocumentCommand{\Deltasub}{m}
+    {\Delta #1\c_math_superscript_token\sublimation}
+\NewDocumentCommand{\Deltavap}{m}
+    {\Delta #1\c_math_superscript_token\vaporization}
+\NewDocumentCommand{\Deltarxn}{m}
+    {\Delta #1\c_math_subscript_token\reaction}
+\tl_new:N \l__thermodynamics_Deltaf_sym_tl
+\NewSubscriptedSymbol{\__thermodynamics_Deltaf}{\l__thermodynamics_Deltaf_sym_tl}{f}
+\NewDocumentCommand{\Deltaf}{m}
+{ \tl_set:Nn \l__thermodynamics_Deltaf_sym_tl {\Delta #1}
+  \__thermodynamics_Deltaf
+}
+\NewDocumentCommand{\fmix}{}{\hat{f}}
+\NewDocumentCommand{\phimix}{}{\hat\phi}
+\NewDocumentCommand{\fpure}{}{f}
+\NewDocumentCommand{\phipure}{}{\phi}
+\tl_new:N \l__thermodynamics_pm_symbol_tl
+\tl_new:N \l__thermodynamics_pm_arg_tl
+\NewDocumentCommand{\partialmolar}{m}
+{
+  \tl_set:Nn \l__thermodynamics_pm_symbol_tl {#1}
+  \__thermodynamics_generic_pm:
+}
+%% cases to consider:
+%% (1) \Mpm{i}
+%% (2) \Mpm[S]{i}
+%% (3) \Mpm^S_i
+%% (4) \Mpm_i^S
+%% (5) \Mpm_i
+%% note that \Mpm^S with no subscript makes no sense and is thus forbidden
+\cs_new:Nn \__thermodynamics_generic_pm:
+{
+  \peek_catcode_remove:NTF \c_math_subscript_token
+  {% case 4 or case 5
+    \__thermodynamics_pm_case_four_or_five
+  }
+  {% look for superscript token
+    \peek_catcode_remove:NTF \c_math_superscript_token
+    {% case 3: \Mpm^{#1}_{#2} or \Mpm^{#1}{#2}
+      \__thermodynamics_pm_case_three
+    }
+    {% Look for optional argument [...]
+      \peek_charcode:NTF [
+      {% case 2: \Mpm[S]{i}
+        \__thermodynamics_pm_case_two
+      }
+      {% case 1: \Mpm{i}
+        \__thermodynamics_pm_case_one
+      }
+    }
+  }
+}
+\cs_new:Npn \__thermodynamics_pm_case_one #1
+{
+  \__thermodynamics_overline:n {\l__thermodynamics_pm_symbol_tl\c_math_subscript_token{#1}}
+}
+\cs_new:Npn \__thermodynamics_pm_case_two [#1]#2
+{
+  \__thermodynamics_overline:n {\l__thermodynamics_pm_symbol_tl
+    \c_math_superscript_token{#1}\c_math_subscript_token{#2}}
+}
+\cs_new:Npn \__thermodynamics_pm_case_three #1
+{
+  \tl_set:Nn \l__thermodynamics_pm_arg_tl {#1}
+  \peek_catcode_remove:NTF \c_math_subscript_token
+  { \__thermodynamics_pm_case_three_part_two }
+  { \__thermodynamics_pm_case_three_part_two }
+}
+\cs_new:Npn \__thermodynamics_pm_case_three_part_two #1
+{
+  \__thermodynamics_overline:n {\l__thermodynamics_pm_symbol_tl
+    \c_math_superscript_token{\l__thermodynamics_pm_arg_tl}
+    \c_math_subscript_token{#1}}
+}
+\cs_new:Npn \__thermodynamics_pm_case_four_or_five #1
+{
+  \tl_set:Nn \l__thermodynamics_pm_arg_tl {#1}
+  \peek_catcode_remove:NTF \c_math_superscript_token
+  { \__thermodynamics_pm_case_four }
+  { \__thermodynamics_pm_case_five }
+}
+\cs_new:Npn \__thermodynamics_pm_case_four #1
+{
+  \__thermodynamics_overline:n {\l__thermodynamics_pm_symbol_tl\c_math_superscript_token{#1}
+    \c_math_subscript_token{\l__thermodynamics_pm_arg_tl}}
+}
+\cs_new:Npn \__thermodynamics_pm_case_five
+{
+  \__thermodynamics_overline:n {\l__thermodynamics_pm_symbol_tl
+    \c_math_subscript_token{\l__thermodynamics_pm_arg_tl}}
+}
+\NewDocumentCommand{\NewThermodynamicProperty}{m m}
+{
+  \NewExtensiveProperty{#1}{#2}
+  \NewPartialMolarProperty{#1}{#2}
+  \NewResidualProperty{#1}{#2}
+  \NewExcessProperty{#1}{#2}
+}
+\NewDocumentCommand{\NewExtensiveProperty}{m m}
+{
+  % Extensive property
+  \exp_after:wN \NewDocumentCommand \exp_after:wN
+    {\cs:w #1t\cs_end:}{}{\__thermodynamics_extensive:n {#2}}
+  % Molar property
+  \exp_after:wN \NewDocumentCommand \exp_after:wN
+    {\cs:w #1m\cs_end:}{}{\__thermodynamics_intensive:n {#2}}
+  % Specific property
+  \exp_after:wN \NewDocumentCommand \exp_after:wN
+    {\cs:w #1s\cs_end:}{}{\__thermodynamics_specific:n {#2}}
+}
+\NewDocumentCommand{\NewPartialMolarProperty}{m m}
+{
+  % Partial molar property
+  \exp_after:wN \NewDocumentCommand \exp_after:wN
+    {\cs:w #1pm\cs_end:}{}{\partialmolar{#2}}
+}
+\NewDocumentCommand{\NewExcessProperty}{m m}
+{
+  \exp_after:wN \NewSuperscriptedSymbol \exp_after:wN
+    {\cs:w #1 Et\cs_end:}{\__thermodynamics_extensive:n{#2}}{\excess}
+  \exp_after:wN \NewSuperscriptedSymbol \exp_after:wN
+    {\cs:w #1 E\cs_end:}{\__thermodynamics_intensive:n{#2}}{\excess}
+  \exp_after:wN \NewSuperscriptedSymbol \exp_after:wN
+    {\cs:w #1 Es\cs_end:}{\__thermodynamics_specific:n{#2}}{\excess}
+
+  %^^A TODO: make super- or subscripted partial molar quantities work
+  % Excess partial molar property
+  \exp_after:wN \NewDocumentCommand \exp_after:wN
+    {\cs:w #1Epm\cs_end:}{}{\partialmolar{#2}
+       \c_math_superscript_token\excess}
+}
+\NewDocumentCommand{\NewResidualProperty}{m m}
+{
+  \exp_after:wN \NewSuperscriptedSymbol \exp_after:wN
+    {\cs:w #1 Rt\cs_end:}{\__thermodynamics_extensive:n{#2}}{\residual}
+  \exp_after:wN \NewSuperscriptedSymbol \exp_after:wN
+    {\cs:w #1 R\cs_end:}{\__thermodynamics_intensive:n{#2}}{\residual}
+  \exp_after:wN \NewSuperscriptedSymbol \exp_after:wN
+    {\cs:w #1 Rs\cs_end:}{\__thermodynamics_specific:n{#2}}{\residual}
+
+  % Residual partial molar property
+  \exp_after:wN \NewDocumentCommand \exp_after:wN
+    {\cs:w #1Rpm\cs_end:}{}{\partialmolar{#2}
+        \c_math_superscript_token\residual}
+}
+\NewDocumentCommand{\Nt}{}{\g__thermodynamics_mole_symbol}
+\NewThermodynamicProperty{E}{\g__thermodynamics_total_energy_symbol}
+\NewThermodynamicProperty{U}{\g__thermodynamics_internal_energy_symbol}
+\NewThermodynamicProperty{F}{\g__thermodynamics_Helmholtz_symbol}
+\NewThermodynamicProperty{G}{\g__thermodynamics_Gibbs_symbol}
+\NewThermodynamicProperty{H}{\g__thermodynamics_enthalpy_symbol}
+\NewThermodynamicProperty{L}{\g__thermodynamics_Landau_symbol}
+\NewThermodynamicProperty{V}{\g__thermodynamics_volume_symbol}
+\NewThermodynamicProperty{S}{\g__thermodynamics_entropy_symbol}
+\NewExtensiveProperty{A}{\g__thermodynamics_area_symbol}
+\NewPartialMolarProperty{A}{\g__thermodynamics_area_symbol}
+\NewExtensiveProperty{Q}{\g__thermodynamics_heat_symbol}
+\NewExtensiveProperty{W}{\g__thermodynamics_work_symbol}
+\NewDocumentCommand{\cPpm}{}
+{
+  \cs_set:Npn \__thermodynamics_pm_case_one ##1
+  {
+    \__thermodynamics_overline:n {\l__thermodynamics_pm_symbol_tl\c_math_subscript_token
+        {\g__thermodynamics_pressure_symbol,##1}}
+  }
+  \cs_set:Npn \__thermodynamics_pm_case_two [##1]##2
+  {
+    \__thermodynamics_overline:n {\l__thermodynamics_pm_symbol_tl\c_math_superscript_token{##1}
+        \c_math_subscript_token{\g__thermodynamics_pressure_symbol,##2}}
+  }
+  \cs_set:Npn \__thermodynamics_pm_case_three_part_two ##1
+  {
+    \__thermodynamics_overline:n {\l__thermodynamics_pm_symbol_tl
+        \c_math_superscript_token{\l__thermodynamics_pm_arg_tl}
+        \c_math_subscript_token{\g__thermodynamics_pressure_symbol,##1}}
+  }
+  \cs_set:Npn \__thermodynamics_pm_case_four ##1
+  {
+    \__thermodynamics_overline:n {\l__thermodynamics_pm_symbol_tl
+        \c_math_superscript_token{##1}\c_math_subscript_token
+      {\g__thermodynamics_pressure_symbol,\l__thermodynamics_pm_arg_tl}}
+  }
+  \cs_set:Npn \__thermodynamics_pm_case_five
+  {
+    \__thermodynamics_overline:n {\l__thermodynamics_pm_symbol_tl\c_math_subscript_token
+        {\g__thermodynamics_pressure_symbol,\l__thermodynamics_pm_arg_tl}}
+  }
+  \partialmolar{\heatcapacitysymbol}
+}
+\NewDocumentCommand{\cVpm}{}
+{
+  \cs_set:Npn \__thermodynamics_pm_case_one ##1
+  {
+    \__thermodynamics_overline:n {\l__thermodynamics_pm_symbol_tl\c_math_subscript_token
+        {\g__thermodynamics_volume_symbol,##1}}
+  }
+  \cs_set:Npn \__thermodynamics_pm_case_two [##1]##2
+  {
+    \__thermodynamics_overline:n {\l__thermodynamics_pm_symbol_tl
+            \c_math_superscript_token{##1}\c_math_subscript_token
+        {\g__thermodynamics_volume_symbol,##2}}
+  }
+  \cs_set:Npn \__thermodynamics_pm_case_three_part_two ##1
+  {
+    \__thermodynamics_overline:n {\l__thermodynamics_pm_symbol_tl
+        \c_math_superscript_token{\l__thermodynamics_pm_arg_tl}
+        \c_math_subscript_token{\g__thermodynamics_volume_symbol,##1}}
+  }
+  \cs_set:Npn \__thermodynamics_pm_case_four ##1
+  {
+    \__thermodynamics_overline:n {\l__thermodynamics_pm_symbol_tl
+        \c_math_superscript_token{##1}
+        \c_math_subscript_token
+      {\g__thermodynamics_volume_symbol,\l__thermodynamics_pm_arg_tl}}
+  }
+  \cs_set:Npn \__thermodynamics_pm_case_five
+  {
+    \__thermodynamics_overline:n {\l__thermodynamics_pm_symbol_tl\c_math_subscript_token
+        {\g__thermodynamics_volume_symbol,\l__thermodynamics_pm_arg_tl}}
+  }
+  \partialmolar{\heatcapacitysymbol}
+}
+\NewDocumentCommand{\residual}{}{R}
+\NewDocumentCommand{\excess}{}{E}
+\NewDocumentCommand{\sumall}{m m}
+  { \sum\c_math_subscript_token{#2=1}
+      \c_math_superscript_token{\ncomponents} }
+\NewDocumentCommand{\sumallbutlast}{m m}
+  { \sum\c_math_subscript_token{#2=1}
+      \c_math_superscript_token{\ncomponents-1} }
+\NewDocumentCommand{\prodall}{m m}
+  { \prod\c_math_subscript_token{#2=1}
+       \c_math_superscript_token{\ncomponents} }
+\NewDocumentCommand{\IG}{}{{\text{IG}}}
+\NewDocumentCommand{\IGM}{}{{\text{IGM}}}
+\NewDocumentCommand{\IS}{}{{\text{IS}}}
+\NewDocumentCommand{\Henryrat}{}{h}
+\NewDocumentCommand{\Henrymol}{}{\mathcal{H}}
 \AtBeginDocument{%
   \providecommand*{\square}{%
     \text{\leavevmode
-      \hbox to.77778em{%
+      \hbox to.65em{%
       \hfil\vrule
-      \vbox to.6em{\hrule width.6em\vfil\hrule}%
+      \vbox to.53em{\hrule width.45em\vfil\hrule}%
       \vrule\hfil}%
     }%
   }%
 }
-\newcommand*{\gammarat}{\gamma^\ast}
-\newcommand*{\gammamol}{\gamma^\square}
-\newcommand*{\Jacobian}[4]{\frac{\partial{(#1,#2)}}{\partial{(#3,#4)}}}%
+\NewDocumentCommand{\gammarat}{}{\gamma\c_math_superscript_token\ast}
+\NewDocumentCommand{\gammamol}{}{\gamma\c_math_superscript_token\square}
+\NewDocumentEnvironment{thermovmatrix}{}
+{ \cs_if_exist:NTF \vmatrix
+  { \begin{vmatrix} }
+  { \left|\begin{array}{c c c c c c c c c c} }
+}
+{ \cs_if_exist:NTF \endvmatrix
+  {  \end{vmatrix} }
+  {  \end{array}\right| }
+}
+\NewDocumentCommand{\Jacobian}{m m}
+    {\__thermodynamics_frac:nn{\partial(#1)}{\partial{(#2)}}}
+\NewDocumentCommand{\Jacobiandet}{O{} O{} m m}
+{
+  \__thermodynamics_Jacobian_set_ncomponents:nn {#3} {#4}
+  \begin{thermovmatrix}
+    \__thermodynamics_Jacobianmatrix:nnnn {#1} {#2} {#3} {#4}
+  \end{thermovmatrix}
+}
+\seq_new:N \l__thermodynamics_row_seq
+\seq_new:N \l__thermodynamics_matrix_seq
+\clist_new:N \l__thermodynamics_other_vars_clist
+\clist_new:N \l__thermodynamics_other_vars_copy_clist
+\tl_new:N \l__thermodynamics_Jacobian_x_tl
+\tl_new:N \l__thermodynamics_Jacobian_n_tl
+\tl_new:N \l__thermodynamics_Jacobian_temp_tl
+\bool_new:N \l__thermodynamics_found_dots_bool
+\cs_new:Nn \__thermodynamics_Jacobian_set_ncomponents:nn
+{
+  % If any entry is \dots, we assume the Jacobian is of the form
+  % d(f_1,\dots,f_n)/d(x_1,\dots,x_n) where f is some function
+  % (any symbol) and x is some variable (any symbol).
+  \tl_if_in:nnTF {#1} {\dots}
+  {% Has dots
+    \bool_set_true:N \l__thermodynamics_found_dots_bool
+    % look for what "x" is
+    \tl_set:Nn \l__thermodynamics_Jacobian_x_tl {\tl_head:n {#2}}
+    % look for what "n" is and set \ncomponents to it
+    \tl_set:Nx \l__thermodynamics_Jacobian_n_tl {\tl_item:nn {#2} {-1}}
+    \RenewExpandableDocumentCommand{\ncomponents}{}{\l__thermodynamics_Jacobian_n_tl}
+  }
+  {% Does not have dots; proceed accordingly
+    \bool_set_false:N \l__thermodynamics_found_dots_bool
+  }
+}
+\cs_new_protected:Nn \__thermodynamics_Jacobianmatrix:nnnn
+{
+  \seq_clear:N \l__thermodynamics_matrix_seq
+  \clist_set:Nn \l__thermodynamics_other_vars_clist {#4}
+  \clist_set_eq:NN \l__thermodynamics_other_vars_copy_clist \l__thermodynamics_other_vars_clist
+
+  \clist_map_inline:nn {#3}
+  {
+    \seq_clear:N \l__thermodynamics_row_seq
+    \tl_if_in:nnTF {##1} {\dots}
+    {% The current row has "dots" => row is \vdots && \vdots
+      \seq_put_right:Nn \l__thermodynamics_matrix_seq
+        { \vdots \c_alignment_token \c_alignment_token \vdots }
+    }
+    {% Ordinary row
+      \clist_map_inline:nn {#4}
+      {
+        \tl_if_in:nnTF {####1} {\dots}
+        {% this column has "dots" in it
+          \seq_put_right:Nn \l__thermodynamics_row_seq \dots
+        }
+        {% Normal column
+          \clist_set_eq:NN \l__thermodynamics_other_vars_clist
+                           \l__thermodynamics_other_vars_copy_clist
+          \clist_remove_all:Nn \l__thermodynamics_other_vars_clist {####1}
+          \bool_if:NTF \l__thermodynamics_found_dots_bool
+          { \tl_set:Nn \l__thermodynamics_Jacobian_temp_tl {\tl_item:nn {####1} {-1}}
+            \seq_put_right:Nx \l__thermodynamics_row_seq
+            {
+              #1\Partial{##1}{####1}
+                  {\allbut{\l__thermodynamics_Jacobian_temp_tl}{\l__thermodynamics_Jacobian_x_tl}}
+            }
+          }
+          { \seq_put_right:Nx \l__thermodynamics_row_seq
+            {
+              #1\Partial{##1}{####1}
+                        {\clist_use:Nn \l__thermodynamics_other_vars_clist ,}
+            }
+          }
+        }
+      }
+      \seq_put_right:Nx \l__thermodynamics_matrix_seq
+      {
+        \seq_use:Nn \l__thermodynamics_row_seq { \c_alignment_token }
+      }
+    }
+  }
+  \tl_if_empty:nTF {#2}
+  {
+    \tl_if_eq:nnTF {#1} {\displaystyle}
+    { \seq_use:Nn \l__thermodynamics_matrix_seq { \\[2.75ex] } }
+    { \seq_use:Nn \l__thermodynamics_matrix_seq { \\[1.25ex] } }
+  }
+  {
+    \seq_use:Nn \l__thermodynamics_matrix_seq { \\[#2] }
+  }
+}
 \endinput
 %%
 %% End of file `thermodynamics.sty'.



More information about the tex-live-commits mailing list.