% \iffalse meta-comment
%
% File: siunitx.dtx Copyright (C) 2008-2019,2021-2026 Joseph Wright
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
% license or (at your option) any later version.  The latest version
% of this license is in the file
%
%    https://www.latex-project.org/lppl.txt
%
% This file is part of the "siunitx bundle" (The Work in LPPL)
% and all files in that bundle must be distributed together.
%
% The released version of this bundle is available from CTAN.
%
% -----------------------------------------------------------------------
%
% The development version of the bundle can be found at
%
%    https://github.com/josephwright/siunitx
%
% for those people who are interested.
%
% -----------------------------------------------------------------------
%
%<*driver>
\documentclass{l3doc}
% Additional commands needed in this source
\ProvideDocumentCommand\email{m}{\href{mailto:#1}{\nolinkurl{#1}}}
\ProvideDocumentCommand\version{m}{\ensuremath{#1}}
% Tidy up the above in bookmarks
\makeatletter
\pdfstringdefDisableCommands{%
  \let\version\@firstofone
}
\makeatother
% The next line is needed so that \GetFileInfo will be able to pick up
% version data
\usepackage{siunitx}
\begin{document}
  \DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
%
% \GetFileInfo{siunitx.sty}
%
% \title{^^A
%   \pkg{siunitx} -- Overall set up^^A
%   \thanks{This file describes \fileversion,
%     last revised \filedate.}^^A
% }
%
% \author{^^A
%  Joseph Wright^^A
%  \thanks{^^A
%    E-mail:
%    \email{joseph@texdev.net}^^A
%   }^^A
% }
%
% \date{Released \filedate}
%
% \maketitle
%
% \begin{documentation}
%
% ^^A API documentation is given on a per-module basis:
% ^^A see the siunitx-<module>.dtx files
%
% \end{documentation}
%
% \begin{implementation}
%
% \section{\pkg{siunitx} implementation}
%
% Start the \pkg{DocStrip} guards.
%    \begin{macrocode}
%<*package>
%    \end{macrocode}
%
% Identify the internal prefix.
%    \begin{macrocode}
%<@@=siunitx>
%    \end{macrocode}
%
%    \begin{macrocode}
%<*init>
%    \end{macrocode}
%
% \subsection{Provide a kernel command}
%
% \begin{macro}{\IfFormatAtLeastTF}
%   Not present in older kernels: use the \LaTeXe{} mechanism as this is correct
%   for this case.
%    \begin{macrocode}
\providecommand\IfFormatAtLeastTF{\@ifl@t@r\fmtversion}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Initial set up}
%
%    \begin{macrocode}
\IfFormatAtLeastTF{2022-11-01}
  {}
  {%
    \PackageError{siunitx}{LaTeX kernel too old}
      {%
        You need a newer LaTeX to use this release of siunitx.\MessageBreak
        Loading~siunitx~will~abort!%
      }%
    \endinput
  }
%    \end{macrocode}
%
% Allow rollback to version~\version{2}: if we need to, version~\version{1}
% could eventually be added here too.
%    \begin{macrocode}
\DeclareRelease{2}{2010-05-23}{siunitx-v2.sty}
\DeclareRelease{v2}{2010-05-23}{siunitx-v2.sty}
\DeclareCurrentRelease{}{2021-05-17}
%    \end{macrocode}
%
% Make sure that the version of \pkg{l3kernel} in use is sufficiently new.
% We use \cs{ExplFileDate} as \cs{@ifpackagelater} doesn't work for pre-loaded
% \pkg{expl3} in the absence of the package.
%    \begin{macrocode}
\@ifl@t@r\ExplLoaderFileDate{2023-10-10}
  {}
  {%
    \PackageError{siunitx}{Support package expl3 too old}
      {%
        You need to update your installation of 'l3kernel'.\MessageBreak
        Loading~siunitx~will~abort!%
      }%
    \endinput
  }%
%    \end{macrocode}
%
% Identify the package and give the over all version information.
%    \begin{macrocode}
\ProvidesExplPackage {siunitx} {2026-04-15} {3.5.4}
  {A comprehensive (SI) units package}
%    \end{macrocode}
%
% \subsection{Safety checks}
%
% \begin{macro}{\@@_load_check:}
%   There are a number of packages that are incompatible with \pkg{siunitx}
%   as they cover the same concepts and in some cases define the same command
%   names. These are all tested at the point of loading to try to trap
%   issues, and a couple are also tested later as it's possible for them to
%   load without an obvious error if \pkg{siunitx} was loaded first.
%    \begin{macrocode}
\msg_new:nnnn { siunitx } { incompatible-package }
  { Package~'#1'~incompatible. }
  { The~#1~package~and~siunitx~are~incompatible. }
\cs_new_protected:Npn \@@_load_check:n #1
  {
    \@ifpackageloaded {#1}
      { \msg_error:nne { siunitx } { incompatible-package } {#1} }
      { }
  }
\clist_map_function:nN
  { SIunits , sistyle , units , unitsdef , fancyunits }
  \@@_load_check:n
\AtBeginDocument
  {
    \clist_map_function:nN { SIunits , sistyle , units }
      \@@_load_check:n
  }
%    \end{macrocode}
%\end{macro}
%
% \subsection{Top-level scratch space}
%
% \begin{macro}{\l_@@_tmp_tl}
%   Scratch space for the interfaces.
%    \begin{macrocode}
\tl_new:N \l_@@_tmp_tl
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
%</init>
%    \end{macrocode}
%
%    \begin{macrocode}
%<*options>
%    \end{macrocode}
%
% \subsection{Load time options}
%
% \begin{variable}
%   {
%     \l_@@_v2_options_bool ,
%     \l_@@_v2_cmds_bool    ,
%     \l_@@_list_tl         ,
%     \l_@@_product_tl      ,
%     \l_@@_column_type_tl
%   }
%    \begin{macrocode}
\keys_define:nn { siunitx }
  {
    disable-deprecated-options .bool_set:N =
      \l_@@_disable_options_bool ,
    disable-deprecated-options .usage:n =
      load ,
    disable-deprecated-commands .bool_set:N =
      \l_@@_disable_cmds_bool ,
    disable-deprecated-commands .usage:n =
      load ,
    list-input-separator .tl_set:N =
      \l_@@_list_tl ,
    list-input-separator .usage:n =
      load ,
    product-input-separator .tl_set:N =
      \l_@@_product_tl ,
    product-input-separator .usage:n =
      load ,
    table-column-type .tl_set:N =
      \l_@@_column_type_tl ,
    table-column-type .usage:n =
      load
  }
\keys_set:nn { siunitx }
  {
    disable-deprecated-options  = false ,
    disable-deprecated-commands = false ,
    list-input-separator        = ; ,
    product-input-separator     = x ,
    table-column-type           = S 
  }
%    \end{macrocode}
% \end{variable}
%
% \subsection{Option handling}
%
% Some messages.
%    \begin{macrocode}
\msg_new:nnn { siunitx } { option-deprecated }
  {
    Option~"#1"~has~been~deprecated~in~this~release.\\ \\
    Use~"#2"~as~a~replacement.
  }
%    \end{macrocode}
%
% \begin{variable}{\g_@@_deprecated_seq}
%   Used to avoid repeatedly warning about deprecated options: needed at the
%   top level.
%    \begin{macrocode}
\seq_new:N \g_@@_deprecated_seq
%    \end{macrocode}
% \end{variable}
%
% \begin{macro}{\@@_deprecated_info:nn}
%   To avoid repeated messages.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_deprecated_info:nn #1#2
  {
    \seq_if_in:NnF \g_@@_deprecated_seq {#1}
      { \msg_info:nnnn { siunitx } { option-deprecated } {#1} {#2} }
    \seq_gput_right:Nn \g_@@_deprecated_seq {#1}
  }
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
\ProcessKeyOptions
%    \end{macrocode}
%
% \begin{macro}{\@@_option_deprecated:nn}
% \begin{macro}{\@@_option_deprecated:nnn}
%   Rather than list all of the older options, simply redirect to a warning.
%    \begin{macrocode}
\bool_if:NT \l_@@_disable_options_bool
  {
    \cs_set_protected:Npn \@@_option_deprecated:nn #1#2
      { \@@_option_removed:n {#1} }
    \cs_set_protected:Npn \@@_option_deprecated:nnn #1#2#3
      { \@@_option_removed:n {#1} }
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%    \begin{macrocode}
%</options>
%    \end{macrocode}
%
% \subsection{User interfaces}
%
%    \begin{macrocode}
%<*interfaces>
%    \end{macrocode}
%
% The user interfaces are defined in terms of documented code-level ones.
% This is all done here, and will appear in the \file{.sty} file before the
% relevant code. Things could be re-arranged by \pkg{DocStrip} but there is no
% advantage.
%
% \subsubsection{Preamble commands}
%
% \begin{macro}
%   {
%     \DeclareSIPower     ,
%     \DeclareSIPrefix    ,
%     \DeclareSIQualifier ,
%     \DeclareSIUnit
%   }
%   Pass data to the code layer.
%    \begin{macrocode}
\NewDocumentCommand \DeclareSIPower { +m +m m }
  {
    \siunitx_declare_power:NNn #1 #2 {#3}
  }
\NewDocumentCommand \DeclareSIPrefix { +m m m }
  {
    \siunitx_declare_prefix:Nnn #1 {#3} {#2}
  }
\NewDocumentCommand \DeclareSIQualifier { +m m }
  {
    \siunitx_declare_qualifier:Nn #1 {#2}
  }
\NewDocumentCommand \DeclareSIUnit { o +m m }
  {
    \IfNoValueTF {#1}
      { \siunitx_declare_unit:Nn #2 {#3} }
      { \siunitx_declare_unit:Nnn #2 {#3} {#1} }
  }
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{Document commands}
%
% \begin{macro}{\qty}
%    \begin{macrocode}
\AtBeginDocument
  {
    \@ifpackageloaded { physics }
      {
        \msg_new:nnn { siunitx } { physics-pkg }
          {
            Detected~the~"physics"~package: \\
            omitting~definition~of~\token_to_str:N \qty.
            \\ \\
            If~you~want~to~use~\qty with~the~siunitx~definition,~add~
            \\ \\
            \iow_indent:n
              {
                \token_to_str:N \AtBeginDocument
                  { 
                    \token_to_str:N \RenewCommandCopy
                      \token_to_str:N \qty \token_to_str:N \SI
                  }
              }
            \\ \\
            to~your~preamble.
          }
        \msg_warning:nn { siunitx } { physics-pkg }
      }
      { }
  }
\@ifpackageloaded { physics }
  { \use_none:nnnn }
  { }
\NewDocumentCommand \qty { O { } m > { \TrimSpaces } m }
  {
    \mode_leave_vertical:
    \group_begin:
      \siunitx_unit_options_apply:n {#3}
      \keys_set:nn { siunitx } {#1}
      \siunitx_quantity:nn {#2} {#3}
    \group_end:
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ang, \duration, \num, \unit}
%   All of a standard form: start a paragraph (if required), set local
%   key values, do the formatting, print the result.
%    \begin{macrocode}
\NewDocumentCommand \ang { O { } > { \SplitArgument { 2 } { ; } } m }
  {
    \mode_leave_vertical:
    \group_begin:
      \keys_set:nn { siunitx } {#1}
      \@@_angle:nnn #2
    \group_end:
  }
\NewDocumentCommand \duration { O { } > { \SplitArgument { 2 } { ; } } m }
  {
    \mode_leave_vertical:
    \group_begin:
      \keys_set:nn { siunitx } {#1}
      \@@_duration:nnn #2
    \group_end:
  }
\NewDocumentCommand \num { O { } m }
  {
    \mode_leave_vertical:
    \group_begin:
      \keys_set:nn { siunitx } {#1}
      \siunitx_number_format:nN {#2} \l_@@_tmp_tl
      \siunitx_print_number:V \l_@@_tmp_tl
    \group_end:
  }
\NewDocumentCommand \unit { O { } > { \TrimSpaces } m }
  {
    \mode_leave_vertical:
    \group_begin:
      \siunitx_unit_options_apply:n {#2}
      \keys_set:nn { siunitx } {#1}
      \siunitx_unit_format:nN {#2} \l_@@_tmp_tl
      \siunitx_print_unit:V \l_@@_tmp_tl
    \group_end:
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}
%   {\qtylist, \numlist, \qtyproduct, \numproduct, \qtyrange, \numproduct}
%   Interfaces for compound values.
%    \begin{macrocode}
\ExpandArgs { Ne } \NewDocumentCommand \qtylist
  {
    O { }
    > { \SplitList { \exp_not:V \l_@@_list_tl } } m
    > { \TrimSpaces } m
  }
  {
    \mode_leave_vertical:
    \group_begin:
      \siunitx_unit_options_apply:n {#3}
      \keys_set:nn { siunitx } {#1}
      \siunitx_quantity_list:nn {#2} {#3}
    \group_end:
  }
\ExpandArgs { Ne } \NewDocumentCommand \numlist
  {
    O { }
    > { \SplitList { \exp_not:V \l_@@_list_tl } } m
  }
  {
    \mode_leave_vertical:
    \group_begin:
      \keys_set:nn { siunitx } {#1}
      \siunitx_number_list:n {#2}
    \group_end:
  }
\ExpandArgs { Ne } \NewDocumentCommand \qtyproduct
  {
    O { }
    > { \SplitList { \exp_not:V \l_@@_product_tl } } m
    > { \TrimSpaces } m
  }
  {
    \mode_leave_vertical:
    \group_begin:
      \siunitx_unit_options_apply:n {#3}
      \keys_set:nn { siunitx } {#1}
      \siunitx_quantity_product:nn {#2} {#3}
    \group_end:
  }
\ExpandArgs { Ne } \NewDocumentCommand \numproduct
  {
    O { }
    > { \SplitList { \exp_not:V \l_@@_product_tl } } m
  }
  {
    \mode_leave_vertical:
    \group_begin:
      \keys_set:nn { siunitx } {#1}
      \siunitx_number_product:n {#2}
    \group_end:
  }
\NewDocumentCommand \qtyrange { O { } m m > { \TrimSpaces } m }
  {
    \mode_leave_vertical:
    \group_begin:
      \siunitx_unit_options_apply:n {#4}
      \keys_set:nn { siunitx } {#1}
      \siunitx_quantity_range:nnn {#2} {#3} {#4}
    \group_end:
  }
\NewDocumentCommand \numrange { O { } m m }
  {
    \mode_leave_vertical:
    \group_begin:
      \keys_set:nn { siunitx } {#1}
      \siunitx_number_range:nn {#2} {#3}
    \group_end:
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\complexnum, \complexqty}
%   Interfaces for complex numbers.
%    \begin{macrocode}
\ExpandArgs { Ne } \NewDocumentCommand \complexnum
  { O { } > { \SplitArgument { 1 } { \c_colon_str } } m }
  {
    \mode_leave_vertical:
    \group_begin:
      \keys_set:nn { siunitx } {#1}
      \@@_complex_number_aux:nn #2
    \group_end:
  }
\ExpandArgs { Ne } \NewDocumentCommand \complexqty
  { O { } > { \SplitArgument { 1 } { \c_colon_str } } m  m }
  {
    \mode_leave_vertical:
    \group_begin:
      \siunitx_unit_options_apply:n {#3}
      \keys_set:nn { siunitx } {#1}
      \@@_complex_quantity_aux:nnn #2 {#3}
    \group_end:
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\tablenum}
%   Slightly odd set up at present: we have to have the |\ignorespaces|.
%    \begin{macrocode}
\NewDocumentCommand \tablenum { O { } m }
  {
    \mode_leave_vertical:
    \group_begin:
      \keys_set:nn { siunitx } {#1}
      \siunitx_cell_begin:w
        \ignorespaces #2
      \siunitx_cell_end:
    \group_end:
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\sisetup}
%   A very thin wrapper.
%    \begin{macrocode}
\NewDocumentCommand \sisetup { m }
  { \keys_set:nn { siunitx } {#1} }
%    \end{macrocode}
% \end{macro}
%
% \subsection{\enquote{Glue} commands}
%
% \begin{macro}{\@@_angle:nnn, \@@_duration:nnn}
%   The document level interface for \cs{ang} and \cs{duration} need some
%   \enquote{glue} to work with the code-level API.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_angle:nnn #1#2#3
  {
    \tl_if_novalue:nTF {#2}
      { \siunitx_angle:n {#1} }
      {
        \tl_if_novalue:nTF {#3}
          { \siunitx_angle:nnn {#1} {#2} { } }
          { \siunitx_angle:nnn {#1} {#2} {#3} }
      }
  }
\cs_new_protected:Npn \@@_duration:nnn #1#2#3
  {
    \tl_if_novalue:nTF {#2}
      { \siunitx_duration:n {#1} }
      {
        \tl_if_novalue:nTF {#3}
          { \siunitx_duration:nnn {#1} {#2} { } }
          { \siunitx_duration:nnn {#1} {#2} {#3} }
      }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_complex_number_aux:nn}
% \begin{macro}{\@@_complex_quantity_aux:nnn}
%   The same idea for complex values.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_complex_number_aux:nn #1#2
  {
    \tl_if_novalue:nTF {#2}
      { \siunitx_complex_number:n {#1} }
      { \siunitx_complex_number:nn {#1} {#2} }
  }
\cs_new_protected:Npn \@@_complex_quantity_aux:nnn #1#2#3
  {
    \tl_if_novalue:nTF {#2}
      { \siunitx_complex_quantity:nn {#1} {#3} }
      { \siunitx_complex_quantity:nnn {#1} {#2} {#3} }
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \subsection{Table column}
%
% User interfaces in tabular constructs are provided using the mechanisms from
% the \pkg{array} package.
%    \begin{macrocode}
\RequirePackage { array }
%    \end{macrocode}
%
% \begin{macro}{\@@_declare_column:Nnn}
%   Creating numerical columns requires that these are declared before anything
%   else in \cs{NC@list}: this is necessary to work with optional arguments.
%   This means a bit of manual effort after the simple declaration of a new
%   column type.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_declare_column:Nnn #1#2#3
  {
    \cs_if_exist:cT { NC@find@ #1 }
      {
        \cs_undefine:c { NC@find@ #1 }
        \cs_set_protected:Npn \@@_tmp:w ##1 \NC@do #1 ##2 \q_stop
          { \NC@list {##1##2} }
        \exp_after:wN \@@_tmp:w \the \NC@list \q_stop
        \msg_warning:nnn { siunitx } { column-overwritten } {#1}
      }
    \newcolumntype {#1} { }
    \cs_set_protected:Npn \@@_tmp:w \NC@do ##1##2 \NC@do #1
      { \NC@list { \NC@do ##1 \NC@do #1 ##2 } }
    \exp_after:wN \@@_tmp:w \the \NC@list
    \ExpandArgs { Nc } \renewcommand * { NC@rewrite@ #1 } [ 1 ] [ ]
      {
        \@temptokena \expandafter
          {
            \the \@temptokena
            > {#2} c < {#3}
          }
        \NC@find
      }
  }
\msg_new:nnn { siunitx } { column-overwritten }
  { Tabular~column~type~"#1"~overwritten~with~siunitx~definition. }
%    \end{macrocode}
%   When \pkg{mdwtab} is loaded the syntax required is slightly different.
%    \begin{macrocode}
\AtBeginDocument
  {
    \@ifpackageloaded { mdwtab }
      {
        \cs_set_protected:Npn \@@_declare_column:Nnn #1#2#3
          {
            \cs_if_exist:cT { NC@find@ #1 }
               {
                 \cs_undefine:c { NC@find@ #1 }
                 \msg_warning:nnn { siunitx } { column-overwritten } {#1}
               }
            \newcolumntype {#1} [ 1 ] [ ]
              { > {#2} c < {#3} }
           }
      }
      { }
    \tl_map_inline:Nn \l_@@_column_type_tl
      {
        \@@_declare_column:Nnn #1
          {
            \keys_set:nn { siunitx } {##1}
            \siunitx_cell_begin:w
          }
          { \siunitx_cell_end: }
      }
  }
%    \end{macrocode}
% \end{macro}
%
% \subsection{Document commands in bookmarks}
%
% In bookmarks, the \pkg{siunitx} document commands need to produce simple
% strings that represent their input as far as possible.
%
% \begin{macro}{\@@_bookmark_cmd:Nn}
%   To keep things fast, expandable versions of the document command are
%   created only once. As here we are at the top-level for internal names,
%   we can use the various parts of \pkg{siunitx-compound} that would otherwise
%   be inaccessible.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_bookmark_cmd:Nnn #1#2#3
  {
    \ExpandArgs { c } \DeclareExpandableDocumentCommand
      { \cs_to_str:N #1 \c_space_tl ( pdfstring ~ context ) }
      {#2} {#3}
  }
\@@_bookmark_cmd:Nnn \qty { o m m } { #2 ~ #3 }
\@@_bookmark_cmd:Nnn \ang { m } { \@@_angle:n {#1} }
\@@_bookmark_cmd:Nnn \duration { m } { \@@_duration:n {#1} }
\@@_bookmark_cmd:Nnn \num { o m } { #2 }
\@@_bookmark_cmd:Nnn \unit { o m } { #2 }
\@@_bookmark_cmd:Nnn \numlist { o m }
  {
    \@@_list_use:nnVVV {#2} { }
      \l_siunitx_list_separator_pair_tl
      \l_siunitx_list_separator_tl
      \l_siunitx_list_separator_final_tl
  }
\@@_bookmark_cmd:Nnn \qtylist { o m m }
  {
    \@@_list_use:nnVVV {#2} {#3}
      \l_siunitx_list_separator_pair_tl
      \l_siunitx_list_separator_tl
      \l_siunitx_list_separator_final_tl
  }
\@@_bookmark_cmd:Nnn \numproduct { o m } { }
\@@_bookmark_cmd:Nnn \qtyproduct { o m m } { }
\@@_bookmark_cmd:Nnn \numrange { o m m }
  { #2 \tl_use:N \l_siunitx_range_phrase_tl #3 }
\@@_bookmark_cmd:Nnn \qtyrange { o m m m }
  { #2 ~ #4 \tl_use:N \l_siunitx_range_phrase_tl #3 ~ #4 }
%    \end{macrocode}
% \end{macro}
% We also need the v2 names.
%    \begin{macrocode}
\@@_bookmark_cmd:Nnn \si { o m } { #2 }
\@@_bookmark_cmd:Nnn \SI { o m O { } m } { #3 #2 ~ #4 }
\@@_bookmark_cmd:Nnn \SIlist { o m m }
  {
    \@@_list_use:nnVVV {#2} {#3}
      \l_siunitx_list_separator_pair_tl
      \l_siunitx_list_separator_tl
      \l_siunitx_list_separator_final_tl
  }
\@@_bookmark_cmd:Nnn \SIrange { o m m m }
  { #2 ~ #4 \tl_use:N \l_siunitx_range_phrase_tl #3 ~ #4 }
%    \end{macrocode}
%
% \begin{variable}{\c_@@_bookmark_seq}
%   Commands usable in bookmarks
%    \begin{macrocode}
\seq_const_from_clist:Nn \c_@@_bookmark_seq
  {
    \ang , \qty , \num , \unit ,
    \numlist , \qtylist ,
    \numrange , \qtyrange ,
    \si , \SI , \SIlist , \SIrange
  }
%    \end{macrocode}
% \end{variable}
%
% Activate the document commands here: the unit macros are handled in
% \pkg{siunitx-final}.
%    \begin{macrocode}
\AtBeginDocument
  {
    \@ifpackageloaded { hyperref }
      {
        \pdfstringdefDisableCommands
          {
            \seq_map_inline:Nn \c_@@_bookmark_seq
              {
                \ExpandArgs { Nc } \DeclareCommandCopy #1
                  { \cs_to_str:N #1 \c_space_tl ( pdfstring ~ context ) }
              }
          }
        \pdfstringdefDisableCommands
          {
            \siunitx_unit_pdfstring_context:
            \cs_if_exist:NT \FB@fg { \def \fg { \FB@fg } }
            \edef \H
              {
                \exp_not:c { PU-cmd }
                \exp_not:N \H
                \exp_not:c { PU \token_to_str:N \H }
              }
          }
      }
      { }
  }
%    \end{macrocode}
%
% \begin{macro}[EXP]{\@@_angle:n}
% \begin{macro}[EXP]{\@@_duration:w}
%   Expandable splitting of the angle: simply enough, also outputs the
%    \begin{macrocode}
\cs_new:Npn \@@_angle:n #1
  { \@@_angle:w #1 ; ; ; \q_stop }
\cs_new:Npn \@@_angle:w #1 ; #2 ; #3 ; #4 \q_stop
  {
    \tl_if_blank:nF {#1}
      { #1 \degree }
    \tl_if_blank:nF {#2}
      {
        \tl_if_blank:nF {#1} { \c_space_tl }
        #2 \arcminute
      }
    \tl_if_blank:nF {#3}
      {
        \tl_if_blank:nF {#1#2} { \c_space_tl }
        #3 \arcsecond
      }
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \begin{macro}[EXP]{\@@_duration:n}
% \begin{macro}[EXP]{\@@_duration:w}
%    \begin{macrocode}
\cs_new:Npn \@@_duration:n #1
  { \@@_angle:w #1 ; ; ; \q_stop }
\cs_new:Npn \@@_duration:w #1 ; #2 ; #3 ; #4 \q_stop
  {
    \tl_if_blank:nF {#1}
      { #1 ~ \hour }
    \tl_if_blank:nF {#2}
      {
        \tl_if_blank:nF {#1} { \c_space_tl }
        #2 ~ \minute
      }
    \tl_if_blank:nF {#3}
      {
        \tl_if_blank:nF {#1#2} { \c_space_tl }
        #3 ~ \second
      }
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}[EXP]
%   {\@@_list_use:nnnnn, \@@_list_use:nnVVV, \@@_list_use_aux:nnnnn}
% \begin{macro}[EXP]{\@@_list_use_auxi:w}
% \begin{macro}[EXP]{\@@_list_use_auxii:nnw, \@@_list_use_auxiii:nnw}
% \begin{macro}[EXP]{\@@_list_count:n}
% \begin{macro}[EXP]{\@@_list_count:w}
%   Copies of the ideas in the \pkg{l3clist} module but using |;| as a list
%   separator. The functions have to be extended to allow for a unit argument.
%    \begin{macrocode}
\cs_new:Npn \@@_list_use:nnnnn #1#2#3#4#5
  {
    \tl_if_blank:nTF {#2}
      { \@@_list_use_aux:nnnnn {#1} { } }
      { \@@_list_use_aux:nnnnn {#1} { ~ #2 } }
        {#3} {#4} {#5}
  }
\cs_generate_variant:Nn \@@_list_use:nnnnn { nnVVV }
\cs_new:Npn \@@_list_use_aux:nnnnn #1#2#3#4#5
  {
    \int_case:nnF { \@@_list_count:n {#1} }
      {
        { 0 } { }
        { 1 } { \@@_list_use_auxi:nw {#2} #1 ; ; { } }
        { 2 } { \@@_list_use_auxi:nw {#2} #1 ; {#3} }
      }
      {
        \@@_list_use_auxii:nnw {#2} { } #1 ;
          \q_mark ; { \@@_list_use_auxii:nnw {#2} {#4} }
          \q_mark ; { \@@_list_use_auxiii:nnw {#2} {#5} }
          \q_stop { }
      }
  }
\cs_new:Npn \@@_list_use_auxi:nw #1#2 ; #3 ; #4
  { #2 #1 #4 #3 \tl_if_blank:nF {#3} {#1} }
\cs_new:Npn \@@_list_use_auxii:nnw
  #1#2#3 ; #4 ; #5 ; #6 \q_mark ; #7#8 \q_stop #9
  { #7 {#4} ; {#5} ; #6 \q_mark ; {#7} #8 \q_stop { #9 #2 #3 #1 } }
\cs_new:Npn \@@_list_use_auxiii:nnw #1#2#3 ; #4 \q_stop #5
  { #5 #2 #3 #1 }
\cs_new:Npe \@@_list_count:n #1
  {
    \exp_not:N \int_eval:n
      {
        0
        \exp_not:N \@@_list_count:w \c_space_tl
        #1
        \exp_not:n { ; \s_stop \use_none_delimit_by_q_stop:w ; \q_stop }
      }
  }
\cs_new:Npe \@@_list_count:w #1 ;
  {
    \exp_not:N \use_none_delimit_by_s_stop:w #1 \exp_not:N \s_stop
    \exp_not:N \tl_if_blank:nF {#1} { + 1 }
    \exp_not:N \@@_list_count:w \c_space_tl
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%    \begin{macrocode}
%</interfaces>
%    \end{macrocode}
%
%    \begin{macrocode}
%</package>
%    \end{macrocode}
%
% \end{implementation}
%
% \PrintIndex
