summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/latex-lab/latex-lab-float.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/latex-lab/latex-lab-float.dtx')
-rw-r--r--Master/texmf-dist/source/latex/latex-lab/latex-lab-float.dtx494
1 files changed, 494 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-float.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-float.dtx
new file mode 100644
index 00000000000..430b2aec96c
--- /dev/null
+++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-float.dtx
@@ -0,0 +1,494 @@
+% \iffalse meta-comment
+%
+%% File: latex-lab-float.dtx (C) Copyright 2023 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
+%
+% https://www.latex-project.org/lppl.txt
+%
+%
+% The development version of the bundle can be found below
+%
+% https://github.com/latex3/latex2e/required/latex-lab
+%
+% for those people who are interested or want to report an issue.
+%
+%<*driver>
+\documentclass{l3doc}
+\EnableCrossrefs
+\CodelineIndex
+\begin{document}
+ \DocInput{latex-lab-float.dtx}
+\end{document}
+%</driver>
+%
+% \fi
+%
+%
+% \title{The \textsf{latex-lab-floats} package\\
+% Tagging of floats }
+% \author{\LaTeX{} Project\thanks{Initial implementation done by Ulrike Fischer}}
+% \date{v0.81 2023-06-07}
+%
+% \maketitle
+%
+% \newcommand{\xt}[1]{\textsl{\textsf{#1}}}
+% \newcommand{\TODO}[1]{\textbf{[TODO:} #1\textbf{]}}
+% \newcommand{\docclass}{document class \marginpar{\raggedright document class
+% customizations}}
+%
+% \providecommand\hook[1]{\texttt{#1}}
+% \begin{documentation}
+% \begin{abstract}
+% The following code implements a first draft for the tagging of float
+% environments
+% \end{abstract}
+%
+%
+% \section{Introduction}
+%
+% The code here handle the tagging of float environments.
+%
+% Figures (and tables) are in \LaTeX{} typically typeset in float environments.
+% These are boxes which can \emph{float} away to special float areas on the pages,
+% e.g., to the top or the bottom of a page or to special float pages.
+% If the rules allow it they can also be placed in the main text stream (\enquote{here}).
+% Floats can also be collected at the end of the document.
+% In either case the order within each type of floats
+% (e.g., figures, tables, algorithms, etc.) is preserved.
+%
+% A special type, called a H-float, (provided by the float package)
+% is always placed in the main text stream and does not
+% necessarly preserve the order with normal floats of the same type: It is basically
+% a minipage with a caption.
+%
+% Floats typically contain a figure (or a table, etc.) and a caption,
+% but more complex constructions with subfigures,
+% copyright statements, sources or additional description are possible too.
+%
+% In the \LaTeX{} source a float is normally more or less at the place of
+% the first call-out, but when preparing a document for print the code
+% is sometimes moved to place floats in a more visually pleasing way.
+%
+% \section{Tagging}
+%
+% Floats (with the exception of H-floats) do not belong into the text stream, they
+% are \enquote{consultation objects}: Readers must be able to choose if and when they read the float.
+% Floats have captions, the PDF rules require that a \texttt{Caption} is the first or last
+% structure in its parent structure.
+% This poses some challenges on a good tagging.
+%
+% In PDF~2.0 there is the suitable \texttt{Aside} tag which hopefully will
+% be handled correctly regarding the reading order once processor actually support
+% PDF~2.0. But in PDF~1.7 we rolemap it to \texttt{Note} and this doesn't lead to
+% a good reading order. The code therefore collect the float structures and moves
+% them to a \texttt{Sect} the end of the document or the chapter
+% (H-floats once they are handled will not be moved).
+%
+% To fulfill the requirement that a \texttt{Caption} should be at the begin or end, we always
+% move it to the begin of the structure. If a float has two captions the author
+% has to insert a command which splits the float in two.
+%
+% Subfigures and subcaptions are currently not handled, but will be implemented
+% as simple \texttt{Part} with their own \texttt{Caption}.
+%
+% \section{Links}
+% The code disable the caption patches from hyperref. It will add an anchor at the
+% begin of the float or a split. It changes caption so that a link to a caption label
+% will go to the begin of the float.
+%
+% \section{Tools}
+%
+% The code add two keys for the \cs{tagtool} command
+%
+% \begin{description}
+% \item[flush-floats] This will flush out the collected floats sofar (currently
+% table and figure. The value is a sectioning level, e.g. \texttt{section} or \texttt{chapter},
+% the floats will then inserted as a \texttt{Sect} of this level (all \texttt{Sect} of smaller or equal
+% level are closed). The key then starts a new container for following floats.
+% If no value is given, the \texttt{Sect} is at the document level. The code automatically
+% flush all open floats at the end of the document.
+%
+% \item[split-float] This can be used inside a float if there are two captions.
+% It will only work reasonably well if the content of the float parts are in a sensible order
+% and can be separated by this command. More complex setups with tabulars will need more
+% thoughts
+%
+% \end{description}
+%
+%
+% \begin{macrocode}
+%<@@=tag>
+%<*package>
+% \end{macrocode}
+% \end{documentation}
+% \begin{implementation}
+% \section{Implementation}
+% \begin{macrocode}
+\ProvidesExplPackage {latex-lab-testphase-float} {2023-04-28} {0.8}
+ {Code related to the tagging of floats}
+% \end{macrocode}
+% \subsection{Variables}
+% We rolemap to Aside, and float sections to Sect
+%
+% \begin{macrocode}
+\tagpdfsetup{add-new-tag=float/Aside}
+\tagpdfsetup{add-new-tag=figures/Sect}
+\tagpdfsetup{add-new-tag=tables/Sect}
+% \end{macrocode}
+%
+% \begin{variable}{
+% \g_@@_float_sect_prop,
+% \g_@@_float_types_seq,
+% \@current@float@struct
+% }
+% These variables will hold the structure number for the float container
+% and the list of float types. Currently only figure and table are supported
+% TODO: interface to declare new float types.
+% \begin{macrocode}
+\prop_new:N \g_@@_float_sect_prop
+\seq_new:N \g_@@_float_types_seq
+\seq_gput_right:Nn \g_@@_float_types_seq {figure}
+\seq_gput_right:Nn \g_@@_float_types_seq {table}
+\tl_new:N\@current@float@struct
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_float_sect_bool}
+% With this boolean float collection is switched on and off.
+% Currently it is always on and set globally.
+% TODO: think if an interface is needed.
+% TODO: would a local variable make more sense?
+% \begin{macrocode}
+\bool_new:N \g_@@_float_sect_bool
+\bool_gset_true:N \g_@@_float_sect_bool
+% \end{macrocode}
+% \end{variable}
+%
+%
+%\subsection{Moving float structures}
+%
+% Currently it is for all float types or none.
+% Probably we will need some more options here to select some float types.
+%
+% \begin{macro}{\@@_float_init_collect:}
+% This initializes a container structure for every float type.
+% It can be used more than once in a document, this allows to have e.g.
+% chapter wise containers.
+% \begin{macrocode}
+\cs_new_protected:Npn\@@_float_init_collect:
+ {
+ \bool_if:NT\g_@@_float_sect_bool
+ {
+ \seq_map_inline:Nn\g_@@_float_types_seq
+ {
+ \tag_struct_begin:n{tag=##1s,stash}
+ \prop_gput:Nnx\g_@@_float_sect_prop {##1-struct}{\int_use:N\c@g__tag_struct_abs_int}
+ \tag_struct_end:
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_float_stop_sect:}
+% This pushes out the floats. For every type is checks if there is actually
+% a float of this type and then writes out the container structure.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_float_stop_sect:
+ {
+ \bool_if:NT\g_@@_float_sect_bool
+ {
+ \seq_map_inline:Nn\g_@@_float_types_seq
+ {
+ \prop_get:NnNT\g_@@_float_sect_prop{##1-used}\l_@@_tmpa_tl
+ {
+ \exp_args:Ne
+ \tag_struct_use_num:n{\prop_item:Nn\g_@@_float_sect_prop{##1-struct}}
+ \prop_gremove:Nn \g_@@_float_sect_prop{##1-used}
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{flush-floats}
+% This is a key for \cs{tagtool} to flush out the collected floats.
+% The value allows to set to which level the create Sect contains.
+% So \texttt{section} will close all previous Sect until the section level
+% and create a new section.
+% \begin{macrocode}
+\keys_define:nn { tag / tool}
+ {
+ flush-floats .code:n =
+ {
+ \keys_set:nn {tag / tool} {sec-stop=#1}
+ \@@_float_stop_sect:
+ \@@_float_init_collect:
+ },
+ flush-float .default:n = Document
+ }
+% \end{macrocode}
+% \end{macro}
+% We need at least one pair
+% \begin{macrocode}
+\AddToHook{begindocument/end}[latex-lab/float]
+ {\@@_float_init_collect:}
+\AddToHook{tagpdf/finish/before}[latex-lab/float]
+ {\par\__tag_sec_end:n{-10}\@@_float_stop_sect:}
+\DeclareHookRule{tagpdf/finish/before}{latex-lab/float}{before}{tagpdf}
+% \end{macrocode}
+% \subsection{Splitting floats}
+% \begin{macro}{split-float}
+% TODO: check if the target affect spacing!!
+% \begin{macrocode}
+\keys_define:nn { tag / tool}
+ {
+ split-float .code:n =
+ {
+ \@@_float_end:
+ \@@_float_begin:
+ \MakeLinkTarget[tagstructure]{g__tag_struct_abs_int}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+
+% \subsection{Patching}
+% \begin{macro}{\@@_float_stop_par:,\@@_float_start_par:}
+% if a float is in a par, we need commands to stop and restart the P-mc
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_float_stop_par:
+ {
+ \tag_mc_end:
+ \bool_if:NF \g_@@_float_sect_bool
+ {
+ \tag_struct_end:
+ }
+ }
+\cs_new_protected:Npn \@@_float_start_par:
+ {
+ \bool_if:NF \g_@@_float_sect_bool
+ {
+ \tag_struct_begin:n{tag=text}%
+ }
+ \tag_mc_begin:n{tag=P}
+ }
+
+% \end{macrocode}
+% \end{macro}
+% These commands are the main commands to start and end the float tagging.
+%
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_float_begin:
+ {%
+% \end{macrocode}
+% We test if the float structure should be included directly or move to a dedicated section.
+% \begin{macrocode}
+ \bool_if:NTF\g_@@_float_sect_bool
+ {
+ \exp_args:Ne
+ \tag_struct_begin:n{tag=float,parent=0\prop_item:No\g_@@_float_sect_prop{\@captype-struct}}%
+ \prop_gput:Nxx \g_@@_float_sect_prop {\@captype-used}{true}
+ }
+ {
+ \tag_struct_begin:n{tag=float}
+ }
+ \tl_set:Nx\@current@float@struct{\tag_get:n{struct_num}}%
+ \typeout{Float structure: \@current@float@struct}
+ }
+
+\cs_new_protected:Npn\@@_float_end:{\tag_struct_end:} %end Aside
+
+% \end{macrocode}
+% This patches the main command \cs{@xfloat}.
+% There is a : in the code, so we disable expl3 syntax
+% \begin{macrocode}
+\ExplSyntaxOff
+\def\@xfloat #1[#2]{%
+ \@nodocument
+ \def \@captype {#1}%
+ \def \@fps {#2}%
+ \@onelevel@sanitize \@fps
+ \def \reserved@b {!}%
+ \ifx \reserved@b \@fps
+ \@fpsadddefault
+ \else
+ \ifx \@fps \@empty
+ \@fpsadddefault
+ \fi
+ \fi
+ \ifhmode
+ \@bsphack
+% \end{macrocode}
+% If the float is in hmode we have to interrupt the P
+% \begin{macrocode}
+ \@nameuse{@@_float_stoppar:} %<---end P
+ \@floatpenalty -\@Mii
+ \else
+ \@floatpenalty-\@Miii
+ \fi
+ \ifinner
+ \@parmoderr\@floatpenalty\z@
+ \else
+ \@next\@currbox\@freelist
+ {%
+ \@tempcnta \sixt@@@@n
+ \expandafter \@tfor \expandafter \reserved@a
+ \expandafter :\expandafter =\@fps
+ \do
+ {%
+ \if \reserved@a h%
+ \ifodd \@tempcnta
+ \else
+ \advance \@tempcnta \@ne
+ \fi
+ \else\if \reserved@a t%
+ \@setfpsbit \tw@
+ \else\if \reserved@a b%
+ \@setfpsbit 4%
+ \else\if \reserved@a p%
+ \@setfpsbit 8%
+ \else\if \reserved@a !%
+ \ifnum \@tempcnta>15
+ \advance\@tempcnta -\sixt@@@@n\relax
+ \fi
+ \else
+ \@latex@error{Unknown float option `\reserved@a'}%
+ {Option `\reserved@a' ignored and `p' used.}%
+ \@setfpsbit 8%
+ \fi\fi\fi\fi\fi
+ }%
+ \@tempcntb \csname ftype@\@captype \endcsname
+ \multiply \@tempcntb \@xxxii
+ \advance \@tempcnta \@tempcntb
+ \global \count\@currbox \@tempcnta
+ }%
+ \@fltovf
+ \fi
+% \end{macrocode}
+% This starts the structure for the float.
+% \begin{macrocode}
+ \@nameuse{@@_float_begin:}%
+ \global \setbox\@currbox
+ \color@vbox
+ \normalcolor
+ \vbox \bgroup
+ \hsize\columnwidth
+ \@parboxrestore
+ \@floatboxreset
+% \end{macrocode}
+% We add a target for links. TODO: check that it doesn't affect spacing!!
+% \begin{macrocode}
+ \MakeLinkTarget[tagstructure]{g__tag_struct_abs_int}%
+}%
+% \end{macrocode}
+% The end code of the float ...
+% \begin{macrocode}
+\def\end@float{%
+ \@endfloatbox
+ \@nameuse{@@_float_end:}%
+ \ifnum\@floatpenalty <\z@
+ \@largefloatcheck
+ \@cons\@currlist\@currbox
+ \ifnum\@floatpenalty <-\@Mii
+ \penalty -\@Miv
+ \@tempdima\prevdepth
+ \vbox{}%
+ \prevdepth\@tempdima
+ \penalty\@floatpenalty
+ \else
+ \vadjust{\penalty -\@Miv \vbox{}\penalty\@floatpenalty}\@Esphack
+ \@nameuse{@@_float_start_par:} %restart P safe here??
+ \fi
+ \fi
+}
+\ExplSyntaxOn
+% \end{macrocode}
+%
+% \subsection{Handling captions}
+%
+% To avoid that hyperref interferes we disable its patches:
+% \begin{macrocode}
+\def\hyper@nopatch@caption{}
+% \end{macrocode}
+% As we will use the structure number in the target, we need to provide a
+% theH-representation. (Once the kernel will create
+% theH-representation generally this will be provided automatically, as tagpdf uses
+% \cs{newcounter})
+% \begin{macrocode}
+\providecommand\theHg__tag_struct_abs_int{\int_use:N\c@g__tag_struct_abs_int}
+% \end{macrocode}
+
+% \begin{macro}{\@makecaption}
+% \cs{@makecaption} is defined by the classes so we overwrite it for now
+% at begin document.
+% \begin{macrocode}
+\AddToHook{begindocument}
+ {
+ \long\def\@makecaption#1#2{%
+ \vskip\abovecaptionskip
+ \xdef\@currentHref{tagstructure.\@current@float@struct}%
+% \end{macrocode}
+% we don't want tagging when storing the caption for the singleline check
+% \begin{macrocode}
+ \tag_stop:n{caption}
+ \sbox\@tempboxa{#1:~#2}%
+ \tag_start:n{caption}
+% \end{macrocode}
+% we stop paratagging. TODO: check
+% \begin{macrocode}
+ \tagtool{para=false}
+ \tag_struct_begin:n{tag=Caption,parent=\@current@float@struct}
+% \end{macrocode}
+% move the caption to the begin of the float structure:
+% \begin{macrocode}
+ \seq_gpop_right:cN {g__tag_struct_kids_\@current@float@struct _seq}\l_@@_tmpa_tl
+ \seq_gput_left:cV {g__tag_struct_kids_\@current@float@struct _seq}\l_@@_tmpa_tl
+ \ifdim \wd\@tempboxa >\hsize
+ \tag_struct_begin:n{tag=Lbl}
+ \tag_mc_begin:n{}
+ #1:~
+ \tag_mc_end:
+ \tag_struct_end:
+ \tag_mc_begin:n{}
+ #2\par
+ \tag_mc_end:
+ \else
+% \end{macrocode}
+% we don't reuse the box as it doesn't contain tagging, but set the text explicitly.
+% \begin{macrocode}
+ \global \@minipagefalse
+ \hb@xt@\hsize{\hfil
+ \tag_struct_begin:n{tag=Lbl}
+ \tag_mc_begin:n{}
+ #1:~
+ \tag_mc_end:
+ \tag_struct_end:
+ \tag_mc_begin:n{}
+ #2\par
+ \tag_mc_end:\hfil}%
+ \fi
+ \tag_struct_end: %caption
+ \vskip\belowcaptionskip}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+
+% \begin{macrocode}
+%<*latex-lab>
+\ProvidesFile{float-latex-lab-testphase.ltx}
+ [2023-04-30 v0.8 code related to the tagging of floats]
+\RequirePackage{latex-lab-testphase-float}
+%</latex-lab>
+% \end{macrocode}
+% \end{implementation}