% \iffalse meta-comment
%
% File: siunitx-sexagesimal.dtx Copyright (C) 2016-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\foreign{m}{\textit{#1}}
% 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-sexagesimal} -- Formatting sexagesimal values^^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}
%
% \section{Formatting sexagesimal values}
%
% The generic sexagesimal formatting code is designed for values which have
% three components, each related by a factor of 60 to the next higher
% component.
%
% \begin{function}
%   {
%     \siunitx_sexagesimal:n, \siunitx_sexagesimal:e,
%     \siunitx_sexagesimal:nnn, \siunitx_sexagesimal:eee
%   }
%   \begin{syntax}
%     \cs{siunitx_sexagesimal:n} \Arg{decimal}
%     \cs{siunitx_sexagesimal:nnn} \Arg{major} \Arg{intermediate} \Arg{minor}
%   \end{syntax}
%   Typeset the \meta{sexagesimal} value (which may be given as separate
%   \meta{major}, \meta{intermediate} and \meta{minor} components). The
%   \meta{sexagesimal} (or components) may be given as expressions. The
%   \meta{sexagesimal} should be a number as understood by
%   \cs{siunitx_format_number:nN}, with no uncertainty, exponent or imaginary
%   part. The unit symbols for \meta{major}, \meta{intermediate}, \meta{minor}
%   are set by the options described below.
% \end{function}
%
% \begin{function}{sexagesimal-mode}
%   \begin{syntax}
%     |sexagesimal-mode| = \meta{choice}
%   \end{syntax}
%   Selects how sexagesimal values are formatted: a choice from
%   the options |parts|, |decimal| and |input|. The option |components| means
%   that sexagesimal values will always be typeset in components (major,
%   intermediate, minor) format, whilst |decimal| means that angles are typeset
%   as a single decimal value. The |input| setting means that the input format
%   (\foreign{i.e.}~difference between \cs{siunitx_sexagesimal:n} and
%   \cs{siunitx_sexagesimal:nnn}) is maintained. The standard setting is
%   |input|.
% \end{function}
%
% \begin{function}
%   {
%     fill-sexagesimal-major        ,
%     fill-sexagesimal-intermediate ,
%     fill-sexagesimal-minor
%   }
%   \begin{syntax}
%     |fill-sexagesimal-major| = |true|\verb"|"|false|
%   \end{syntax}
%   Determines whether a missing component is zero-filled when printing an
%   arc. The standard setting is |false|.
% \end{function}
%
% \begin{function}{sexagesimal-separator}
%   \begin{syntax}
%     |sexagesimal-separator| = \meta{separator}
%   \end{syntax}
%   Inserted between component parts (major, intermediate and minor
%   components). The standard setting is empty.
% \end{function}
%
% \begin{function}
%   {
%     sexagesimal-unit-major        ,
%     sexagesimal-unit-intermediate ,
%     sexagesimal-unit-minor
%   }
%   \begin{syntax}
%     |sexagesimal-unit-major| = \meta{unit}
%   \end{syntax}
%   Sets the unit symbol(s) used for major, intermediate and minor components,
%   respectively. The standard settings are empty.
% \end{function}
%
% \begin{function}{sexagesimal-unit-over-decimal}
%   \begin{syntax}
%     |sexagesimal-unit-over-decimal| = |true|\verb"|"|false|
%   \end{syntax}
%   Determines if the component separator is printed over the decimal marker.
%   The standard setting is |false|.
% \end{function}
%
% \section{Formatting angles}
%
% \begin{function}
%   {
%     \siunitx_angle:n, \siunitx_angle:e,
%     \siunitx_angle:nnn, \siunitx_angle:eee
%   }
%   \begin{syntax}
%     \cs{siunitx_angle:n} \Arg{angle}
%     \cs{siunitx_angle:nnn} \Arg{degrees} \Arg{minutes} \Arg{seconds}
%   \end{syntax}
%   Typeset the \meta{angle} (which may be given as separate \meta{degree},
%   \meta{minute} and \meta{second} components). The \meta{angle}
%   (or components) may be given as expressions. The \meta{angle} should be a
%   number as understood by \cs{siunitx_format_number:nN}, with no uncertainty,
%   exponent or imaginary part.  The unit symbols for degrees, minutes and
%   seconds are |\degree|, |\arcminute| and |\arcsecond|, respectively.
% \end{function}
%
% \begin{function}{angle-mode}
%   \begin{syntax}
%     |angle-mode| = \meta{choice}
%   \end{syntax}
%   Selects how angles are formatted: a choice from
%   the options |arc|, |decimal| and |input|. The option |arc| means that angles
%   will always be typeset in arc (degree, minute, second) format, whilst
%   |decimal| means that angles are typeset as a single decimal value. The
%   |input| setting means that the input format (\foreign{i.e.}~difference
%   between \cs{siunitx_angle:n} and \cs{siunitx_angle:nnn}) is maintained. The
%   standard setting is |input|.
% \end{function}
%
% \begin{function}
%   {
%     angle-symbol-degree ,
%     angle-symbol-minute ,
%     angle-symbol-second
%   }
%   \begin{syntax}
%     |angle-symbol-degree| = \meta{symbol}
%   \end{syntax}
%   Sets the symbol used for arc degrees, minutes or seconds, respectively.
% \end{function}
%
% \begin{function}{angle-symbol-over-decimal}
%   \begin{syntax}
%     |angle-symbol-over-decimal| = |true|\verb"|"|false|
%   \end{syntax}
%   Determines if the arc separator is printed over the decimal marker, a
%   format used in astronomy. The standard setting is |false|.
% \end{function}
%
% \begin{function}{angle-separator}
%   \begin{syntax}
%     |angle-separator| = \meta{separator}
%   \end{syntax}
%   Inserted between angle parts (degree, minute and second components).
%   The standard setting is empty.
% \end{function}
%
% \begin{function}
%   {
%     fill-angle-degrees ,
%     fill-angle-minutes ,
%     fill-angle-seconds
%   }
%   \begin{syntax}
%     |fill-arc-degrees| = |true|\verb"|"|false|
%   \end{syntax}
%   Determines whether a missing angle part is zero-filled when printing an
%   arc. The standard setting is |false|.
% \end{function}
%
% \section{Formatting durations}
%
% \begin{function}
%   {
%     \siunitx_duration:n, \siunitx_duration:e,
%     \siunitx_duration:nnn, \siunitx_duration:eee
%   }
%   \begin{syntax}
%     \cs{siunitx_duration:n} \Arg{decimal}
%     \cs{siunitx_duration:nnn} \Arg{hours} \Arg{minutes} \Arg{seconds}
%   \end{syntax}
%   Typeset the \meta{duration} (which may be given as separate \meta{hour},
%   \meta{minute} and \meta{second} components). The \meta{duration}
%   (or components) may be given as expressions. The \meta{duration} should be a
%   number as understood by \cs{siunitx_format_number:nN}, with no uncertainty,
%   exponent or imaginary part.  The unit symbols for hours, minutes and
%   seconds are |\degree|, |\arcminute| and |\arcsecond|, respectively.
% \end{function}
%
% \begin{function}{component-separator}
%   \begin{syntax}
%     |component-separator| = \meta{separator}
%   \end{syntax}
%   Inserted between arc parts (degree, minute and second components).
%   The standard setting is |\,|.
% \end{function}
%
% \begin{function}{duration-mode}
%   \begin{syntax}
%     |duration-mode| = \meta{choice}
%   \end{syntax}
%   Selects how durations are formatted: a choice from
%   the options |component|, |decimal| and |input|. The option |component|
%   means that durations will always be typeset in component (hour, minute,
%   second) format, whilst |decimal| means that angles are typeset as a single
%   decimal value. The |input| setting means that the input format
%   (\foreign{i.e.}~difference  between \cs{siunitx_duration:n} and
%   \cs{siunitx_duration:nnn}) is maintained. The standard setting is |input|.
% \end{function}
%
% \begin{function}
%   {
%     duration-unit-hour   ,
%     duration-unit-minute ,
%     duration-unit-second
%   }
%   \begin{syntax}
%     |duration-unit-hour| = \meta{unit}
%   \end{syntax}
%   Sets the symbol used for component hours, minutes or seconds, respectively.
% \end{function}
%
% \begin{function}
%   {
%     fill-duration-hours   ,
%     fill-duration-minutes ,
%     fill-duration-seconds
%   }
%   \begin{syntax}
%     |fill-duration-hours| = |true|\verb"|"|false|
%   \end{syntax}
%   Determines whether a missing part is zero-filled when printing an
%   duration in component form. The standard setting is |false|.
% \end{function}
%
% \end{documentation}
%
% \begin{implementation}
%
% \section{\pkg{siunitx-angle} implementation}
%
% Start the \pkg{DocStrip} guards.
%    \begin{macrocode}
%<*package>
%    \end{macrocode}
%
% \subsection{General mechanism}
%
% Identify the internal prefix.
%    \begin{macrocode}
%<@@=siunitx_sexagesimal>
%    \end{macrocode}
%
% \begin{variable}{\l_@@_tmp_bool, \l_@@_tmp_dim, \l_@@_tmp_tl}
%   Scratch space.
%    \begin{macrocode}
\bool_new:N \l_@@_tmp_bool
\dim_new:N \l_@@_tmp_dim
\tl_new:N \l_@@_tmp_tl
%    \end{macrocode}
% \end{variable}
%
% \begin{variable}
%   {
%     \l_@@_fill_major_bool    ,
%     \l_@@_fill_inter_bool    ,
%     \l_@@_fill_minor_bool    ,
%     \l_@@_unit_major_tl      ,
%     \l_@@_unit_inter_tl      ,
%     \l_@@_unit_minor_tl      ,
%     \l_@@_force_comp_bool    ,
%     \l_@@_force_decimal_bool ,
%     \l_@@_astronomy_bool     ,
%     \l_@@_separator_tl
%   }
%    \begin{macrocode}
\keys_define:nn { siunitx }
  {
    fill-sexagesimal-major .bool_set:N =
      \l_@@_fill_major_bool ,
    fill-sexagesimal-intermediate .bool_set:N =
      \l_@@_fill_inter_bool ,
    fill-sexagesimal-minor .bool_set:N =
      \l_@@_fill_minor_bool ,
    sexagesimal-mode .choice: ,
    sexagesimal-mode / component .code:n =
      {
        \bool_set_true:N \l_@@_force_comp_bool
        \bool_set_false:N \l_@@_force_decimal_bool
      } ,
    sexagesimal-mode / decimal .code:n =
      {
        \bool_set_false:N \l_@@_force_comp_bool
        \bool_set_true:N \l_@@_force_decimal_bool
      } ,
    sexagesimal-mode / input .code:n =
      {
        \bool_set_false:N \l_@@_force_comp_bool
        \bool_set_false:N \l_@@_force_decimal_bool
      } ,
    sexagesimal-unit-major .tl_set:N =
      \l_@@_unit_major_tl ,
    sexagesimal-unit-intermediate .tl_set:N =
      \l_@@_unit_inter_tl ,
    sexagesimal-unit-minor .tl_set:N =
      \l_@@_unit_minor_tl ,
    sexagesimal-unit-over-decimal .bool_set:N =
      \l_@@_astronomy_bool ,
    sexagesimal-separator .tl_set:N =
      \l_@@_separator_tl
  }
\bool_new:N \l_@@_force_comp_bool
\bool_new:N \l_@@_force_decimal_bool
%    \end{macrocode}
% \end{variable}
%
% \begin{macro}{\siunitx_sexagesimal:n, \siunitx_sexagesimal:e, \@@_decimal:n}
% \begin{macro}{\siunitx_sexagesimal:nnn, \siunitx_sexagesimal:eee}
% \begin{macro}{\@@_comp_convert:n, \@@_comp_convert:e}
% \begin{macro}{\@@_comp_convert:w}
%   The first step here is to force format conversion if required. Going to
%   a decimal is easy, going to arc format is a bit more painful: avoid
%   repeating calculations mainly for code readability.
%    \begin{macrocode}
\cs_new_protected:Npn \siunitx_sexagesimal:n #1
  {
    \bool_if:NTF \l_siunitx_number_parse_bool
      { \@@_decimal:n {#1} }
      {
        \tl_if_blank:nF {#1}
          {
            \tl_set:Nn \l_@@_major_tl { \ensuremath {#1} }
            \@@_comp_print:VVV
              \l_@@_major_tl
              \c_empty_tl
              \c_empty_tl
          }
      }
  }
\cs_generate_variant:Nn \siunitx_sexagesimal:n { e }
\cs_new_protected:Npn \@@_decimal:n #1
  {
    \bool_if:NTF \l_@@_force_comp_bool
      { \@@_comp_convert:e { \fp_eval:n {#1} } }
      {
        \siunitx_number_parse:nN {#1} \l_@@_major_tl
        \siunitx_number_process:NN \l_@@_major_tl \l_@@_major_tl
        \tl_set:Ne \l_@@_major_tl
          { \siunitx_number_output:NN \l_@@_major_tl \q_nil }
        \@@_comp_print:VVV
          \l_@@_major_tl
          \c_empty_tl
          \c_empty_tl
      }
  }
\cs_new_protected:Npn \siunitx_sexagesimal:nnn #1#2#3
  {
    \bool_if:NTF \l_siunitx_number_parse_bool
      {
        \bool_if:NTF \l_@@_force_decimal_bool
          {
            \siunitx_sexagesimal:e
              { \fp_eval:n { #1 + ( 0 #2 ) / 60 + ( 0 #3 ) / 3600 } }
          }
          { \@@_comp_sign:nnn {#1} {#2} {#3} }
      }
      {
        \tl_set:Ne \l_@@_major_tl
          { \tl_if_blank:nF {#1} { \exp_not:n { \ensuremath {#1} } } }
        \tl_set:Ne \l_@@_inter_tl
          { \tl_if_blank:nF {#2} { \exp_not:n { \ensuremath {#2} } } }
        \tl_set:Ne \l_@@_minor_tl
          { \tl_if_blank:nF {#3} { \exp_not:n { \ensuremath {#3} } } }
        \@@_comp_print:VVV
          \l_@@_major_tl
          \l_@@_inter_tl
          \l_@@_minor_tl
      }
  }
\cs_generate_variant:Nn \siunitx_sexagesimal:nnn { eee }
%    \end{macrocode}
%   Here, the need for absolute values is to handle conversion of negative
%   values: the result should be exactly one sign in the integer part. For
%   integer input, we can control whether there are minute or second parts
%   at all.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_comp_convert:n #1
  {
    \@@_comp_convert:w #1 . \q_nil . \q_stop
  }
\cs_generate_variant:Nn \@@_comp_convert:n { e }
\cs_new_protected:Npn \@@_comp_convert:w #1 . #2 . #3 \q_stop
  {
    \quark_if_nil:nTF {#2}
      {
        \siunitx_sexagesimal:eee
          { \fp_eval:n { trunc(#1,0) } }
          { \bool_if:NT \l_@@_fill_inter_bool { 0 } }
          { \bool_if:NT \l_@@_fill_minor_bool { 0 } }
      }
      {
        \siunitx_sexagesimal:eee
          { \fp_eval:n { trunc(#1.#2,0) } }
          { \fp_eval:n { abs(trunc((#1.#2 - trunc(#1,0)) * 60,0)) } }
          {
            \fp_eval:n
              {
                abs
                  (
                            (#1.#2 - trunc(#1.#2,0)) * 60
                    - trunc((#1.#2 - trunc(#1.#2,0)) * 60,0)
                  )
                * 60
              }
          }
      }
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{variable}{\c_@@_parts_tl}
%   For mappings.
%    \begin{macrocode}
\clist_const:Nn \c_@@_parts_tl { major , inter , minor }
%    \end{macrocode}
% \end{variable}
%
% \begin{variable}{\l_@@_major_tl, \l_@@_inter_tl, \l_@@_minor_tl}
%   Space for formatting parsed numbers.
%    \begin{macrocode}
\tl_new:N \l_@@_major_tl
\tl_new:N \l_@@_inter_tl
\tl_new:N \l_@@_minor_tl
%    \end{macrocode}
% \end{variable}
%
% \begin{variable}{\l_@@_sign_tl}
%   For the \enquote{sign shuffle}.
%    \begin{macrocode}
\tl_new:N \l_@@_sign_tl
%    \end{macrocode}
% \end{variable}
%
% \begin{variable}{\l_@@_signed_bool}
%   To check that only one sign is seen in arc mode.
%    \begin{macrocode}
\bool_new:N \l_@@_signed_bool
%    \end{macrocode}
% \end{variable}
%
% \begin{macro}{\@@_suppress_comp:, \@@_suppress_exp:, \@@_suppress_uncert:,}
%   Pre-compilation of keys to suppress uncertainties and exponents,
%   and 
%    \begin{macrocode}
\keys_precompile:nnN
  { siunitx }
  { input-comparators = }
  \l_@@_tmp_tl
\cs_new_protected:Npe \@@_suppress_comp:
  { \exp_not:V \l_@@_tmp_tl }
\keys_precompile:nnN
  { siunitx }
  { input-exponent-markers = }
  \l_@@_tmp_tl
\cs_new_protected:Npe \@@_suppress_exp:
  { \exp_not:V \l_@@_tmp_tl }
\keys_precompile:nnN
  { siunitx }
  {
    input-close-uncertainty = ,
    input-open-uncertainty  = ,
    input-uncertainty-signs =
  }
  \l_@@_tmp_tl
\cs_new_protected:Npe \@@_suppress_uncert:
  { \exp_not:V \l_@@_tmp_tl }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_comp_sign:nnn}
% \begin{macro}{\@@_comp_sign:nn}
% \begin{macro}{\@@_comp_sign_auxi:, \@@_comp_sign_auxii:}
% \begin{macro}{\@@_extract_sign:nnnnnnnn}
% \begin{macro}[EXP]{\@@_sign:nnnnnnn}
%   To get the sign in the right place whilst dealing with zero filling
%   means doing some shuffling. That means doing processing of each number
%   manually. For degrees, auto-conversion can give |-0|, which needs to be
%   picked up early to set the sign. A bit of shuffling is needed as only
%   the seconds argument is permitted to have an uncertainty.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_comp_sign:nnn #1#2#3
  {
    \group_begin:
      \tl_clear:N \l_@@_sign_tl
      \bool_set_false:N \l_@@_signed_bool
      \group_begin:
        \@@_suppress_exp:
        \@@_suppress_uncert:
        \str_if_eq:nnTF {#1} { -0 }
          {
            \@@_comp_sign:nn { } { major }
            \@@_suppress_comp:
            \tl_set:Nn \l_@@_sign_tl { - }
            \bool_set_true:N \l_@@_signed_bool
          }
          { \@@_comp_sign:nn {#1} { major } } 
        \@@_comp_sign:nn {#2} { inter }
        \tl_set:Ne \l_@@_tmp_tl
          {
            \tl_set:Nn \exp_not:N \l_@@_sign_tl
              { \exp_not:V \l_@@_sign_tl }
            \tl_set:Nn \exp_not:N \l_@@_major_tl
              { \exp_not:V \l_@@_major_tl }
            \tl_set:Nn \exp_not:N \l_@@_inter_tl
              { \exp_not:V \l_@@_inter_tl }
            \exp_not:c
              {
                bool_set_
                \bool_if:NTF \l_@@_signed_bool
                  { true }
                  { false }
                :N
              }
                \exp_not:N \l_@@_signed_bool
          }
      \exp_after:wN \group_end: \l_@@_tmp_tl
      \@@_comp_sign:nn {#3} { minor }
      \tl_if_empty:NF \l_@@_sign_tl
        {
          \clist_map_function:NN \c_@@_parts_tl
            \@@_comp_sign_auxi:n
        }
      \clist_map_function:NN \c_@@_parts_tl \@@_comp_sign_auxii:n
      \@@_comp_print:VVV
        \l_@@_major_tl
        \l_@@_inter_tl
        \l_@@_minor_tl
    \group_end:
  }
\cs_new_protected:Npn \@@_comp_sign:nn #1#2
  {
    \tl_if_blank:nTF {#1}
      {
        \bool_if:cTF { l_@@_fill_ #2 _bool }
          {
            \tl_set:cn { l_@@_ #2 _tl }
              { { } { } { 0 } { } { } { } { 0 } }
          }
          { \tl_clear:c { l_@@_ #2 _tl } }
      }
      {
        \siunitx_number_parse:nN {#1} \l_@@_tmp_tl
        \tl_if_empty:NF \l_@@_tmp_tl
          {
            \exp_after:wN \@@_extract_sign:nnnnnnnn \l_@@_tmp_tl {#2}
            \bool_set_true:N \l_@@_signed_bool
          }
      }
  }
\cs_new_protected:Npn \@@_comp_sign_auxi:n #1
  {
    \tl_if_empty:cF { l_@@_ #1 _tl }
      {
        \tl_set:ce { l_@@_ #1 _tl }
          {
            { }
            { \exp_not:V \l_@@_sign_tl }
            \exp_after:wN \exp_after:wN \exp_after:wN
              \@@_sign:nnnnnnn
                \cs:w l_@@_ #1 _tl \cs_end:
           }
        \clist_map_break:
      }
  }
\cs_new_protected:Npn \@@_comp_sign_auxii:n #1
  {
    \tl_if_empty:cF { l_@@_ #1 _tl }
      {
        \bool_lazy_and:nnF
          { \l_@@_force_comp_bool }
          { ! \str_if_eq_p:nn {#1} { minor } }
          {
            \siunitx_number_process:cc
              { l_@@_ #1 _tl } { l_@@_ #1 _tl }
          }
        \tl_set:ce { l_@@_ #1 _tl }
          {
            \siunitx_number_output:cN
              { l_@@_ #1 _tl } \q_nil
          }
      }
  }
\cs_new_protected:Npn \@@_extract_sign:nnnnnnnn #1#2#3#4#5#6#7#8
  {
    \tl_if_blank:nTF {#2}
      { \tl_set_eq:cN { l_@@_ #8 _tl } \l_@@_tmp_tl }
      {
        \bool_if:NTF \l_@@_signed_bool
          { \msg_error:nnn { siunitx } { sexagesimal-multi-sign } }
          { \tl_set:Nn \l_@@_sign_tl {#2} }
        \tl_set:cn { l_@@_ #8 _tl }
          { {#1} { } {#3} {#4} {#5} {#6} {#7} }
        \@@_suppress_comp:
      }
  }
\cs_new:Npn \@@_sign:nnnnnnn #1#2#3#4#5#6#7
  { \exp_not:n { {#3} {#4} {#5} {#6} {#7} } }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%  \begin{variable}{\l_@@_marker_box, \l_@@_unit_box}
%    For \enquote{astronomy style} output.
%    \begin{macrocode}
\box_new:N \l_@@_marker_box
\box_new:N \l_@@_unit_box
%    \end{macrocode}
%  \end{variable}
%
% \begin{macro}
%   {
%     \@@_comp_print:nnn, \@@_comp_print:VVV,
%     \@@_comp_print_auxi:nnn, \@@_comp_print_auxi:nVn
%   }
% \begin{macro}{\@@_comp_print_auxii:w}
% \begin{macro}{\@@_comp_print_auxiii:nw}
% \begin{macro}{\@@_comp_print_auxiv:nnnnn}
% \begin{macro}{\@@_comp_print_auxv:n}
% \begin{macro}{\@@_comp_print_auxvi:NN}
% \begin{macro}{\@@_comp_print_auxvii:nw}
% \begin{macro}{\@@_comp_print_auxiix:nw}
% \begin{macro}{\@@_comp_print_auxix:nn}
%   The final stage of printing an angle is to put together the three parts:
%   this works even for decimal angles as they will blank arguments for the
%   other two parts The need to handle astronomy-style formatting means that
%   the number has to be decomposed into parts.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_comp_print:nnn #1#2#3
  {
    \@@_comp_print_auxi:nVn {#1}
      \l_@@_unit_major_tl {#2#3}
    \@@_comp_print_auxi:nVn {#2}
      \l_@@_unit_inter_tl {#3}
    \@@_comp_print_auxi:nVn {#3}
      \l_@@_unit_minor_tl { }
  }
\cs_generate_variant:Nn \@@_comp_print:nnn { VVV }
\cs_new_protected:Npn \@@_comp_print_auxi:nnn #1#2#3
  {
    \tl_if_blank:nF {#1}
      {
        \bool_if:NTF \l_siunitx_number_parse_bool
          {
            \bool_if:NTF \l_@@_astronomy_bool
              { \@@_comp_print_auxii:nw {#2} #1 \q_stop }
              { \@@_comp_print_auxvii:nw {#2} #1 \q_stop }
          }
          { \@@_comp_print_auxix:nn {#1} {#2} }
       \tl_if_blank:nF {#3}
          {
            \nobreak
            \l_@@_separator_tl
          }
      }        
  }
\cs_generate_variant:Nn \@@_comp_print_auxi:nnn { nV }
%    \end{macrocode}
%    To align the two parts of the astronomy-style marker, we need to allow
%    for the |\scriptspace|.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_comp_print_auxii:nw
  #1#2 \q_nil #3 \q_nil #4 \q_nil #5 \q_nil #6 \q_nil #7 \q_stop
  {
    \@@_comp_print_auxiii:nw {#6} #7 \q_stop
      {#2#3#4} {#5} {#1}
  }
\cs_new_protected:Npn \@@_comp_print_auxiii:nw
  #1#2 \q_nil #3 \q_nil #4 \q_nil #5 \q_nil #6 \q_nil #7 \q_stop
  { \@@_comp_print_auxiv:nnnnn {#1} {#6#7} }
\cs_new_protected:Npn \@@_comp_print_auxiv:nnnnn #1#2#3#4#5
  {
    \mode_if_math:TF
      { \bool_set_true:N \l_@@_tmp_bool }
      { \bool_set_false:N \l_@@_tmp_bool }
    \siunitx_print_number:n {#3}
    \tl_if_blank:nTF {#1}
      { \@@_comp_print_auxix:nn {#2} {#5} }
      {
        \hbox_set:Nn \l_@@_marker_box
          {
            \@@_comp_print_auxv:n
               { \siunitx_print_number:n {#4} }
          }
        \hbox_set:Nn \l_@@_unit_box
          {
            \@@_comp_print_auxv:n
              {
                \siunitx_unit_format:nN {#5} \l_@@_tmp_tl
                \siunitx_print_unit:V \l_@@_tmp_tl
                \skip_horizontal:n { -\scriptspace }
              }
          }
        \dim_compare:nNnTF { \box_wd:N \l_@@_marker_box } >
          { \box_wd:N \l_@@_unit_box }
          {
            \@@_comp_print_auxvi:NN
              \l_@@_marker_box
              \l_@@_unit_box
          }
          {
            \@@_comp_print_auxvi:NN
              \l_@@_unit_box
              \l_@@_marker_box
          }
        \hbox_set_to_wd:Nnn \l_@@_marker_box
          \l_@@_tmp_dim
          {
            \hbox_overlap_right:n
              { \box_use_drop:N \l_@@_marker_box }
            \hbox_overlap_right:n
              { \box_use_drop:N \l_@@_unit_box }
            \tex_hfil:D
          }
        \box_use:N \l_@@_marker_box
        \tex_kern:D \scriptspace 
        \siunitx_print_number:n {#1#2}
      }
  }
\cs_new_protected:Npn \@@_comp_print_auxv:n #1
  {
    \bool_if:NTF \l_@@_tmp_bool
      { \ensuremath }
      { \use:n }
        {#1}
  }
\cs_new_protected:Npn \@@_comp_print_auxvi:NN #1#2
  {
    \dim_set:Nn \l_@@_tmp_dim { \box_wd:N #1 }
    \hbox_set_to_wd:Nnn #2
      \l_@@_tmp_dim
      {
        \tex_hss:D
        \hbox_unpack_drop:N #2
        \tex_hss:D
      }
  }
\cs_new_protected:Npn \@@_comp_print_auxvii:nw
  #1#2 \q_nil #3 \q_nil #4 \q_nil #5 \q_nil #6 \q_nil #7 \q_stop
  { \@@_comp_print_auxiix:nw {#1} {#2#3#4#5#6} #7 \q_stop }
\cs_new_protected:Npn \@@_comp_print_auxiix:nw
  #1#2#3 \q_nil #4 \q_nil #5 \q_nil #6 \q_nil #7 \q_nil #8 \q_stop
  { \@@_comp_print_auxix:nn {#2#7#8} {#1} }
\cs_new_protected:Npn \@@_comp_print_auxix:nn #1#2
  {
    \group_begin:
      \siunitx_unit_options_apply:n {#2}
      \siunitx_unit_format:nN {#2} \l_@@_tmp_tl
      \siunitx_quantity_print:nV {#1} \l_@@_tmp_tl
    \group_end:
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%    \begin{macrocode}
\msg_new:nnnn { siunitx } { sexagesimal-multi-sign }
  { Multiple~signs~given~for~sexagesimal~components! }
  {
    A~sexagesimal~value~given~as~components~should~have~at~most~one~sign:~
    only~the~first~sign~will~be~used.
  }
%    \end{macrocode}
%
% \subsection{Angles}
%
% Identify the internal prefix.
%    \begin{macrocode}
%<@@=siunitx_angle>
%    \end{macrocode}
%
% \begin{variable}
%   {
%     \l_@@_symbol_degree_tl    ,
%     \l_@@_symbol_minute_tl    ,
%     \l_@@_symbol_second_tl    ,
%     \l_@@_force_arc_bool      ,
%     \l_@@_force_decimal_bool  ,
%     \l_@@_astronomy_bool      ,
%     \l_@@_separator_tl        ,
%     \l_@@_fill_degrees_bool   ,
%     \l_@@_fill_minutes_bool   ,
%     \l_@@_fill_seconds_bool
%    }
%    \begin{macrocode}
\keys_define:nn { siunitx }
  {
    angle-mode .choice: ,
    angle-mode / arc .code:n =
      {
        \bool_set_true:N \l_@@_force_arc_bool
        \bool_set_false:N \l_@@_force_decimal_bool
      } ,
    angle-mode / decimal .code:n =
      {
        \bool_set_false:N \l_@@_force_arc_bool
        \bool_set_true:N \l_@@_force_decimal_bool
      } ,
    angle-mode / input .code:n =
      {
        \bool_set_false:N \l_@@_force_arc_bool
        \bool_set_false:N \l_@@_force_decimal_bool
      } ,
    angle-symbol-degree .tl_set:N =
      \l_@@_symbol_degree_tl ,
    angle-symbol-minute .tl_set:N =
      \l_@@_symbol_minute_tl ,
    angle-symbol-second .tl_set:N =
      \l_@@_symbol_second_tl ,
    angle-symbol-over-decimal .bool_set:N =
      \l_@@_astronomy_bool ,
    angle-separator .tl_set:N =
      \l_@@_separator_tl ,
    fill-angle-degrees .bool_set:N =
      \l_@@_fill_degrees_bool ,
    fill-angle-minutes .bool_set:N =
      \l_@@_fill_minutes_bool ,
    fill-angle-seconds .bool_set:N =
      \l_@@_fill_seconds_bool ,
  }
\bool_new:N \l_@@_force_arc_bool
\bool_new:N \l_@@_force_decimal_bool
%    \end{macrocode}
% \end{variable}
%
% \begin{macro}{\siunitx_angle:n, \siunitx_angle:e}
% \begin{macro}{\siunitx_angle:nnn, \siunitx_angle:eee}
% \begin{macro}{\@@_aux:}
%    \begin{macrocode}
\cs_new_protected:Npn \siunitx_angle:n #1
  {
    \group_begin:
      \@@_aux:
      \siunitx_sexagesimal:n {#1}
    \group_end:
  }
\cs_generate_variant:Nn \siunitx_angle:n { e , x }
\cs_new_protected:Npn \siunitx_angle:nnn #1#2#3
  {
    \group_begin:
      \@@_aux:
      \siunitx_sexagesimal:nnn {#1} {#2} {#3}
    \group_end:
  }
\cs_generate_variant:Nn \siunitx_angle:nnn { eee , xxx }
\cs_new_protected:Npn \@@_aux:
  {
    \keys_set:ne { siunitx }
      {
        fill-sexagesimal-major =
          \bool_if:NTF \l_@@_fill_degrees_bool { true } { false } ,
        fill-sexagesimal-intermediate =
          \bool_if:NTF \l_@@_fill_minutes_bool { true } { false } ,
        fill-sexagesimal-minor =
          \bool_if:NTF \l_@@_fill_seconds_bool { true } { false } ,
        sexagesimal-mode =
          \bool_if:NTF \l_@@_force_arc_bool
            { component }
            {
              \bool_if:NTF \l_@@_force_decimal_bool
                { decimal }
                { input }
            } ,
        sexagesimal-unit-major =
          { \exp_not:V \l_@@_symbol_degree_tl } ,
        sexagesimal-unit-intermediate =
          { \exp_not:V \l_@@_symbol_minute_tl } ,
        sexagesimal-unit-minor =
          { \exp_not:V \l_@@_symbol_second_tl } ,
        sexagesimal-unit-over-decimal = 
          \bool_if:NTF \l_@@_astronomy_bool { true } { false } ,
        sexagesimal-separator =
          { \exp_not:V \l_@@_separator_tl }
      }
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \subsection{Durations}
%
% Identify the internal prefix.
%    \begin{macrocode}
%<@@=siunitx_duration>
%    \end{macrocode}
%
% \begin{variable}
%   {
%     \l_@@_unit_hour_tl    ,
%     \l_@@_unit_minute_tl    ,
%     \l_@@_unit_second_tl    ,
%     \l_@@_force_arc_bool      ,
%     \l_@@_force_decimal_bool  ,
%     \l_@@_separator_tl        ,
%     \l_@@_fill_hours_bool   ,
%     \l_@@_fill_minutes_bool   ,
%     \l_@@_fill_seconds_bool
%    }
%    \begin{macrocode}
\keys_define:nn { siunitx }
  {
    duration-mode .choice: ,
    duration-mode / component .code:n =
      {
        \bool_set_true:N \l_@@_force_comp_bool
        \bool_set_false:N \l_@@_force_decimal_bool
      } ,
    duration-mode / decimal .code:n =
      {
        \bool_set_false:N \l_@@_force_comp_bool
        \bool_set_true:N \l_@@_force_decimal_bool
      } ,
    duration-mode / input .code:n =
      {
        \bool_set_false:N \l_@@_force_comp_bool
        \bool_set_false:N \l_@@_force_decimal_bool
      } ,
    duration-unit-hour .tl_set:N =
      \l_@@_symbol_hour_tl ,
    duration-unit-minute .tl_set:N =
      \l_@@_symbol_minute_tl ,
    duration-unit-second .tl_set:N =
      \l_@@_symbol_second_tl ,
    duration-separator .tl_set:N =
      \l_@@_separator_tl ,
    fill-duration-hours .bool_set:N =
      \l_@@_fill_hours_bool ,
    fill-duration-minutes .bool_set:N =
      \l_@@_fill_minutes_bool ,
    fill-duration-seconds .bool_set:N =
      \l_@@_fill_seconds_bool ,
  }
\bool_new:N \l_@@_force_comp_bool
\bool_new:N \l_@@_force_decimal_bool
%    \end{macrocode}
% \end{variable}
%
% \begin{macro}{\siunitx_duration:n, \siunitx_duration:e}
% \begin{macro}{\siunitx_duration:nnn, \siunitx_duration:eee}
% \begin{macro}{\@@_aux:}
%    \begin{macrocode}
\cs_new_protected:Npn \siunitx_duration:n #1
  {
    \group_begin:
      \@@_aux:
      \siunitx_sexagesimal:n {#1}
    \group_end:
  }
\cs_generate_variant:Nn \siunitx_duration:n { e }
\cs_new_protected:Npn \siunitx_duration:nnn #1#2#3
  {
    \group_begin:
      \@@_aux:
      \siunitx_sexagesimal:nnn {#1} {#2} {#3}
    \group_end:
  }
\cs_generate_variant:Nn \siunitx_duration:nnn { eee }
\cs_new_protected:Npn \@@_aux:
  {
    \keys_set:ne { siunitx }
      {
        fill-sexagesimal-major =
          \bool_if:NTF \l_@@_fill_hours_bool { true } { false } ,
        fill-sexagesimal-intermediate =
          \bool_if:NTF \l_@@_fill_minutes_bool { true } { false } ,
        fill-sexagesimal-minor =
          \bool_if:NTF \l_@@_fill_seconds_bool { true } { false } ,
        sexagesimal-mode =
          \bool_if:NTF \l_@@_force_comp_bool
            { component }
            {
              \bool_if:NTF \l_@@_force_decimal_bool
                { decimal }
                { input }
            } ,
        sexagesimal-unit-major =
          { \exp_not:V \l_@@_symbol_hour_tl } ,
        sexagesimal-unit-intermediate =
          { \exp_not:V \l_@@_symbol_minute_tl } ,
        sexagesimal-unit-minor =
          { \exp_not:V \l_@@_symbol_second_tl } ,
        sexagesimal-separator =
          { \exp_not:V \l_@@_separator_tl }
      }
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \subsection{Deprecated options}
% 
%    \begin{macrocode}
\msg_new:nnn { siunitx } { angle-option-deprecated }
  {
    Option~"#1"~has~been~deprecated~in~this~release.\\ \\
    Set~the~"quantity-product"~option~for~the~units~
    \token_to_str:N \arcminute,~\arcsecond\ and~\degree\ instead.
  }
\keys_define:nn { siunitx }
  {
    number-angle-product .code:n =
      {
        \msg_info:nnn { siunitx } { angle-option-deprecated }
          { number-angle-product }
        \siunitx_unit_options_declare:Nn \arcminute
          { quantity-product = {#1} }
        \siunitx_unit_options_declare:Nn \arcsecond
          { quantity-product = {#1} }
        \siunitx_unit_options_declare:Nn \degree
          { quantity-product = {#1} }
      }
  }
%    \end{macrocode}
%
% \subsection{Standard settings for module options}
%
%    \begin{macrocode}
\keys_set:nn { siunitx }
  {
    angle-mode                    = input      ,
    angle-symbol-degree           = \degree    ,
    angle-symbol-minute           = \arcminute ,
    angle-symbol-over-decimal     = false      ,
    angle-symbol-second           = \arcsecond ,
    angle-separator               =            ,
    duration-mode                 = input      ,
    duration-unit-hour            = \hour      ,
    duration-unit-minute          = \minute    ,
    duration-unit-second          = \second    ,
    duration-separator            =
      \TextOrMath { \space } { \  } ,
    fill-angle-degrees            = false      ,
    fill-angle-minutes            = false      ,
    fill-angle-seconds            = false      ,
    fill-duration-hours           = false      ,
    fill-duration-minutes         = false      ,
    fill-duration-seconds         = false      ,
    fill-sexagesimal-major        = false      ,
    fill-sexagesimal-intermediate = false      ,
    fill-sexagesimal-minor        = false      ,
    sexagesimal-mode              = input      ,
    sexagesimal-unit-major        =            ,
    sexagesimal-unit-intermediate =            ,
    sexagesimal-unit-minor        =            ,
    sexagesimal-unit-over-decimal = false      ,
    sexagesimal-separator         =
  }
%    \end{macrocode}
%
%    \begin{macrocode}
%</package>
%    \end{macrocode}
%
% \end{implementation}
%
% \PrintIndex
