summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/updatemarks
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/updatemarks')
-rw-r--r--macros/latex/contrib/updatemarks/README.md2
-rw-r--r--macros/latex/contrib/updatemarks/doc/updatemarks.pdfbin459124 -> 511281 bytes
-rw-r--r--macros/latex/contrib/updatemarks/doc/updatemarks.tex96
-rw-r--r--macros/latex/contrib/updatemarks/tex/updatemarks-nums.sty161
-rw-r--r--macros/latex/contrib/updatemarks/tex/updatemarks.sty225
5 files changed, 415 insertions, 69 deletions
diff --git a/macros/latex/contrib/updatemarks/README.md b/macros/latex/contrib/updatemarks/README.md
index eb3a99d23c..57f5f3cb56 100644
--- a/macros/latex/contrib/updatemarks/README.md
+++ b/macros/latex/contrib/updatemarks/README.md
@@ -8,6 +8,6 @@ use `\UpdateMarks` to reinsert marks. Read the documentation for more details.
# Copyright and License
-Copyright 2023 Wenjian Chern
+Copyright 2023, 2024 Wenjian Chern
LICENSE: [LPPL 1.3c](http://www.latex-project.org/lppl.txt)
diff --git a/macros/latex/contrib/updatemarks/doc/updatemarks.pdf b/macros/latex/contrib/updatemarks/doc/updatemarks.pdf
index f6e4581896..7c2e6e949b 100644
--- a/macros/latex/contrib/updatemarks/doc/updatemarks.pdf
+++ b/macros/latex/contrib/updatemarks/doc/updatemarks.pdf
Binary files differ
diff --git a/macros/latex/contrib/updatemarks/doc/updatemarks.tex b/macros/latex/contrib/updatemarks/doc/updatemarks.tex
index 2de3b6bded..a462711ab9 100644
--- a/macros/latex/contrib/updatemarks/doc/updatemarks.tex
+++ b/macros/latex/contrib/updatemarks/doc/updatemarks.tex
@@ -4,7 +4,7 @@
\title{Update marks in box\thanks{Issues: \url{https://github.com/Sophanatprime/updatemarks/issues}}}
\author{WenJian Chern\thanks{Email: longaster@163.com}}
-\date{\today\qquad v0.2b}
+\date{\today\qquad v0.2e}
\begin{document}
@@ -59,9 +59,9 @@ But, if you put \env{minipage} in \env{tcolorbox} or the other way round,
The point is, updating marks is done inner to outer and level by level,
if any level is not updated, you will lost all marks in inner boxes.
-Furthermore, whether marks are updated or not {\TeX} is only influenced by box level
+Furthermore, whether marks are updated or not is only influenced by box level
instead of group level, so if you try to limit marks in a certain position, you should
-use a box.
+use a box instead of \tn{begingroup} and \tn{endgroup}.
The extracting and updating would not remove these marks, they still be there, you
can find them by your own method as well.
@@ -82,7 +82,8 @@ including \env{varwidth} of \pkg{varwidth} package, etc.
If \env{multicols} or \env{adjmulticols} or their starred versions are put in a box
--- so called \emph{boxed multicols}, you are able to eanble automatically extracting
-and updating marks into the box (not outer of the box, because it only ).
+and updating marks into the box (not outer of the box, because they are only updated
+one level).
If you need to update marks in this box, you have to do it manually.
Of cause, if the box is \env{minipage} or \env{tcolorbox} or another \env{multicols}
or any other supported environments or commands, then no more things to do.
@@ -96,7 +97,7 @@ are not correct. Multiple contiguous forced break or \tn{clearpage} may cause th
wrong marks.
If your {\LaTeX} version is 2022-06-01 or newer,
-you can get more accurate mark values by using \cs{TopMark}, \cs{FirstMark}
+you can get more correct mark values by using \cs{TopMark}, \cs{FirstMark}
and \cs{LastMark} in head and foot, but only the
\texttt{previous-page} region and \texttt{page} region are supported for now.
Still, Multiple contiguous forced break or \tn{clearpage} may cause the wrong marks.
@@ -122,8 +123,6 @@ automatical updating list. If you are not using these two commands, then nothing
to be done.
-\enlargethispage{20pt}
-
\begin{function}{\AddToUpdateMarksList,\SetUpdateMarksList,\RemoveFromUpdateMarksList}
\begin{syntax}
\verb|\AddToUpdateMarksList| \marg{number list}
@@ -139,6 +138,7 @@ Specially, for those mark classes declared by \cs{NewMarkClass}, you are able to
\begin{verbatim}
\RemoveFromUpdateMarksList { [2e-right], 4, \MarkClass{my-class} }
\end{verbatim}
+You can also use number ranges in \meta{number list}, such as \verb|2 -> 5|.
\end{function}
@@ -205,8 +205,22 @@ or if not in a box then the main vertical list.
If \meta{number list} is presented, the mark classes are these numbers, otherwise
they are the automatical updating list.
+
+\texttt{insertmark} hook would not be used as it's already been used.
\end{function}
+\begin{function}[added=2024-02-19]{\ExtractMarksTo}
+ \begin{syntax}
+ \verb|\ExtractMarks| \marg{box number} \marg{cmd}
+ \verb|\ExtractMarks| \oarg{number list} \marg{box number} \marg{cmd}
+ \verb|\ExtractMarks| * \marg{text} \marg{cmd}
+ \verb|\ExtractMarks| * \oarg{number list} \marg{text} \marg{cmd}
+ \end{syntax}
+It collect all marks to \tn[no-index]{cmd}, you can use \tn[no-index] to reinsert
+these marks.
+
+\texttt{insertmark} hook would not be used as it's already been used.
+\end{function}
\section{Disable patches or write your own patches}
@@ -230,15 +244,21 @@ you are able set them in preamble before or after \pkg{updatemarks} is loaded.
This section describes the interfaces of \LaTeX3.
+\begin{function}[added=2024-02-19]{\updatemarks_parse_classes:Nn}
+ \begin{syntax}
+ \verb|\updatemarks_parse_classes:Nn| \meta{seq var} \marg{number list}
+ \end{syntax}
+Parse number list and save it to \meta{seq var}.
+\end{function}
+
\begin{function}{\updatemarks_extract:nN,\updatemarks_extract_split:N}
\begin{syntax}
- \verb|\updatemarks_extract:nN| \marg{box material} \meta{seq var}
+ \verb|\updatemarks_extract:nN| \marg{material} \meta{seq var}
\verb|\updatemarks_extract_split:N| \meta{seq var}
\end{syntax}
-These two functions have the same functions of
-\cs{ExtractMarks} and \cs{ExtractSplitMarks}.
+Programming interface of \cs{ExtractMarks} and \cs{ExtractSplitMarks}, respectively.
-\meta{box material} is content to build a box.
+\meta{material} is content to build a box.
Such as unpacked box using \cs{hbox_unpack:N} or \cs{vbox_unpack:N} or text.
\meta{seq var} is the number sequence of mark classes which are need to be extracted.
@@ -246,6 +266,26 @@ Such as unpacked box using \cs{hbox_unpack:N} or \cs{vbox_unpack:N} or text.
They only save the marks whose positions are first or last.
\end{function}
+\begin{function}[added=2024-02-19]{\updatemarks_extract:nNN}
+ \begin{syntax}
+ \verb|\updatemarks_extract:nNN| \marg{material} \meta{seq var} \meta{tl var}
+ \end{syntax}
+Programming interface of \cs{ExtractMarksTo}.
+
+\texttt{insertmark} hook would not be used as it's already been used.
+\end{function}
+
+\begin{function}[added=2024-02-19]{\updatemarks_extract_act:nNn}
+ \begin{syntax}
+ \verb|\updatemarks_extract_act:nNn| \marg{material} \meta{seq var} \marg{code}
+ \end{syntax}
+Run \meta{code} for every mark classes in \meta{seq var}, the code can use one
+parameter, which is the current mark class, and two \texttt{tl} variable
+\cs{l_updatemarks_first_tl} and \cs{l_updatemarks_last_tl}, which save
+the first and last marks at specified mark class, respectively. If these two \texttt{tl}
+is not exist, then no marks at the mark class are inserted.
+\end{function}
+
\begin{function}{\updatemarks_update:N}
\begin{syntax}
\verb|\updatemarks_update:N| \meta{seq var}
@@ -256,6 +296,8 @@ This function has the same function of \cs{UpdateMarks}.
reinserted into the current box or the main vertical list.
It only reinserts marks whose positions are first or last.
+
+\texttt{insertmark} hook would not be used as it's already been used.
\end{function}
\begin{function}{\updatemarks_save:Nnn}
@@ -264,18 +306,28 @@ It only reinserts marks whose positions are first or last.
\end{syntax}
Saving marks at \meta{position} of specified mark classes \meta{seq var},
whose values are expanding \meta{value code} \emph{once}.
+
+If \cs{l_updatemarks_nonempty_bool} is set to \texttt{true}, then the expanded value
+will not be saved if it is total empty.
+
The \meta{value code} receives each item in the \meta{seq var}
-as a trailing brace group.
+as a trailing brace group, than expand the whole part of
+\meta{value code} and the trailing group \emph{once}.
\end{function}
-\begin{function}{\updatemarks_save_x:Nnn}
+\begin{function}{\updatemarks_save_e:Nnn}
\begin{syntax}
- \verb|\updatemarks_save_x:Nnn| \meta{seq var} \marg{position} \marg{value code}
+ \verb|\updatemarks_save_e:Nnn| \meta{seq var} \marg{position} \marg{value code}
\end{syntax}
Saving marks at \meta{position} of specified mark classes \meta{seq var},
whose values are fully expanding \meta{value code}.
+
+If \cs{l_updatemarks_nonempty_bool} is set to \texttt{true}, then the expanded value
+will not be saved if it is total empty.
+
The \meta{value code} receives each item in the \meta{seq var}
-as a trailing brace group.
+as a trailing brace group, then \emph{fully expand} the whole part of
+\meta{value code} and the trailing group.
\end{function}
\begin{function}{\updatemarks_alias:Nnn}
@@ -284,6 +336,9 @@ as a trailing brace group.
\end{syntax}
Setting marks at \meta{alias position} are equal to \meta{source position}
of specified mark classes \meta{seq var}.
+
+If \cs{l_updatemarks_nonempty_bool} is set to \texttt{true}, then the expanded value
+will not be saved if it is total empty.
\end{function}
\begin{function}{\updatemarks_remove:Nn}
@@ -318,5 +373,16 @@ Readonly number sequence which holds the mark classes allocated by
\cs{NewMarkClass}. If \cs{NewMarkClass} is undefined, then it's empty.
\end{function}
+\begin{function}{\l_updatemarks_nonempty_bool}
+A local \texttt{bool} variable which is used to control if is going to save
+a total empty value.
+\end{function}
+
+\begin{function}{\l_updatemarks_first_tl,\l_updatemarks_last_tl}
+A local \texttt{tl} variable which are use to save the first and last marks.
+\end{function}
+
+
+\PrintIndex
\end{document} \ No newline at end of file
diff --git a/macros/latex/contrib/updatemarks/tex/updatemarks-nums.sty b/macros/latex/contrib/updatemarks/tex/updatemarks-nums.sty
new file mode 100644
index 0000000000..02fcde3cdb
--- /dev/null
+++ b/macros/latex/contrib/updatemarks/tex/updatemarks-nums.sty
@@ -0,0 +1,161 @@
+% updatemarks-nums.sty
+% Copyright 2024 Wenjian Chern.
+%
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3c
+% of this license or any later version.
+% The latest version of this license is in
+% http://www.latex-project.org/lppl.txt
+% and version 1.3c or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%
+% This work has the LPPL maintenance status `maintained'.
+%
+% The Current Maintainer of this work is Wenjian Chern.
+%
+% This work consists of the files updatemarks-nums.sty
+%
+\@ifundefined{ProvidesExplPackage}{\RequirePackage{expl3}}
+\ProvidesExplPackage{updatemarks-nums}{2024/02/19}{v0.1}{parse number range}
+
+\tl_new:N \l__parserange_tmpa_tl
+\tl_new:N \l__parserange_tmpb_tl
+\seq_new:N \l__parserange_tmp_seq
+\int_new:N \l__parserange_begin_int
+\int_new:N \l__parserange_end_int
+\int_new:N \l__parserange_max_int
+\int_new:N \l__parserange_min_int
+\bool_new:N \l__parserange_invalid_bool
+\quark_new:N \q__parserange
+\cs_new_protected:Npn \parserange_check:
+ {
+ \cs_set_eq:NN \__parserange_single:n \__parserange_single_check:n
+ \cs_set_eq:NN \__parserange_range: \__parserange_range_check:
+ }
+\cs_new_protected:Npn \parserange_nocheck:
+ {
+ \cs_set_eq:NN \__parserange_single:n \__parserange_single_nocheck:n
+ \cs_set_eq:NN \__parserange_range: \__parserange_range_nocheck:
+ }
+\cs_new_protected:Npn \parserange:nnnN #1#2#3#4
+ {
+ \seq_set_eq:NN #4 \c_empty_seq
+ \int_set:Nn \l__parserange_min_int { \__parserange_to_int:n {#1} }
+ \int_set:Nn \l__parserange_max_int { \__parserange_to_int:n {#2} }
+ \clist_map_inline:nn {#3}
+ {
+ \__parserange_aux:n {##1}
+ \bool_if:NF \l__parserange_invalid_bool
+ { \seq_concat:NNN #4 #4 \l__parserange_tmp_seq }
+ }
+ }
+\cs_generate_variant:Nn \parserange:nnnN { nnvN, nneN }
+\cs_new_protected:Npn \parserange:nnN
+ { \parserange:nnnN { 1 } }
+\cs_generate_variant:Nn \parserange:nnN { nvN, neN }
+\cs_new_protected:Npn \__parserange_aux:n #1
+ {
+ \bool_set_false:N \l__parserange_invalid_bool
+ \seq_clear:N \l__parserange_tmp_seq
+ \__parserange_action:nnn
+ {#1}
+ { \__parserange_single:n {#1} }
+ {
+ \tl_if_empty:NTF \l__parserange_tmpa_tl
+ { \int_set_eq:NN \l__parserange_begin_int \l__parserange_min_int }
+ {
+ \int_set:Nn \l__parserange_begin_int
+ { \exp_args:No \__parserange_to_int:n \l__parserange_tmpa_tl }
+ }
+ \tl_if_empty:NTF \l__parserange_tmpb_tl
+ { \int_set_eq:NN \l__parserange_end_int \l__parserange_max_int }
+ {
+ \int_set:Nn \l__parserange_end_int
+ { \exp_args:No \__parserange_to_int:n \l__parserange_tmpb_tl }
+ }
+ \__parserange_range:
+ }
+ }
+\cs_new_protected:Npn \parserange_use_delimiter:n #1
+ {
+ \tl_if_empty:nTF {#1}
+ {
+ \cs_set:Npn \__parserange_action:nnn ##1
+ { \__parserange_aux:w ##1 \prg_do_nothing: \q_nil \q__parserange }
+ \cs_set:Npn \__parserange_aux:w ##1##2 ##3 \q__parserange
+ {
+ \tl_set:Nx \l__parserange_tmpa_tl { \tl_trim_spaces:n {##1} }
+ \tl_set:Nx \l__parserange_tmpa_tl { \tl_trim_spaces:n {##2} }
+ \quark_if_nil:nTF {##3}
+ }
+ }
+ {
+ \cs_set:Npn \__parserange_action:nnn ##1
+ { \__parserange_aux:w ##1 #1 #1 \q__parserange }
+ \cs_set:Npn \__parserange_aux:w ##1 #1 ##2 #1 ##3 \q__parserange
+ {
+ \tl_set:Nx \l__parserange_tmpa_tl { \tl_trim_spaces:n {##1} }
+ \tl_set:Nx \l__parserange_tmpb_tl { \tl_trim_spaces:n {##2} }
+ \tl_if_blank:nTF {##3}
+ }
+ }
+ }
+\cs_new_protected:Npn \parserange_set_to_int:n
+ { \cs_set:Npn \__parserange_to_int:n ##1 }
+\parserange_set_to_int:n {#1}
+\cs_new_protected:Npn \parserange_use_default_delimiter:
+ {
+ \cs_set:Npn \__parserange_action:nnn ##1
+ { \__parserange_aux:w ##1 -> -> \q__parserange }
+ \cs_set:Npn \__parserange_aux:w ##1 -> ##2 -> ##3 \q__parserange
+ {
+ \tl_set:Nx \l__parserange_tmpa_tl { \tl_trim_spaces:n {##1} }
+ \tl_set:Nx \l__parserange_tmpb_tl { \tl_trim_spaces:n {##2} }
+ \tl_if_blank:nTF {##3} { \use_i:nn } { \use_ii:nn }
+ }
+ }
+\parserange_use_default_delimiter: % \parserange_use_delimiter:n {->}
+\cs_new:Npn \__parserange_single_check:n #1
+ {
+ \bool_lazy_or:nnTF
+ { \int_compare_p:nNn {#1} > \l__parserange_max_int }
+ { \int_compare_p:nNn {#1} < \l__parserange_min_int }
+ { \bool_set_true:N \l__parserange_invalid_bool }
+ {
+ \seq_put_right:Nx \l__parserange_tmp_seq
+ { \int_eval:n { \__parserange_to_int:n {#1} } }
+ }
+ }
+\cs_new:Npn \__parserange_single_nocheck:n #1
+ {
+ \seq_put_right:Nx \l__parserange_tmp_seq
+ { \int_eval:n { \__parserange_to_int:n {#1} } }
+ }
+\cs_new_eq:NN \__parserange_single:n \__parserange_single_check:n
+\cs_new:Npn \__parserange_range_check:
+ {
+ \int_compare:nNnT \l__parserange_begin_int < \l__parserange_min_int
+ { \int_set_eq:NN \l__parserange_begin_int \l__parserange_min_int }
+ \int_compare:nNnT \l__parserange_end_int > \l__parserange_max_int
+ { \int_set_eq:NN \l__parserange_end_int \l__parserange_max_int }
+ \bool_lazy_or:nnTF
+ { \int_compare_p:nNn \l__parserange_begin_int > \l__parserange_max_int }
+ { \int_compare_p:nNn \l__parserange_begin_int > \l__parserange_end_int }
+ { \bool_set_true:N \l__parserange_invalid_bool }
+ {
+ \int_step_inline:nnn
+ { \l__parserange_begin_int } { \l__parserange_end_int }
+ { \seq_put_right:Nn \l__parserange_tmp_seq {##1} }
+ }
+ }
+\cs_new:Npn \__parserange_range_nocheck:
+ {
+ \int_compare:nNnTF \l__parserange_begin_int > \l__parserange_end_int
+ { \bool_set_true:N \l__parserange_invalid_bool }
+ {
+ \int_step_inline:nnn
+ { \l__parserange_begin_int } { \l__parserange_end_int }
+ { \seq_put_right:Nn \l__parserange_tmp_seq {##1} }
+ }
+ }
+\cs_new_eq:NN \__parserange_range: \__parserange_range_check:
diff --git a/macros/latex/contrib/updatemarks/tex/updatemarks.sty b/macros/latex/contrib/updatemarks/tex/updatemarks.sty
index ab5acb8aa3..244ce20b5f 100644
--- a/macros/latex/contrib/updatemarks/tex/updatemarks.sty
+++ b/macros/latex/contrib/updatemarks/tex/updatemarks.sty
@@ -1,12 +1,12 @@
% updatemarks.sty
-% Copyright 2023 Wenjian Chern.
+% Copyright 2023, 2024 Wenjian Chern.
%
% This work may be distributed and/or modified under the
-% conditions of the LaTeX Project Public License, either version 1.3
+% conditions of the LaTeX Project Public License, either version 1.3c
% of this license or any later version.
% The latest version of this license is in
% http://www.latex-project.org/lppl.txt
-% and version 1.3 or later is part of all distributions of LaTeX
+% and version 1.3c or later is part of all distributions of LaTeX
% version 2005/12/01 or later.
%
% This work has the LPPL maintenance status `maintained'.
@@ -16,27 +16,38 @@
% This work consists of the files updatemarks.sty and updatemarks.tex
%
\NeedsTeXFormat{LaTeX2e}
-\@ifundefined{ProvidesExplPackage}{\RequirePackage{expl3}}{}
\@ifundefined{NewDocumentCommand}{\RequirePackage{xparse}}{}
-\ProvidesExplPackage{updatemarks}{2023/09/03}{0.2b}{extract and update marks from box}
+\ProvidesExplPackage{updatemarks}{2024/02/19}{0.2e}{extract and update marks from box}
\RequirePackage{etoolbox}
+\RequirePackage{updatemarks-nums}
\seq_new:N \g__updatemarks_seq
\box_new:N \l__updatemarks_r_box
\cs_new_eq:NN \l__updatemarks_s_box \l_tmpa_box % this box is used for locally split
\tex_countdef:D \g_updatemarks_max_int 256 \exp_stop_f:
\tl_new:N \l__updatemarks_tl
+\tl_new:N \g__updatemarks_saved_tl
-
-%% basicly copy from \__mark_update_structure:nn of LaTeX kernel
-\cs_new_protected:Npn \__updatemarks_extract:nnn #1#2#3 % box, map of number, code
+%% basicly copy from \__mark_extract_and_handle_marks:nn of LaTeX kernel
+\cs_new_protected:Npn \__updatemarks_extract:nnn #1#2#3 % material, map of number, code
+ {
+ \__updatemarks_extract:nn {#1}
+ { \__updatemarks_extract_split:nn {#2} {#3} }
+ }
+\cs_new_protected:Npn \__updatemarks_extract:nn #1#2 % material, code
{
\group_begin:
\dim_set_eq:NN \tex_splitmaxdepth:D \c_max_dim
\int_set_eq:NN \tex_vbadness:D \c_max_int
\dim_set_eq:NN \tex_vfuzz:D \c_max_dim
+ \__updatemarks_prepare_and_extract:nn {#2} {#1}
+ \group_end:
+ }
+% old mechanism
+\cs_new_protected:Npn \__updatemarks_prepare_and_extract:nn #1#2 % code, material
+ {
\vbox_set_to_ht:Nnw \l__updatemarks_r_box { -.5 \c_max_dim }
- #1 \tex_unskip:D
+ #2 \tex_unskip:D
\box_set_to_last:N \l__updatemarks_r_box
\int_compare:nNnT { \tex_lastnodetype:D } < { 0 }
{
@@ -53,18 +64,15 @@
\int_compare:nNnTF { \tex_badness:D } > { 0 }
{
\vbox_set_split_to_ht:NNn \l__updatemarks_s_box \l__updatemarks_r_box \c_max_dim
- \__updatemarks_extract_split:nn {#2} {#3}
+ #1
}
- {
- \msg_error:nn { updatemarks } { infinite-shrinkage }
- #2
- {
- \cs_undefine:N \l_updatemarks_first_tl
- \cs_undefine:N \l_updatemarks_last_tl
- #3
- }
- }
- \group_end:
+ { \msg_error:nn { updatemarks } { infinite-shrinkage } }
+ }
+% new mechanism, copy a LaTeX kernel command
+\cs_if_exist:NT \__mark_prepare_and_extract:nn
+ {
+ \cs_gset_eq:NN \__updatemarks_prepare_and_extract:nn
+ \__mark_prepare_and_extract:nn
}
\cs_new_protected:Npn \__updatemarks_extract_split:nn #1#2 % map of number, code
{
@@ -76,7 +84,11 @@
\cs_undefine:N \l_updatemarks_first_tl
\cs_undefine:N \l_updatemarks_last_tl
}
- { \tl_set:No \l_updatemarks_first_tl { \tex_splitfirstmarks:D ##1 } }
+ {
+ \tl_set:No \l_updatemarks_first_tl { \tex_splitfirstmarks:D ##1 }
+ \tl_if_empty:NT \l_updatemarks_first_tl
+ { \cs_undefine:N \l_updatemarks_first_tl }
+ }
#2
}
}
@@ -89,6 +101,32 @@
\tl_gset_eq:cN { g__updatemarks_last-#1_tl } \l_updatemarks_last_tl
}
}
+\cs_new_protected:Npn \__updatemarks_extract_for_reinsertion:nn #1#2 % material, map
+ {
+ \__updatemarks_extract:nn {#1}
+ {
+ #2
+ {
+ \tl_if_empty:oF { \tex_splitbotmarks:D ##1 }
+ {
+ \tl_if_empty:oF { \tex_splitfirstmarks:D ##1 }
+ {
+ \tl_gput_right:Nx \g__updatemarks_saved_tl
+ {
+ \tex_marks:D ##1
+ { \exp_not:N \exp_not:n { \tex_splitfirstmarks:D ##1 } }
+ }
+ }
+ \tl_gput_right:Nx \g__updatemarks_saved_tl
+ {
+ \tex_marks:D ##1
+ { \exp_not:N \exp_not:n { \tex_splitbotmarks:D ##1 } }
+ }
+ }
+ }
+ }
+ }
+
\cs_new_protected:Npn \updatemarks_extract:nN #1#2 % box material, seq
{
\__updatemarks_extract:nnn {#1}
@@ -101,22 +139,77 @@
{ \seq_map_inline:Nn #1 }
{ \__updatemarks_extract_num:n {##1} }
}
+\cs_new_protected:Npn \updatemarks_extract:nNN #1#2#3
+ {
+ \tl_clear:N \g__updatemarks_saved_tl
+ \__updatemarks_extract_for_reinsertion:nn {#1}
+ { \seq_map_inline:Nn #2 }
+ \tl_set_eq:NN #3 \g__updatemarks_saved_tl
+ }
+\cs_new_eq:NN \__updatemarks_extract_act:n ?
+\cs_new_protected:Npn \updatemarks_extract_act:nNn #1#2#3 % material, seq, code
+ {
+ \cs_set_protected:Npn \__updatemarks_extract_act:n ##1 {#3}
+ \__updatemarks_extract:nnn {#1}
+ { \seq_map_inline:Nn #2 }
+ { \__updatemarks_extract_act:n {##1} }
+ }
+\bool_new:N \l_updatemarks_nonempty_bool
+\tl_new:N \l__updatemarks_saved_tl
\cs_new_protected:Npn \updatemarks_save:Nnn #1#2#3 % seq, pos, value
{
- \seq_map_inline:Nn #1
- { \tl_gset:co { g__updatemarks_#2-##1_tl } { #3 {##1} } }
+ \bool_if:NTF \l_updatemarks_nonempty_bool
+ {
+ \seq_map_inline:Nn #1
+ {
+ \tl_set:No \l__updatemarks_saved_tl { #3 {##1} }
+ \tl_if_empty:NF \l__updatemarks_saved_tl
+ { \tl_gset_eq:cN { g__updatemarks_#2-##1_tl } \l__updatemarks_saved_tl }
+ }
+ }
+ {
+ \seq_map_inline:Nn #1
+ {
+ \tl_gset:co { g__updatemarks_#2-##1_tl } { #3 {##1} }
+ }
+ }
}
-\cs_new_protected:Npn \updatemarks_save_x:Nnn #1#2#3 % seq, pos, value
+\cs_new_protected:Npn \updatemarks_save_e:Nnn #1#2#3 % seq, pos, value
{
- \seq_map_inline:Nn #1
- { \tl_gset:cx { g__updatemarks_#2-##1_tl } { #3 {##1} } }
+ \bool_if:NTF \l_updatemarks_nonempty_bool
+ {
+ \seq_map_inline:Nn #1
+ {
+ \tl_set:Nx \l__updatemarks_saved_tl { #3 {##1} }
+ \tl_if_empty:NF \l__updatemarks_saved_tl
+ { \tl_gset_eq:cN { g__updatemarks_#2-##1_tl } \l__updatemarks_saved_tl }
+ }
+ }
+ {
+ \seq_map_inline:Nn #1
+ {
+ \tl_gset:cx { g__updatemarks_#2-##1_tl } { #3 {##1} }
+ }
+ }
}
+\cs_new_eq:NN \updatemarks_save_x:Nnn \updatemarks_save_e:Nnn
\cs_new_protected:Npn \updatemarks_alias:Nnn #1#2#3 % seq, pos1, pos2
{
- \seq_map_inline:Nn #1
- { \tl_gset_eq:cc { g__updatemarks_#2-##1_tl } { g__updatemarks_#3-##1_tl } }
+ \bool_if:NTF \l_updatemarks_nonempty_bool
+ {
+ \seq_map_inline:Nn #1
+ {
+ \tl_set_eq:Nc \l__updatemarks_saved_tl { g__updatemarks_#3-##1_tl }
+ \tl_if_empty:NF \l__updatemarks_saved_tl
+ { \tl_gset_eq:cN { g__updatemarks_#2-##1_tl } \l__updatemarks_saved_tl }
+ }
+ }
+ {
+ \seq_map_inline:Nn #1
+ { \tl_gset_eq:cc { g__updatemarks_#2-##1_tl } { g__updatemarks_#3-##1_tl } }
+ }
}
\cs_new_protected:Npn \updatemarks_remove:Nn #1#2 % seq, pos
{ \seq_map_inline:Nn #1 { \cs_undefine:c { g__updatemarks_#2-##1_tl } } }
@@ -145,30 +238,32 @@
\if@nobreak\ifvmode\nobreak\fi\fi
}
}
-% do not check if it is <= \g_updatemarks_max_int
\cs_new_protected:Npn \__updatemarks_gput:Nn #1#2
{
\group_begin:
\cs_set_eq:NN \MarkClass \__updatemarks_class_num:n
\cs_set_eq:NN \MaxClass \g_updatemarks_max_int
- \clist_map_inline:nn {#2}
- { \seq_gput_right:Nx #1 { \int_eval:n { \__updatemarks_maybe_class:n {##1} } } }
+ \parserange_use_delimiter:n { -> }
+ \parserange_check:
+ \parserange_set_to_int:n { \__updatemarks_maybe_class:n {##1} }
+ \parserange:nnnN { 0 } { \g_updatemarks_max_int } {#2} \g__updatemarks_seq
+ \seq_gset_eq:NN #1 \g__updatemarks_seq
\seq_gremove_duplicates:N #1
\group_end:
}
+\cs_new_protected:Npn \updatemarks_parse_classes:Nn { \__updatemarks_gput:Nn }
-\cs_new:Npn \__updatemarks_class_num:n #1 { \cs:w c__mark_class_ #1 _mark \cs_end: }
+\cs_new:Npn \__updatemarks_class_num:n #1
+ {
+ \cs_if_exist_use:cF { c__mark_class_ #1 _mark }
+ { -1 \msg_expandable_error:nnn { updatemarks } { unknown-class } {#1} }
+ }
\cs_new:Npn \__updatemarks_maybe_class:n #1
{
\tl_if_head_eq_meaning:nNTF {#1} [ % ]
{ \__updatemarks_maybe_class_aux:w #1 } {#1}
}
-\cs_new:Npn \__updatemarks_maybe_class_aux:w [#1]
- {
- \cs_if_exist_use:cF { c__mark_class_ #1 _mark }
- { 0 \msg_expandable_error:nnn { updatemarks } { unknown-class } {#1} }
- }
-
+\cs_new:Npn \__updatemarks_maybe_class_aux:w [#1] { \__updatemarks_class_num:n {#1} }
\seq_new:N \g_updatemarks_seq
@@ -200,6 +295,34 @@
\g__updatemarks_seq
}
}
+\NewDocumentCommand \ExtractMarksTo { s o +m m }
+ {
+ \tl_if_novalue:nTF {#2}
+ {
+ \updatemarks_extract:nNN
+ {
+ \bool_if:nTF {#1} { #3 }
+ {
+ \if_hbox:N #3 \hbox_unpack:N #3 \scan_stop: \fi:
+ \if_vbox:N #3 \vbox_unpack:N #3 \scan_stop: \fi:
+ }
+ }
+ \g_updatemarks_seq #4
+ }
+ {
+ \seq_gclear:N \g__updatemarks_seq
+ \__updatemarks_gput:Nn \g__updatemarks_seq {#2}
+ \updatemarks_extract:nNN
+ {
+ \bool_if:nTF {#1} { #3 }
+ {
+ \if_hbox:N #3 \hbox_unpack:N #3 \scan_stop: \fi:
+ \if_vbox:N #3 \vbox_unpack:N #3 \scan_stop: \fi:
+ }
+ }
+ \g__updatemarks_seq #4
+ }
+ }
\NewDocumentCommand \ExtractSplitMarks { o }
{
\tl_if_novalue:nTF {#1}
@@ -259,11 +382,7 @@
}
}
{
- \AtBeginDocument
- {
- \int_step_inline:nnn { 0 } { \g_updatemarks_max_int }
- { \seq_gput_right:Nn \g_updatemarks_seq {#1} }
- }
+ \AtBeginDocument { \AddAllocatedToUpdateMarksList }
}
\msg_new:nnn { updatemarks } { unknown-class } { Unknown~mark~class~`#1'. }
@@ -316,7 +435,8 @@
\apptocmd \endminipage { \updatemarks@of{minipage} } { } { \ERROR }
}
% tcolorbox
-\providecommand \updatemarks@tcolorbox@patch
+\cs_if_exist:NTF \updatemarks@tcolorbox@patch { \use_none:n }
+ { \tl_const:Nn \updatemarks@tcolorbox@patch }
{
\tcbset{updatemarks/.is~choice,
updatemarks/true/.code=\bool_set_true:N \l__updatemarks_tcolorbox_bool,
@@ -363,7 +483,8 @@
\fi
}
% multicol
-\providecommand \updatemarks@multicol@patch
+\cs_if_exist:NTF \updatemarks@multicol@patch { \use_none:n }
+ { \tl_const:Nn \updatemarks@multicol@patch }
{
%% the patch is used to extract marks
\tl_set:No \set@keptmarks
@@ -402,14 +523,16 @@
% patches of new mark mechanism
\updatemarks@multicolnewmark@patch
}
-\providecommand \updatemarks@adjmulticol@patch
+\cs_if_exist:NTF \updatemarks@adjmulticol@patch { \use_none:n }
+ { \tl_const:Nn \updatemarks@adjmulticol@patch }
{
\patchcmd \adjmc@process@ne@column { \unvbox }
{ \extractmarks@of{multicol}{\unvcopy\mult@box}\unvbox }
{ } { \ERROR }
\updatemarks@adjmulticolnewmark@patch
}
-\providecommand \updatemarks@paracol@patch
+\cs_if_exist:NTF \updatemarks@paracol@patch { \use_none:n }
+ { \tl_const:Nn \updatemarks@paracol@patch }
{
\updatemarks@paracolnewmark@patch
}
@@ -451,12 +574,8 @@
{
\bool_if:NT \l__updatemarks_multicol_bool
{
- \seq_map_inline:Nn \g_updatemarks_seq
- {
- \tl_set:Nx \l__updatemarks_tl { \updatemarks_value:nn { top } {#1} }
- \tl_if_empty:NT \l__updatemarks_tl
- { \tl_gset:co { g__updatemarks_top-#1_tl } { \tex_topmarks:D #1 } }
- }
+ \bool_set_false:N \l_updatemarks_nonempty_bool
+ \updatemarks_save:Nnn \g_updatemarks_seq { top } { \tex_topmarks:D \use:n }
}
}
\tl_const:Nn \updatemarks@multicol@middlepage