% \iffalse meta-comment
%
%% File: l3pdfoutline.dtx
%
% Copyright (C) 2026 The LaTeX Project
%
% 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
%
%    http://www.latex-project.org/lppl.txt
%
% This file is part of the "LaTeX PDF management testphase bundle" (The Work in LPPL)
% and all files in that bundle must be distributed together.
%
% -----------------------------------------------------------------------
%
% The development version of the bundle can be found at
%
%    https://github.com/latex3/pdfresources
%
% for those people who are interested.
%
%<*driver>
\DocumentMetadata{tagging=on,pdfstandard=ua-2,testphase=bookmark}
\documentclass[kernel]{l3in2edoc}
\usepackage{booktabs}
\hypersetup{pdfauthor=The LaTeX Project,
 pdftitle=l3pdfoutline (LaTeX PDF management bundle)}
\begin{document}
  \DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
% \providecommand\hook[1]{\texttt{#1}}
% \title{^^A
%   The \pkg{l3pdfoutline} module\\ Commands for PDF bookmarks   ^^A
%   \\ \LaTeX{} PDF management bundle
% }
%
% \author{^^A
%  The \LaTeX{} Project\thanks
%    {^^A
%      E-mail:
%        \href{mailto:latex-team@latex-project.org}
%          {latex-team@latex-project.org}^^A
%    }^^A
% }
%
% \date{Version 0.97a, released 2026-04-21}
%
% \maketitle
% \begin{documentation}
%
% \section{\pkg{l3pdfoutline} documentation}
% \subsection{Introduction}
% This module contains a number of commands to create the PDF outline, also
% called bookmarks.
%
% \emph{Attention:} There can be only one outline in a PDF and
% the commands of this module should not be mixed
% with other code that creates outline items, this would mess up the tree!
%
% A reference implementation that shows the use of the command is in \texttt{latex-lab-bookmark.dtx},
% a package that can replace the package \pkg{bookmark}.
%
% The outline is a tree build with a set of objects.
% The root is the \emph{outline dictionary}
% which is referenced from the catalog with the \texttt{/Outline} key. The other objects
% are called \emph{outline items}.
%
% The dictionaries of the \emph{outline items} contain
% keys which can be divided into three classes:
% \begin{description}
% \item[\enquote{Management}]
% The connection between the root, the items and their children
% are described with keys \texttt{/Parent}, \texttt{/Next}, \texttt{/Prev}, \texttt{/First},
% \texttt{/Last}. The \texttt{/Count} key describes how many subitems are visible (open).
%
% \item[\enquote{Attributes}]
% The \texttt{/Title} key contains the text shown in the bookmarks,
% \texttt{/C} sets its color, the flag \texttt{/F} sets the font type (italic and/or bold).
% There is a \texttt{/SE} key which can reference a structure, but
% its function is unclear (the note in the reference says, that it is not meant for
% navigation, but does not say what it is for).
%
%
% \item[\enquote{Action}]
% The action that should be executed can be set either with an \texttt{/A} or a
% \texttt{/Dest} key. \LaTeX{} typically uses only the first option and adds an action,
% e.g., for a simple link to a destination something like
% |<< /S /GoTo /D (section.1) /SD 19 0 R >>|
% (the \texttt{SD} key is used when there are structures).
%
% While in most cases the outline is used with a \texttt{GoTo} action and more or less mirrors
% the  table of contents, other actions are possible too, an outline item
% can, e.g., open an external url or another file. The PDF reference lists in total
% 17 different, theoretically usable actions\footnote{Sound and Movie are deprecated in PDF~2.0}:
% GoTo, GoToR, GoToE, GoToDp (PDF~2.0), Launch, Thread, URI, Sound, Movie,
% Hide, Named, SetOCGState, Rendition, Trans, GoTo3DView, JavaScript, RichMediaExecute.
%
% An action dictionary typically looks like this:
% \begin{verbatim}
% /A << /Type /Action %optional
%       /S    ... % type name, e.g. /URI or /GoTo
%       /Next ... % optional, next action
%       ...   ... % more keys
%    >>
% \end{verbatim}
%
% The |/Next| key allows to chain actions. The value can be a reference to a
% single action, or an array of actions.
% It depends on the action type which other keys should be used.
%
% From all these action types the \pkg{bookmark} package supports |GoTo| (through the
% |dest| and |page| keys), |GoToR| (through the |gotor| key together
% with the |dest| and |page| keys),
% |Named| (through the |named| key) and |URI| (through the |uri| key).
% These standard types looks like this:
%  \begin{description}
%  \item[GoTo link to a named destination] e.g.
%  |/S /GoTo /D (section.1) /SD 19 0 R|, this can be handled with |\pdfoutline_goto:nnn|.
%
%  \item[GoTo link to a page] |/S /GoTo /D [5 0 R /FitH 0]|
%
%  \item[Named] e.g. |/S/Named/N/FirstPage|, values are \texttt{FirstPage},
%  \texttt{NextPage}, \texttt{PrevPage}, \texttt{LastPage}.
%
%  \item[URI] e.g.|/S/URI/URI(https://blub.de)|
%
%  \item[GoToR] |/S/GoToR/F(blub.pdf)/D[0/Fit]|, |/S/GoToR/F(blub.pdf)/D[3/FitH 0]|,
%  |/S/GoToR/F(blub.pdf)/D(duck)|
%  \end{description}
% All other actions (and also chained actions) are not
% directly supported by \pkg{bookmark} but can be
% implemented by using the |rawaction| key.
% \end{description}
%
% Theoretically all needed objects described above could be created manually,
% but getting all the management keys right wouldn't be trivial.
% For \texttt{/Count} e.g. one would have to track recursively
% the number of visible subitems. Luckily all backends have
% dedicated primitives or \verb+\special+'s to create outline items which take
% care of the management keys. Not quite so lucky is that the
% backends use different methods to decide if
% an outline item is a sibling or a child or some great-uncle of the previous item.
%
% The \texttt{(x)dvipdfmx} backend has the easiest implementation:
% The general syntax is \verb+\special{pdf:out [-]number << attr>>}+
% where the parameter \emph{number} is an integer representing
% the level of the outline entry. The first item
% has to start with the level 1 and one can't skip levels, so one can't
% simply use a fixed number for the various headings; instead one has to keep track of
% which level has been used previously. This is a bit awkward, nevertheless with this backend
% it is possible to build the outline directly while compiling the document and
% one doesn't have to use the \texttt{aux} or to delay code until the end of the document.
%
% When using \pdfTeX{}, lua\TeX{} or the \texttt{dvips} backend, a count must be given
% in the primitive which describes the number of direct children of the outline.
% The backend then collects (recursively) following items until all children are found
% and then goes up a level again.
% To get this number the code has to obviously look ahead
% to count all subsections below the current section. \pkg{hyperref} solved
% this problem by writing everything into the \texttt{.out} file and to
% process it at begin of the next compilation to get the correct count.
% The \pkg{bookmark} package writes
% the content and attributes (hex encoded) into the \texttt{.aux}-file.
% Additionally it keeps track of the number of children during the compilation and
% stores it for every bookmark in a command. When the
% \texttt{.aux} file is read in again at the end of the document, it decodes
% content and attributes again and writes out all the outline objects. In
% this way it can produce the outline tree
% for \pdfTeX{} and lua\TeX{} directly in the
% first compilation. With the \texttt{dvips} backend it creates a \texttt{.ps} file
% which is then read in at the next compilation.
%
% The new implementation in this module doesn't use external files but keeps all
% bookmarks in memory and outputs them at the end of the document (for the
% dvi based engines in the shipout/lastpage hook, this can require a second compilation if the
% page numbers change).
%
% \subsection{The commands}
%
% \subsection{Creating an outline item}
% \begin{function}
%   {\pdfoutline_action:nnn,\pdfoutline_action:neo,\pdfoutline_action:nee}
%   \begin{syntax}
%     \cs{pdfoutline_action:nnn}\Arg{level}\Arg{action}\Arg{title}
%   \end{syntax}
%   This creates an outline item. \meta{level} is an integer expression
%   and sets the (relative) level: A positive
%   number creates a child of the current outline item, 0 creates a sibling,
%   and negative numbers go back.
%   \meta{action} should be a list of dictionary keys and its values
%   that can be used within the |/A| key, e.g. the  output from |\pdfdict_use:n|\footnote{It can
%   not be an object reference as this doesn't work with most backends.}\footnote{This is not completely
%   accurate: the dvips backend expects in some cases special names, e.g. a color must be given
%   with \texttt{/Color} and not \texttt{/C}. Complex actions must therefore be tested
%   and if needed one must add backend abstractions.}.
%   \meta{title} is the title, it should be
%   correctly escaped and encoded for use as a literal string
%   (but without the outer parentheses), such a representation can for example be created
%   with |\pdfstringdef| or with a combination of |\pdf_purify:nN| and
%   |\pdf_string_from_unicode:nnN| from the \texttt{l3pdftools} module.
%   The command can be used for general outline item, for the special case of
%   a GoTo link to a named destination see the following command.
% \end{function}
%
% \begin{function}
%   {\pdfoutline_goto:nnn,\pdfoutline_goto:neo,\pdfoutline_goto:nee}
%   \begin{syntax}
%     \cs{pdfoutline_goto:nnn}\Arg{level}\Arg{destination}\Arg{title}
%   \end{syntax}
%   This creates an outline which creates a link to a named destination.
%   While such a GoTo link can also be created with \cs{pdfoutline_action:nnn}
%   the use of this command is recommended as it will also create a reference to a
%   structure destination if tagging is activated.
%   \meta{level} is an integer expression
%   and sets the (relative) level: A positive
%   number creates a child of the current outline, 0 creates a sibling, and negative numbers
%   go back. \meta{destination} is a destination name.
%   \meta{title} is the title, it should be
%   correctly escaped and encoded for a use as a literal string
%   (but without the outer parentheses), such a representation can for example be created
%   with |\pdfstringdef| with a combination of |\pdf_purify:nN| and
%   |\pdf_string_from_unicode:nnN| from the \texttt{l3pdftools} module.
% \end{function}
%
% \begin{variable}
%   {\l_pdfoutline_active_bool}
%   This boolean decides if bookmarks are shown
%   at all.
% \end{variable}
%
% \begin{variable}
%   {\l_pdfoutline_open_bool}
%   This boolean decides if bookmarks are shown
%   \enquote{open}, so show their children or not.
% \end{variable}
%
% \begin{variable}
%   {\l_pdfoutline_open_int}
%   With this integer you can set the number of
%   visible levels. Bookmarks with a level above the value of this integer are
%   always closed. So if it is set to 1, everything is closed and so
%   only the top level bookmarks are shown
%   if its value is 2, the first level will show its children,
%   etc. By default this integer is set to |\c_max_int| and
%   so everything is open.
% \end{variable}
%
% \begin{variable}
%   {\l_pdfoutline_F_bitset}
%   This bitset is used to set the flag for the font in bookmarks.
%   It knows the two values \texttt{italic} and \texttt{bold}, so after
%   \begin{verbatim}
%   \bitset_set_true:Nn \l_pdfoutline_F_bitset {italic}
%   \end{verbatim}
%   italic will be enabled.
% \end{variable}
%
% \begin{variable}
%   {\l_pdfoutline_color_tl,\l_pdfoutline_color_model_tl}
%   \cs{l_pdfoutline_color_tl} can be empty or hold a color expression to set the color of
%   the outline(s). It then should have either the format |[model]{value}|
%   or be a color expression. For examples: |[rgb]{1,0,.5}| or |red!50!blue|.
%   \cs{l_pdfoutline_color_model_tl} should be |rgb| or |cmyk|. The first is
%   the normal one, the option to use also |cmyk| is only offered for the
%   case that some PDF/A validator complains.
% \end{variable}
%
% \subsection{References}
% A user package that uses these commands to create a tree must be able
% to retrieve parents and level data.
% \begin{function}[EXP]
%   {\pdfoutline_id_ref_last:,\pdfoutline_level_ref_last:}
%   \begin{syntax}
%     \cs{pdfoutline_id_ref_last:} \\
%     \cs{pdfoutline_level_ref_last:}
%   \end{syntax}
%   These expandable functions give back the id and the level
%   of the last bookmark created.
% \end{function}
%
% \begin{function}[EXP]{\pdfoutline_parent_ref:n}
% \begin{syntax}
%  \cs{pdfoutline_parent_ref:n}\Arg{id}
% \end{syntax}
% This retrieves the parent of the bookmark with id \meta{id}.
% If the bookmark is at the root level the value is 1.
% \end{function}
% \end{documentation}
%
% \begin{implementation}
%
% \section{\pkg{l3pdfoutline} implementation}
% \subsection{Package declaration}
%    \begin{macrocode}
%<@@=pdfoutline>
%<*header>
\ProvidesExplPackage{l3pdfoutline}{2026-04-21}{0.97a}
  {PDF outlines}
%</header>
%    \end{macrocode}
%    \begin{macrocode}
%<*package>
%    \end{macrocode}
%
% \subsection{Public variables}
% \begin{variable}{\l_pdfoutline_active_bool,\l_pdfoutline_open_bool}
% The state of the first boolean decides
% if a bookmark is created at all, this allows to disable bookmarks
% fully or in parts.
% The second boolean decides if a bookmark is open (so shows its children)
% or not.
%    \begin{macrocode}
\bool_new:N      \l_pdfoutline_active_bool
\bool_set_true:N \l_pdfoutline_active_bool
\bool_new:N      \l_pdfoutline_open_bool
\bool_set_true:N \l_pdfoutline_open_bool
%    \end{macrocode}
% \end{variable}
%
% \begin{variable}{\l_pdfoutline_open_int}
% This is the level up to which a bookmark is opened. By default the maximum
% integer value is used and everything is open.
%
%    \begin{macrocode}
\int_new:N  \l_pdfoutline_open_int
\int_set:Nn \l_pdfoutline_open_int { \c_max_int }
%    \end{macrocode}
% \end{variable}
%
% \begin{variable}{\l_pdfoutline_F_bitset}
% Outlines have a /F flag, we provide a public
% bitset for it.
%    \begin{macrocode}
\bitset_new:Nn \l_pdfoutline_F_bitset
  {
    Italic         = 1,
    italic         = 1,
    Bold           = 2,
    bold           = 2
  }
%    \end{macrocode}
% \end{variable}
%
% \begin{variable}{\l_pdfoutline_color_tl,\l_pdfoutline_color_model_tl}
% The variable for the color expression.
%    \begin{macrocode}
\tl_new:N  \l_pdfoutline_color_tl
\tl_new:N  \l_pdfoutline_color_model_tl
\tl_set:Nn \l_pdfoutline_color_model_tl {rgb}
%    \end{macrocode}
% \end{variable}
%
% \subsection{Data structure for the Count}
%
% \begin{variable}{\l_@@_tmpa_tl}
%    \begin{macrocode}
\tl_new:N\l_@@_tmpa_tl
%    \end{macrocode}
% \end{variable}

% \begin{variable}{\g_@@_id_int}
% This integer is used to track the bookmarks.
% id 1 is the root, the first \enquote{real} bookmark
% has id 2.
%    \begin{macrocode}
\int_new:N   \g_@@_id_int
\int_gincr:N \g_@@_id_int
%    \end{macrocode}
% \end{variable}
%
% \begin{variable}{\g_@@_current_parent_id_tl}
% This holds the id of the current parent
% so that we do not have to retrieve it all the time.
%    \begin{macrocode}
\tl_new:N   \g_@@_current_parent_id_tl
\tl_gset:Nn \g_@@_current_parent_id_tl {1}
%    \end{macrocode}
% \end{variable}
%
% \begin{variable}{\g_@@_current_level_int}
% This holds the (relative) level. It starts at 1 as dvipdfmx counts this way.
%    \begin{macrocode}
\int_new:N   \g_@@_current_level_int
\int_gincr:N \g_@@_current_level_int
%    \end{macrocode}
% \end{variable}
%
% We do not assume that we will ever have more than 2000 bookmarks, but we set a block
% size so that we can make the range dynamic if needed like in the object code.
%
% \begin{variable}{\c_@@_block_size_int}
% Sets the block size used for managing outlines.
%    \begin{macrocode}
\int_const:Nn \c_@@_block_size_int { 2000 }
%    \end{macrocode}
% \end{variable}
%
% For some backends we must know for every outline
% the numbers of direct children, and
% we must know the id of the parent to be able to go
% up the tree again. For this we use two intarray variables.
% \begin{variable}{\g_@@_kid_count_intarray,\g_@@_parent_id_intarray}
%   The first contains for every id the number of (direct) kids.
%   The second contains the id of the parent.
%    \begin{macrocode}
\intarray_new:Nn   \g_@@_kid_count_intarray { \c_@@_block_size_int }
\intarray_new:Nn   \g_@@_parent_id_intarray { \c_@@_block_size_int }
\intarray_gset:Nnn \g_@@_parent_id_intarray {1}{1}
%    \end{macrocode}
% \end{variable}
%
% Unlike \pkg{bookmark} we do not use an external file but keep all content in memory
% in one large tl var.
% \begin{variable}{\g_@@_collect_build_tl}
%    \begin{macrocode}
\tl_new:N \g_@@_collect_build_tl
%    \end{macrocode}
% \end{variable}
%
% The main commands
% \begin{macro}{\pdfoutline_action:nnn}
%    \begin{macrocode}
\cs_new_protected:Npn \pdfoutline_action:nnn #1 #2 #3
% #1 level, #2 action, #3 title
  {
    \bool_if:NT \l_pdfoutline_active_bool
      {
        \int_compare:nNnTF {\g_@@_id_int}={1}
         {
           \tl_build_gbegin:N \g_@@_collect_build_tl
           \@@_item:nnnn {0}{#2}{#3}{action}
           \tl_gput_right:Nn \g__kernel_pdfmanagement_end_run_code_tl
             {
               \tl_build_gend:N \g_@@_collect_build_tl
               \tl_use:N \g_@@_collect_build_tl
             }
         }
         {
           \@@_item:nnnn {#1}{#2}{#3}{action}
         }
        \cs_gset_protected:Npn \pdfoutline_action:nnn ##1 ##2 ##3
         {
           \bool_if:NT \l_pdfoutline_active_bool
             {\@@_item:nnnn {##1}{##2}{##3}{action}}
         }
     }
  }
\cs_generate_variant:Nn \pdfoutline_action:nnn {nee}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\pdfoutline_goto:nnn}
%    \begin{macrocode}
\cs_new_protected:Npn \pdfoutline_goto:nnn #1 #2 #3
% #1 level, #2 destination, #3 title
  {
   \bool_if:NT \l_pdfoutline_active_bool
      {
        \int_compare:nNnTF {\g_@@_id_int}={1}
         {
           \tl_build_gbegin:N \g_@@_collect_build_tl
           \@@_item:nnnn {0}{#2}{#3}{goto}
           \tl_gput_right:Nn \g__kernel_pdfmanagement_end_run_code_tl
             {
               \tl_build_gend:N \g_@@_collect_build_tl
               \tl_use:N \g_@@_collect_build_tl
             }
         }
         {
           \@@_item:nnnn {#1}{#2}{#3}{goto}
         }
        \cs_gset_protected:Npn \pdfoutline_goto:nnn ##1 ##2 ##3
         {
           \bool_if:NT \l_pdfoutline_active_bool
             {\@@_item:nnnn {##1}{##2}{##3}{goto}}
         }
     }
  }
\cs_generate_variant:Nn \pdfoutline_goto:nnn {nee}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_item:nnnn}
%    \begin{macrocode}
\cs_new_protected:Npn \@@_item:nnnn #1 #2 #3 #4
% #1 level, #2 action, #3 title, #4 keyword action or goto
  {
    \int_gincr:N \g_@@_id_int
%    \end{macrocode}
% Follow up bookmarks. At first siblings.
% The parent doesn't change.
%    \begin{macrocode}
    \int_compare:nNnTF {#1}={0}
      {
        \intarray_gset:Nnn
          \g_@@_parent_id_intarray
          { \g_@@_id_int }
          { \g_@@_current_parent_id_tl }
        \intarray_gset:Nnn
          \g_@@_kid_count_intarray
          { \g_@@_current_parent_id_tl }
          { \intarray_item:Nn \g_@@_kid_count_intarray { \g_@@_current_parent_id_tl } + 1 }
       }
       {
%    \end{macrocode}
% The first child of the previous bookmark
%    \begin{macrocode}
         \int_compare:nNnTF {#1} > {0}
           {
             \int_gincr:N \g_@@_current_level_int
             \tl_gset:Ne \g_@@_current_parent_id_tl
               { \int_eval:n { \g_@@_id_int -1 } }
             \intarray_gset:Nnn
               \g_@@_parent_id_intarray
                { \g_@@_id_int }
                { \g_@@_current_parent_id_tl }
             \intarray_gset:Nnn
               \g_@@_kid_count_intarray
               { \g_@@_current_parent_id_tl }
               { 1 }
            }
%    \end{macrocode}
% The most complicated case: going up the hierarchy.
% The root level is 1, so we can go up at most current level minus 1
% steps. If we are already at the root level, the current parent is 1.
%    \begin{macrocode}
           {
             \int_compare:nNnTF { \g_@@_current_level_int } = {1}
              {
                \tl_gset:Ne \g_@@_current_parent_id_tl {1}
              }
              {
                \int_step_inline:nn
                  { \int_min:nn { \int_abs:n {#1} } { \g_@@_current_level_int -1 } }
                  {
%    \end{macrocode}
% Get recursively the parent of the current parent and decrease the level.
%    \begin{macrocode}
                    \tl_gset:Ne \g_@@_current_parent_id_tl
                      { \intarray_item:Nn \g_@@_parent_id_intarray { \g_@@_current_parent_id_tl } }
                    \int_gdecr:N \g_@@_current_level_int
                  }
              }
%    \end{macrocode}
% Store the parent and
% increase the kid count of the finally found parent (if this is the root level,
% the id is 1)
%    \begin{macrocode}
             \intarray_gset:Nnn
               \g_@@_parent_id_intarray
                { \g_@@_id_int }
                { \g_@@_current_parent_id_tl }
             \intarray_gset:Nnn
               \g_@@_kid_count_intarray
               { \g_@@_current_parent_id_tl }
               {
                 \intarray_item:Nn
                  \g_@@_kid_count_intarray
                  { \g_@@_current_parent_id_tl } + 1
               }
           }
       }
%    \end{macrocode}
% Now we store the collected data into the tl var.
%    \begin{macrocode}
     \@@_store:nnn {#2}{#3}{#4}
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_color_export:nnN}
% This exports space separated values from a color expression or a |[model]{values}|
% expression. It is used in the next command.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_color_export_aux:wnnN [#1] #2 #3 #4
  {
     \color_export:nnnN {#1}{#2}{ space-sep-#3 }#4
  }
\cs_new_protected:Npn \@@_color_export:nnN #1 #2 #3 %#1 color, #2 target model, #3 command
  {
    \tl_if_blank:nTF { #1 }
     { \tl_clear:N #3 }
     {
       \tl_if_head_eq_charcode:nNTF {#1} [ %]
        {
          \@@_color_export_aux:wnnN #1 { #2 } #3
        }
        {
          \color_export:nnN { #1 } { space-sep-#2 } #3
        }
     }
  }
\cs_generate_variant:Nn \@@_color_export:nnN {ee}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_store:nnn}
% This command stores the data into the tl var. The backends have different requirements
% regarding the handling, so we keep arguments separate and generic to stay flexible.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_store:nnn #1 #2 #3
% #1: action or destination, #2: title, #3: keyword action or goto
  {
    \int_compare:nNnF { \g_@@_current_level_int } < { \l_pdfoutline_open_int }
      { \bool_set_false:N \l_pdfoutline_open_bool }
    \@@_color_export:eeN {\l_pdfoutline_color_tl}{\l_pdfoutline_color_model_tl}\l_@@_tmpa_tl
    \tl_build_gput_right:Ne \g_@@_collect_build_tl
      {
        \exp_not:N \use:c { __pdf_backend_#3:nnnnnnn }
        % #1 level, #2 kid count, #3 open? #4 color, #5 flag, #6 action/destination, #7 title,
          {
            \int_use:N \g_@@_current_level_int
          }
          {
            \exp_not:N \intarray_item:Nn
              \exp_not:N \g_@@_kid_count_intarray
              { \int_use:N \g_@@_id_int }
          }
          {
            \bool_if:NTF\l_pdfoutline_open_bool {\exp_not:N \c_true_bool }{ \exp_not:N \c_false_bool}
          }
          {
            \l_@@_tmpa_tl
          }
          {
            \bitset_to_arabic:N \l_pdfoutline_F_bitset
          }
          {
            \exp_not:n {#1} % action/destination, or expand??
          }
          {
            \exp_not:n {#2} % title, or expand??
          }
       }
  }
%    \end{macrocode}
% \end{macro}
%
% \subsection{References}
% \begin{macro}{\pdfoutline_id_ref_last:,}
%    \begin{macrocode}
\cs_new:Npn \pdfoutline_id_ref_last: {\int_use:N\g_@@_id_int}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\pdfoutline_level_ref_last:}
%    \begin{macrocode}
\cs_new:Npn \pdfoutline_level_ref_last: {\int_use:N\g_@@_current_level_int}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\pdfoutline_parent_ref:n}
%    \begin{macrocode}
\cs_new:Npn \pdfoutline_parent_ref:n #1 { \intarray_item:Nn\g_@@_parent_id_intarray{#1} }
%</package>
%    \end{macrocode}
% \end{macro}
%
% \end{implementation}
%
% \PrintIndex
