diff options
Diffstat (limited to 'macros/latex-dev/required/latex-lab/latex-lab-marginpar.dtx')
-rw-r--r-- | macros/latex-dev/required/latex-lab/latex-lab-marginpar.dtx | 259 |
1 files changed, 259 insertions, 0 deletions
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-marginpar.dtx b/macros/latex-dev/required/latex-lab/latex-lab-marginpar.dtx new file mode 100644 index 0000000000..ca79d8a67f --- /dev/null +++ b/macros/latex-dev/required/latex-lab/latex-lab-marginpar.dtx @@ -0,0 +1,259 @@ +% \iffalse meta-comment +% +%% File: latex-lab-marginpar.dtx +%% +% Copyright (C) 2024 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. +% +\def\ltlabmarginpardate{2024-02-12} +\def\ltlabmarginparversion{0.85b} + +%<*driver> +\documentclass[kernel]{l3doc} +\EnableCrossrefs +\CodelineIndex +\begin{document} + \DocInput{latex-lab-marginpar.dtx} +\end{document} +%</driver> +% +% \fi +% +% \title{The \textsf{latex-lab-marginpar} package\\ +% Changes related to the tagging of margin notes} +% \author{\LaTeX{} Project\thanks{Initial implementation done by Ulrike Fischer}} +% \date{v\ltlabmarginparversion\ \ltlabmarginpardate} +% +% \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\DescribeHook[noprint]{#1}}} +% \providecommand\socket[1]{\texttt{#1\DescribeSocket[noprint]{#1}}} +% \providecommand\plug[1]{\texttt{#1\DescribePlug[noprint]{#1}}} +% +% \NewDocElement[printtype=\textit{socket},idxtype=socket,idxgroup=Sockets]{Socket}{socketdecl} +% \NewDocElement[printtype=\textit{hook},idxtype=hook,idxgroup=Hooks]{Hook}{hookdecl} +% \NewDocElement[printtype=\textit{plug},idxtype=plug,idxgroup=Plugs]{Plug}{plugdecl} +% +% \begin{abstract} +% \end{abstract} +% +% \section{Introduction} +% +% This module contains changes to improve the tagging (in the standard classes) of +% margin notes created with the \cs{marginpar} command. +% +% Such margin notes are rather small but nevertheless tagging is not trivial and poses +% a number of interesting problems both regarding the structure and the implementation. +% +% \subsection{Structure} +% \cs{marginpar} creates small boxes in the margin of a page. +% While they are technically floats they also typically +% relate to the paragraph beside them, so their structure element should be placed near +% such a paragraph. +% +% They can be tagged either as artifacts (if they are merely distracting decoration), +% as small headings before the paragraph, or as |Aside|. Unlike the PDF 1.7 fallback |Note| +% the structure |Aside| is not allowed inside |P|, +% so if |Aside| is used, it must be placed before or after the current |P| in the surounding |text-unit|, +% or it must split the |P|. Splitting is probably not so good as +% |\marginpar| is often used somewhere in the middle of sentence. +% The best default is probably to use |Aside|, find the parent |text-unit| and add it there. +% +% \subsection{Implementation} +% +% |marginpar| has an optional argument which allows to define a different content +% on left/right margins for odd/even pages (depending on twoside and \cs{reversemarginpar}). +% +% The current implementation stores *both* arguments in boxes and +% decides in the output routine which +% one to use. This is quite problematic for tagging, as the unused box produces +% structure objects, literals, labels, MCID numbers, +% and perhaps OBJR-objects from links +% which must be later thrown away again (or are thrown away by the engine). +% While it is theoretically not impossible to create +% both boxes while taging is active but to keep everything on hold and insert +% the real structure only when the box is used it is in practice quite difficult, +% slow and error prone. +% +% There are a number of options to avoid this hassle. +% +% \begin{description} +% \item[Minimal tagging] One option is to disable tagging when the boxes +% are built and when the box is used to surround them with a simple Aside. +% +% \begin{description} +% \item[Pro:] easy to implement +% \item[Contra:] +% Content that perhaps needed tagging (|\LaTeX| logo with /ActualText, images, links) is not tagged. +% \end{description} +% +% \item[Remaking the box] +% Tagging is deactivated when the boxes are created. +% The arguments are stored and when the box should be used in the output routine +% (and when it is known which one will be used) the box is (re)created, now with proper tagging. +% +% Contra: The content can change e.g. if it uses counters or macros that are redefine later before the +% output routine is called. As tagging is done later, it is not trivial to insert the +% |Aside| in the right place in the paragraph structure. +% +% \item[Two pass compilation] +% A label is used to detect which argument/boxed is used and +% tagging is activated only for this one. +% +% Contra: costs a |label| and requires a two pass compilation (which is needed anyway). +% This should be ok. |\marginnote| uses a label too, and the same +% label could also be used to resolve problems if a margin note +% moves to a new page (and so replace the mparhack package). +% \end{description} +% +% The last option seems the best and is therefore implemented. +% +% +% \section{Implementation} +% \begin{macrocode} +%<*package> +%<@@=tag> +% \end{macrocode} +% \begin{macrocode} +\ProvidesExplPackage {latex-lab-testphase-marginpar} {\ltlabmarginpardate} {\ltlabmarginparversion} + {Changes related to the tagging of the margin notes} +% \end{macrocode} +% \subsection{Variables} +% We need a variable to make the label unique. +% Todo: Not sure about the name. +% \begin{macro}{\g__kernel_marginpar_int} +% \begin{macrocode} +\int_new:N \g__kernel_marginpar_int +% \end{macrocode} +% \end{macro} +% +% \subsection{Tagging sockets} +% +% \begin{socketdecl}{tagsupport/marginpar/begin,tagsupport/marginpar/end} +% \begin{macrocode} +\socket_new:nn {tagsupport/marginpar/begin}{0} +\socket_new:nn {tagsupport/marginpar/end}{0} +% \end{macrocode} +% \end{socketdecl} +% \begin{plugdecl}{tagsupport/marginpar/begin,tagsupport/marginpar/end} +% \begin{macrocode} +\socket_new_plug:nnn {tagsupport/marginpar/begin}{default} + { + \if_mode_horizontal: + \tag_mc_end: + \tag_struct_begin:n{tag=Aside,parent=\g__tag_para_main_struct_tl}% + \else: + \tag_struct_begin:n{tag=Aside}% + \fi: + } +\socket_new_plug:nnn {tagsupport/marginpar/end}{default} + { + \tag_struct_end: + \if_mode_horizontal: \tag_mc_begin:n{} \fi: + } +\socket_assign_plug:nn {tagsupport/marginpar/begin}{default} +\socket_assign_plug:nn {tagsupport/marginpar/end}{default} +% \end{macrocode} +% \end{plugdecl} + +% \subsection{Kernel command changes} +% \begin{macro}{\@savemarbox } +% We add sockets that add a tagging structure Aside: +% \begin{macrocode} +\long\def \@savemarbox #1#2{% + \UseTaggingSocket{marginpar/begin} + \global\setbox #1% + \color@vbox + \vtop{% + \hsize\marginparwidth + \@parboxrestore + \@marginparreset + #2\par + \@minipagefalse + \outer@nobreak + }% + \color@endbox + \UseTaggingSocket{marginpar/end} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@ympar} +% We must avoid that \cs{@xympar} creates tagging structure: +% \begin{macrocode} +\long\def\@ympar#1{% + \@savemarbox\@marbox{#1}% + \global\setbox\@currbox\copy\@marbox + \tag_stop: + \@xympar + \tag_start:} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@xmpar} +% \cs{@xmpar} is the command used if an optional argument is present. +% In this case we must stop tagging for \cs{@xympar} as above +% but also decide which of the two @savemarbox should have tagging active. +% We add a label to \cs{@marbox}. If that exist tagging is activated for this +% box else for the other one. +% \begin{macrocode} +\long\def\@xmpar[#1]#2{% + \int_gincr:N\g__kernel_marginpar_int + \property_if_recorded:eTF { tag_marginpar-opt-\int_use:N\g__kernel_marginpar_int } + { + \@savemarbox\@marbox {#1 + \property_record:ee + { tag_marginpar-opt-\int_use:N\g__kernel_marginpar_int }{page} + }% + \tag_stop: + \@savemarbox\@currbox{#2}% + \tag_start: + } +% \end{macrocode} +% order matters! the tagged box should be first so that it can pick up +% the correct text-unit number. +% \begin{macrocode} + { + \@savemarbox\@currbox{#2}% + \tag_stop: + \@savemarbox\@marbox{#1 + \property_record:ee + { tag_marginpar-opt-\int_use:N\g__kernel_marginpar_int }{page}} + \tag_start: + } + \tag_stop: + \@xympar + \tag_start: + } +%</package> +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%<*latex-lab> +\ProvidesFile{marginpar-latex-lab-testphase.ltx} + [\ltlabmarginpardate\space v\ltlabmarginparversion\space + Changes related to the tagging of the margin notes] + +\RequirePackage{latex-lab-testphase-marginpar} + +%</latex-lab> +% \end{macrocode} |