summaryrefslogtreecommitdiff
path: root/macros/latex-dev/required/latex-lab/latex-lab-marginpar.dtx
diff options
context:
space:
mode:
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.dtx259
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}