\ProvidesPackage{physics-patch}
% physics-patch 1.0
% Patches for physics package and integration of physics and siunitx packages
% Author: Willie Shen (Willie169)
% Repository: https://github.com/Willie169/physics-patch
% Last update: Feb 13, 2025
%
% The physics-patch package fixes issues in the physics package and improves compatibility between physics and siunitx
% It provides improved versions of \qty, \dv, and \pdv and introduces new macros
%
% This package requires xparse, etoolbox, and amsmath package
% Optionally, load physics and/or siunitx optionally before this package
% By default, physics-patch overrides \qty with an improved version. To disable this, use the nooverride option
%
% This package is released under the LaTeX Project Public License (LPPL) 1.3c
% See https://www.latex-project.org/lppl/lppl-1-3c for the details of that license
% Some parts of this package are modified from the physics package, created by Sergio C. de la Barrera and licenced under LPPL 1.3
% See https://ctan.org/pkg/physics for the details of that package

\RequirePackage{xparse}
\RequirePackage{etoolbox}
\RequirePackage{amsmath}

% override: override \qty to \patchedqty (default)
% nooverride: not override \qty to \patchedqty
\newif\ifoverride
\DeclareOption{override}{\overridetrue}
\DeclareOption{nooverride}{\overridefalse}
\ExecuteOptions{override}
\ProcessOptions\relax

\DeclareDocumentCommand{\patchedphysicsquantity}{ t\big t\Big t\bigg t\Bigg o d() d|| g }
{ % Flexible automatic bracketing of an expression in () or [] or {} or ||
  % Handles manual override of sizing
  \IfBooleanTF{#1}{\let\ltag\bigl \let\rtag\bigr}{
    \IfBooleanTF{#2}{\let\ltag\Bigl \let\rtag\Bigr}{
      \IfBooleanTF{#3}{\let\ltag\biggl \let\rtag\biggr}{
        \IfBooleanTF{#4}{\let\ltag\Biggl \let\rtag\Biggr}{\let\ltag\left \let\rtag\right}
      }
    }
  }
  % Handles actual bracketing
  \IfNoValueTF{#5}{
    \IfNoValueTF{#6}{
      \IfNoValueTF{#7}{
        \IfNoValueTF{#8}{
          \IfBooleanTF{#1}{\big}{
            \IfBooleanTF{#2}{\Big}{
              \IfBooleanTF{#3}{\bigg}{
                \IfBooleanTF{#4}{\Bigg}{}
              }
            }
          }
        }
        {\ltag\lbrace#8\rtag\rbrace}
      }{
        \ltag\lvert{#7}\rtag\rvert
        \IfNoValueTF{#8}{}{#8}
      }
    }{
        \ltag(#6\rtag)
        \IfNoValueTF{#7}{}{|#7|}
        \IfNoValueTF{#8}{}{#8}
    }
  }{
    \ltag[#5\rtag]
    \IfNoValueTF{#6}{}{(#6)}
    \IfNoValueTF{#7}{}{|#7|}
    \IfNoValueTF{#8}{}{#8}
  }
}
\let\ppqty\patchedphysicsquantity
\IfPackageLoadedTF{siunitx}
{
  \DeclareDocumentCommand\siqty{o m m}{
    \IfValueTF{#1}{\SI[#1]{#2}{#3}}{\SI{#2}{#3}}
  }
  \DeclareDocumentCommand{\integratedquantity}{ t\big t\Big t\bigg t\Bigg o d() d|| g g }
  { % integrate \qty from physics and \qty from siunitx
    \IfValueTF{#9}
    { % \qty from siunitx
      \IfValueTF{#5}
      {\siqty[#5]{#8}{#9}}
      {\siqty{#8}{#9}}
    }{ % \qty from physics
      % Handles manual override of sizing
      \IfBooleanTF{#1}{\let\ltag\bigl \let\rtag\bigr}{
        \IfBooleanTF{#2}{\let\ltag\Bigl \let\rtag\Bigr}{
          \IfBooleanTF{#3}{\let\ltag\biggl \let\rtag\biggr}{
            \IfBooleanTF{#4}{\let\ltag\Biggl \let\rtag\Biggr}{\let\ltag\left \let\rtag\right}
          }
        }
      }
      % Handles actual bracketing
      \IfNoValueTF{#5}{
        \IfNoValueTF{#6}{
          \IfNoValueTF{#7}{
            \IfNoValueTF{#8}{
              \IfBooleanTF{#1}{\big}{
                \IfBooleanTF{#2}{\Big}{
                  \IfBooleanTF{#3}{\bigg}{
                    \IfBooleanTF{#4}{\Bigg}{}
                  }
                }
              }
            }
            {\ltag\lbrace#8\rtag\rbrace}
          }{
            \ltag\lvert{#7}\rtag\rvert
            \IfNoValueTF{#8}{}{#8}
          }
        }{
            \ltag(#6\rtag)
            \IfNoValueTF{#7}{}{|#7|}
            \IfNoValueTF{#8}{}{#8}
        }
      }{
        \ltag[#5\rtag]
        \IfNoValueTF{#6}{}{(#6)}
        \IfNoValueTF{#7}{}{|#7|}
        \IfNoValueTF{#8}{}{#8}
      }
    }
  }
  \let\patchedquantity\integratedquantity
  \let\iqty\integratedquantity
}{
  \let\patchedquantity\patchedphysicsquantity
}
\let\ptqty\patchedquantity
\ifoverride\let\qty\patchedquantity\fi
\DeclareDocumentCommand\derivative{ s o m g d() }
{ % Total derivative
  % s: star for \flatfrac flat derivative
  % o: optional n for nth derivative
  % m: mandatory (x in df/dx)
  % g: optional (f in df/dx)
  % d: long-form d/dx(...)
  \IfBooleanTF{#1}
  {\let\fractype\flatfrac}
  {\let\fractype\frac}
  \IfNoValueTF{#4}
  {
    \IfNoValueTF{#5}
    {\fractype{\diffd \IfNoValueTF{#2}{}{^{#2}}}{\diffd #3\IfNoValueTF{#2}{}{^{#2}}}}
    {\fractype{\diffd \IfNoValueTF{#2}{}{^{#2}}}{\diffd #3\IfNoValueTF{#2}{}{^{#2}}} \argopen(#5\argclose)}
  }
  {\fractype{\diffd \IfNoValueTF{#2}{}{^{#2}} #3}{\diffd #4\IfNoValueTF{#2}{}{^{#2}}}}
  \IfNoValueTF{#5}{}{\argopen(#5\argclose)}
}
\let\dv\derivative
\DeclareDocumentCommand\partialderivative{ s o m g g d() }
{ % Partial derivative
  % s: star for \flatfrac flat derivative
  % o: optional n for nth derivative
  % m: mandatory (x in df/dx)
  % g: optional (f in df/dx)
  % g: optional (y in d^2f/dxdy)
  % d: long-form d/dx(...)
  \IfBooleanTF{#1}
  {\let\fractype\flatfrac}
  {\let\fractype\frac}
  \IfNoValueTF{#4}
  {
    \IfNoValueTF{#6}
    {\fractype{\partial \IfNoValueTF{#2}{}{^{#2}}}{\partial #3\IfNoValueTF{#2}{}{^{#2}}}}
    {\fractype{\partial \IfNoValueTF{#2}{}{^{#2}}}{\partial #3\IfNoValueTF{#2}{}{^{#2}}} \argopen(#6\argclose)}
  }
  {
    \IfNoValueTF{#5}
    {\fractype{\partial \IfNoValueTF{#2}{}{^{#2}} #3}{\partial #4\IfNoValueTF{#2}{}{^{#2}}}}
    {\fractype{\partial^2 #3}{\partial #4 \partial #5}}
    \IfNoValueTF{#6}{}{\argopen(#6\argclose)}
  }
}
\let\pdv\partialderivative