% \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} % % % \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: } % % \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} % % \end{macrocode}