summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3basics.dtx')
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3basics.dtx483
1 files changed, 57 insertions, 426 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx
index 19014478169..002e524aa8a 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-09-19}
+% \date{Released 2019-09-28}
%
% \maketitle
%
@@ -1275,6 +1275,24 @@
% execute <false code>. Similar for the other functions.
% \end{function}
%
+% \section{Starting a paragraph}
+%
+% \begin{function}[added = 2017-07-04]{\mode_leave_vertical:}
+% \begin{syntax}
+% \cs{mode_leave_vertical:}
+% \end{syntax}
+% Ensures that \TeX{} is not in vertical (inter-paragraph) mode. In
+% horizontal or math mode this command has no effect, in vertical mode it
+% switches to horizontal mode, and inserts a box of width
+% \tn{parindent}, followed by the \tn{everypar} token list.
+% \begin{texnote}
+% This results in the contents of the \tn{everypar} token register being
+% inserted, after \cs{mode_leave_vertical:} is complete. Notice that in
+% contrast to the \LaTeXe{} \tn{leavevmode} approach, no box is used
+% by the method implemented here.
+% \end{texnote}
+% \end{function}
+%
% \end{documentation}
%
% \begin{implementation}
@@ -1690,447 +1708,51 @@
% \begin{macro}{\__kernel_if_debug:TF}
% A more meaningful test of whether debugging is enabled than messing
% up with guards. We can also more easily change the logic in one
-% place then. At present, debugging is disabled in the format and in
-% generic mode, while in \LaTeXe{} mode it is enabled if one of the
-% options \texttt{enable-debug}, \texttt{log-functions} or
-% \texttt{check-declarations} was given.
+% place then. This is needed primarily for deprecations.
% \begin{macrocode}
\cs_set_protected:Npn \__kernel_if_debug:TF #1#2 {#2}
-%<*package>
-\tex_ifodd:D \l@expl@enable@debug@bool
- \cs_set_protected:Npn \__kernel_if_debug:TF #1#2 {#1}
-\fi:
-%</package>
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\debug_on:n, \debug_off:n, \@@_all_on:, \@@_all_off:}
-%
+% \begin{macro}{\debug_on:n, \debug_off:n}
+% Stubs.
% \begin{macrocode}
-\__kernel_if_debug:TF
+\cs_set_protected:Npn \debug_on:n #1
{
- \cs_set_protected:Npn \debug_on:n #1
- {
- \exp_args:No \clist_map_inline:nn { \tl_to_str:n {#1} }
- {
- \cs_if_exist_use:cF { @@_ ##1 _on: }
- { \__kernel_msg_error:nnn { kernel } { debug } {##1} }
- }
- }
- \cs_set_protected:Npn \debug_off:n #1
- {
- \exp_args:No \clist_map_inline:nn { \tl_to_str:n {#1} }
- {
- \cs_if_exist_use:cF { @@_ ##1 _off: }
- { \__kernel_msg_error:nnn { kernel } { debug } {##1} }
- }
- }
- \cs_set_protected:Npn \@@_all_on:
- {
- \debug_on:n
- {
- check-declarations ,
- check-expressions ,
- deprecation ,
- log-functions ,
- }
- }
- \cs_set_protected:Npn \@@_all_off:
- {
- \debug_off:n
- {
- check-declarations ,
- check-expressions ,
- deprecation ,
- log-functions ,
- }
- }
+ \__kernel_msg_error:nnx { kernel } { enable-debug }
+ { \tl_to_str:n { \debug_on:n {#1} } }
}
+\cs_set_protected:Npn \debug_off:n #1
{
- \cs_set_protected:Npn \debug_on:n #1
- {
- \__kernel_msg_error:nnx { kernel } { enable-debug }
- { \tl_to_str:n { \debug_on:n {#1} } }
- }
- \cs_set_protected:Npn \debug_off:n #1
- {
- \__kernel_msg_error:nnx { kernel } { enable-debug }
- { \tl_to_str:n { \debug_off:n {#1} } }
- }
+ \__kernel_msg_error:nnx { kernel } { enable-debug }
+ { \tl_to_str:n { \debug_off:n {#1} } }
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\debug_suspend:, \debug_resume:}
-% \begin{macro}{\@@_suspended:T}
-% \begin{macro}{\l_@@_suspended_tl}
-% Suspend and resume locally all debug-related errors and logging
-% except deprecation errors. The \cs{debug_suspend:} and \cs{debug_resume:}
-% pairs can be nested. We keep track of nesting in a token list
-% containing a number of periods. At first begin with the
-% \enquote{non-suspended} version of \cs{@@_suspended:T}.
-% \begin{macrocode}
-\__kernel_if_debug:TF
- {
- \cs_set_nopar:Npn \l_@@_suspended_tl { }
- \cs_set_protected:Npn \debug_suspend:
- {
- \tl_put_right:Nn \l_@@_suspended_tl { . }
- \cs_set_eq:NN \@@_suspended:T \use:n
- }
- \cs_set_protected:Npn \debug_resume:
- {
- \tl_set:Nx \l_@@_suspended_tl
- { \tl_tail:N \l_@@_suspended_tl }
- \tl_if_empty:NT \l_@@_suspended_tl
- {
- \cs_set_eq:NN \@@_suspended:T \use_none:n
- }
- }
- \cs_set:Npn \@@_suspended:T #1 { }
- }
- {
- \cs_set_protected:Npn \debug_suspend: { }
- \cs_set_protected:Npn \debug_resume: { }
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}
-% {\@@_check-declarations_on:, \@@_check-declarations_off:}
-% \begin{macro}{\__kernel_chk_var_exist:N}
-% \begin{macro}{\__kernel_chk_cs_exist:N, \__kernel_chk_cs_exist:c}
-% \begin{macro}{\__kernel_chk_var_local:N, \__kernel_chk_var_global:N}
-% \begin{macro}{\__kernel_chk_var_scope:NN}
-% When debugging is enabled these two functions set up functions that
-% test their argument (when \texttt{check-declarations} is active)
-% \begin{itemize}
-% \item \cs{__kernel_chk_var_exist:N} and \cs{__kernel_chk_cs_exist:N}, two
-% functions that test that their argument is defined;
-% \item \cs{__kernel_chk_var_scope:NN} that checks that its argument |#2|
-% has scope |#1|.
-% \item \cs{__kernel_chk_var_local:N} and \cs{__kernel_chk_var_global:N} that
-% perform both checks.
-% \end{itemize}
-% \begin{macrocode}
-\__kernel_if_debug:TF
- {
- \exp_args:Nc \cs_set_protected:Npn { @@_check-declarations_on: }
- {
- \cs_set_protected:Npn \__kernel_chk_var_exist:N ##1
- {
- \@@_suspended:T \use_none:nnn
- \cs_if_exist:NF ##1
- {
- \__kernel_msg_error:nnx { kernel } { non-declared-variable }
- { \token_to_str:N ##1 }
- }
- }
- \cs_set_protected:Npn \__kernel_chk_cs_exist:N ##1
- {
- \@@_suspended:T \use_none:nnn
- \cs_if_exist:NF ##1
- {
- \__kernel_msg_error:nnx { kernel } { command-not-defined }
- { \token_to_str:N ##1 }
- }
- }
- \cs_set_protected:Npn \__kernel_chk_var_scope:NN
- {
- \@@_suspended:T \use_none:nnn
- \@@_chk_var_scope_aux:NN
- }
- \cs_set_protected:Npn \__kernel_chk_var_local:N ##1
- {
- \@@_suspended:T \use_none:nnnnn
- \__kernel_chk_var_exist:N ##1
- \@@_chk_var_scope_aux:NN l ##1
- }
- \cs_set_protected:Npn \__kernel_chk_var_global:N ##1
- {
- \@@_suspended:T \use_none:nnnnn
- \__kernel_chk_var_exist:N ##1
- \@@_chk_var_scope_aux:NN g ##1
- }
- }
- \exp_args:Nc \cs_set_protected:Npn { @@_check-declarations_off: }
- {
- \cs_set_protected:Npn \__kernel_chk_var_exist:N ##1 { }
- \cs_set_protected:Npn \__kernel_chk_cs_exist:N ##1 { }
- \cs_set_protected:Npn \__kernel_chk_var_local:N ##1 { }
- \cs_set_protected:Npn \__kernel_chk_var_global:N ##1 { }
- \cs_set_protected:Npn \__kernel_chk_var_scope:NN ##1##2 { }
- }
- \cs_set_protected:Npn \__kernel_chk_cs_exist:c
- { \exp_args:Nc \__kernel_chk_cs_exist:N }
- \tex_ifodd:D \l@expl@check@declarations@bool
- \use:c { @@_check-declarations_on: }
- \else:
- \use:c { @@_check-declarations_off: }
- \fi:
- }
- { }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_chk_var_scope_aux:NN}
-% \begin{macro}{\@@_chk_var_scope_aux:Nn}
-% \begin{macro}{\@@_chk_var_scope_aux:NNn}
-% First check whether the name of the variable |#2| starts with
-% \meta{letter}|_|. If it does then pass that letter, the
-% \meta{scope}, and the variable name to
-% \cs{@@_chk_var_scope_aux:NNn}. That function compares the two
-% letters and triggers an error if they differ (the \cs{scan_stop:}
-% case is not reachable here). If the second character was not |_|
-% then pass the same data to the same auxiliary, except for its first
-% argument which is now a control sequence. That control sequence is
-% actually a token list (but to avoid triggering the checking code we
-% manipulate it using \cs{cs_set_nopar:Npn}) containing a single
-% letter \meta{scope} according to what the first assignment to the
-% given variable was.
-% \begin{macrocode}
-\__kernel_if_debug:TF
- {
- \cs_set_protected:Npn \@@_chk_var_scope_aux:NN #1#2
- { \exp_args:NNf \@@_chk_var_scope_aux:Nn #1 { \cs_to_str:N #2 } }
- \cs_set_protected:Npn \@@_chk_var_scope_aux:Nn #1#2
- {
- \if:w _ \use_i:nn \use_i_delimit_by_q_stop:nw #2 ? ? \q_stop
- \exp_after:wN \@@_chk_var_scope_aux:NNn
- \use_i_delimit_by_q_stop:nw #2 ? \q_stop
- #1 {#2}
- \else:
- \exp_args:Nc \@@_chk_var_scope_aux:NNn
- { @@_chk_/ #2 }
- #1 {#2}
- \fi:
- }
- \cs_set_protected:Npn \@@_chk_var_scope_aux:NNn #1#2#3
- {
- \if:w #1 #2
- \else:
- \if:w #1 \scan_stop:
- \cs_gset_nopar:Npn #1 {#2}
- \else:
- \__kernel_msg_error:nnxxx { kernel } { local-global }
- {#1} {#2} { \iow_char:N \\ #3 }
- \fi:
- \fi:
- }
- }
- { }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}
-% {\@@_check-expressions_on:, \@@_check-expressions_off:}
-% \begin{macro}{\__kernel_chk_expr:nNnN}
-% \begin{macro}{\@@_chk_expr_aux:nNnN}
-% When debugging is enabled these two functions set
-% \cs{__kernel_chk_expr:nNnN} to test or not whether the given
-% expression is valid. The idea is to evaluate the expression within
-% a brace group (to catch trailing \cs{use_none:nn} or similar), then
-% test that the result is what we expect. This is done by turning it
-% to an integer and hitting that with \cs{tex_romannumeral:D} after
-% replacing the first character by |-0|. If all goes well, that
-% primitive finds a non-positive integer and gives an empty output.
-% If the original expression evaluation stopped early it leaves a
-% trailing \cs{tex_relax:D}, which stops the second evaluation (used
-% to convert to integer) before it encounters the final
-% \cs{tex_relax:D}. Since \cs{tex_romannumeral:D} does not absorb
-% \cs{tex_relax:D} the output will be nonempty. Note that |#3| is
-% empty except for mu expressions for which it is \cs{tex_mutoglue:D}
-% to avoid an \enquote{incompatible glue units} error. Note also that
-% if we had omitted the first \cs{tex_relax:D} then for instance
-% |1+2\relax+3| would incorrectly be accepted as a valid integer
-% expression.
-% \begin{macrocode}
-\__kernel_if_debug:TF
- {
- \exp_args:Nc \cs_set_protected:Npn { @@_check-expressions_on: }
- {
- \cs_set:Npn \__kernel_chk_expr:nNnN ##1##2
- {
- \@@_suspended:T { ##1 \use_none:nnnnnnn }
- \exp_after:wN \@@_chk_expr_aux:nNnN
- \exp_after:wN { \tex_the:D ##2 ##1 \scan_stop: }
- ##2
- }
- }
- \exp_args:Nc \cs_set_protected:Npn { @@_check-expressions_off: }
- { \cs_set:Npn \__kernel_chk_expr:nNnN ##1##2##3##4 {##1} }
- \use:c { @@_check-expressions_off: }
- \cs_set:Npn \@@_chk_expr_aux:nNnN #1#2#3#4
- {
- \tl_if_empty:oF
- {
- \tex_romannumeral:D - 0
- \exp_after:wN \use_none:n
- \int_value:w #3 #2 #1 \scan_stop:
- }
- {
- \__kernel_msg_expandable_error:nnnn
- { kernel } { expr } {#4} {#1}
- }
- #1
- }
- }
- { }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_log-functions_on:, \@@_log-functions_off:}
-% \begin{macro}{\__kernel_debug_log:x}
-% These two functions (corresponding to the \pkg{expl3} option
-% \texttt{log-functions}) control whether \cs{__kernel_debug_log:x} writes to the
-% log file or not. Since \cs{iow_log:x} does not yet have its final
-% definition we do not use \cs{cs_set_eq:NN} (not defined yet anyway).
-% Once everything is defined, turn logging on or off depending on what
-% option was given. When debugging is not enabled, simply produce an
-% error.
% \begin{macrocode}
-\__kernel_if_debug:TF
- {
- \exp_args:Nc \cs_set_protected:Npn { @@_log-functions_on: }
- {
- \cs_set_protected:Npn \__kernel_debug_log:x
- { \@@_suspended:T \use_none:nn \iow_log:x }
- }
- \exp_args:Nc \cs_set_protected:Npn { @@_log-functions_off: }
- { \cs_set_protected:Npn \__kernel_debug_log:x { \use_none:n } }
- \tex_ifodd:D \l@expl@log@functions@bool
- \use:c { @@_log-functions_on: }
- \else:
- \use:c { @@_log-functions_off: }
- \fi:
- }
- { }
+\cs_set_protected:Npn \debug_suspend: { }
+\cs_set_protected:Npn \debug_resume: { }
% \end{macrocode}
% \end{macro}
-% \end{macro}
%
-% \begin{macro}{\@@_deprecation_on:, \@@_deprecation_off:}
% \begin{macro}{\__kernel_deprecation_code:nn}
% \begin{variable}{\g_@@_deprecation_on_tl, \g_@@_deprecation_off_tl}
% Some commands were more recently deprecated and not yet removed;
% only make these into errors if the user requests it. This relies on
% two token lists, filled up in \pkg{l3deprecation}.
% \begin{macrocode}
-\__kernel_if_debug:TF
- {
- \cs_set_protected:Npn \@@_deprecation_on:
- { \g_@@_deprecation_on_tl }
- \cs_set_protected:Npn \@@_deprecation_off:
- { \g_@@_deprecation_off_tl }
- \cs_set_nopar:Npn \g_@@_deprecation_on_tl { }
- \cs_set_nopar:Npn \g_@@_deprecation_off_tl { }
- \cs_set_protected:Npn \__kernel_deprecation_code:nn #1#2
- {
- \tl_gput_right:Nn \g_@@_deprecation_on_tl {#1}
- \tl_gput_right:Nn \g_@@_deprecation_off_tl {#2}
- }
- }
+\cs_set_nopar:Npn \g_@@_deprecation_on_tl { }
+\cs_set_nopar:Npn \g_@@_deprecation_off_tl { }
+\cs_set_protected:Npn \__kernel_deprecation_code:nn #1#2
{
- \cs_set_protected:Npn \__kernel_deprecation_code:nn #1#2 { }
+ \tl_gput_right:Nn \g_@@_deprecation_on_tl {#1}
+ \tl_gput_right:Nn \g_@@_deprecation_off_tl {#2}
}
% \end{macrocode}
% \end{variable}
% \end{macro}
-% \end{macro}
-%
-% \begin{macro}
-% {\__kernel_patch:nnNNpn, \__kernel_patch_conditional:nNNpnn}
-% \begin{macro}
-% {\@@_patch_aux:nnnn, \@@_patch_auxii:nnnn}
-% When debugging is not enabled, \cs{__kernel_patch:nnNNpn} and
-% \cs{__kernel_patch_conditional:nNNpnn} throw the patch away.
-% Otherwise they can be followed by \cs{cs_new:Npn} (or similar), and
-% \cs{prg_new_conditional:Npnn} (or similar), respectively. In each
-% case, grab the name of the function to be defined and its parameters
-% then insert tokens before and/or after the definition.
-% \begin{macrocode}
-\__kernel_if_debug:TF
- {
- \cs_set_protected:Npn \__kernel_patch:nnNNpn #1#2#3#4#5#
- { \@@_patch_aux:nnnn {#1} {#2} { #3 #4 #5 } }
- \cs_set_protected:Npn \__kernel_patch_conditional:nNNpnn #1#2#3#4#
- { \@@_patch_auxii:nnnn {#1} { #2 #3 #4 } }
- \cs_set_protected:Npn \@@_patch_aux:nnnn #1#2#3#4
- { #3 { #1 #4 #2 } }
- \cs_set_protected:Npn \@@_patch_auxii:nnnn #1#2#3#4
- { #2 {#3} { #1 #4 } }
- }
- {
- \cs_set_protected:Npn \__kernel_patch:nnNNpn #1#2 { }
- \cs_set_protected:Npn \__kernel_patch_conditional:nNNpnn #1 { }
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}
-% {\__kernel_patch_args:nNNpn, \__kernel_patch_conditional_args:nNNpnn}
-% \begin{macro}
-% {\__kernel_patch_args:nnnNNpn, \__kernel_patch_conditional_args:nnnNNpnn}
-% \begin{macro}
-% {
-% \@@_tmp:w,
-% \@@_patch_args_aux:nnnNNnn,
-% \@@_patch_args_aux:nnnNNnnn,
-% \@@_patch_args_aux:nnnn
-% }
-% See \cs{__kernel_patch:nnNNpn}. The first argument is something like
-% |{#1}{(#2)}|. Define a temporary macro using the \meta{parameters}
-% and \meta{code} of the definition that follows, then expand that
-% temporary macro in front of the first argument to obtain new
-% \meta{code}. Then perform the definition as if that new \meta{code}
-% was directly typed in the file.
-% \begin{macrocode}
-\cs_set_protected:Npn \__kernel_patch_args:nNNpn
- { \__kernel_patch_args:nnnNNpn { } { } }
-\cs_set_protected:Npn \__kernel_patch_conditional_args:nNNpnn
- { \__kernel_patch_conditional_args:nnnNNpnn { } { } }
-\__kernel_if_debug:TF
- {
- \cs_set_protected:Npn \__kernel_patch_args:nnnNNpn #1#2#3#4#5#6#
- { \@@_patch_args_aux:nnnNNnn {#1} {#2} {#3} #4 #5 {#6} }
- \cs_set_protected:Npn \__kernel_patch_conditional_args:nnnNNpnn
- #1#2#3#4#5#6#
- { \@@_patch_args_aux:nnnNNnnn {#1} {#2} {#3} #4 #5 {#6} }
- \cs_set_protected:Npn \@@_patch_args_aux:nnnNNnn #1#2#3#4#5#6#7
- {
- \cs_set:Npn \@@_tmp:w #6 {#7}
- \exp_after:wN \@@_patch_args_aux:nnnn \exp_after:wN
- { \@@_tmp:w #3 } { #4 #5 #6 } {#1} {#2}
- }
- \cs_set_protected:Npn \@@_patch_args_aux:nnnNNnnn #1#2#3#4#5#6#7#8
- {
- \cs_set:Npn \@@_tmp:w #6 {#8}
- \exp_after:wN \@@_patch_args_aux:nnnn \exp_after:wN
- { \@@_tmp:w #3 } { #4 #5 #6 {#7} } {#1} {#2}
- }
- \cs_set_protected:Npn \@@_patch_args_aux:nnnn #1#2#3#4
- { #2 { #3 #1 #4 } }
- }
- {
- \cs_set_protected:Npn \__kernel_patch_args:nnnNNpn #1#2#3 { }
- \cs_set_protected:Npn \__kernel_patch_conditional_args:nnnNNpnn
- #1#2#3 { }
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
%
% \subsection{Conditional processing and definitions}
%
@@ -2515,20 +2137,12 @@
#5 {#1} {#2} {#3} {#4}
\@@_set_eq_conditional_loop:nnnnNw {#1} {#2} {#3} {#4} #5
}
-\__kernel_patch:nnNNpn
- { \__kernel_chk_cs_exist:c { #5 _p : #6 } } { }
\cs_set:Npn \@@_set_eq_conditional_p_form:wNnnnn #1 \q_stop #2#3#4#5#6
{ #2 { #3 _p : #4 } { #5 _p : #6 } }
-\__kernel_patch:nnNNpn
- { \__kernel_chk_cs_exist:c { #5 : #6 TF } } { }
\cs_set:Npn \@@_set_eq_conditional_TF_form:wNnnnn #1 \q_stop #2#3#4#5#6
{ #2 { #3 : #4 TF } { #5 : #6 TF } }
-\__kernel_patch:nnNNpn
- { \__kernel_chk_cs_exist:c { #5 : #6 T } } { }
\cs_set:Npn \@@_set_eq_conditional_T_form:wNnnnn #1 \q_stop #2#3#4#5#6
{ #2 { #3 : #4 T } { #5 : #6 T } }
-\__kernel_patch:nnNNpn
- { \__kernel_chk_cs_exist:c { #5 : #6 F } } { }
\cs_set:Npn \@@_set_eq_conditional_F_form:wNnnnn #1 \q_stop #2#3#4#5#6
{ #2 { #3 : #4 F } { #5 : #6 F } }
% \end{macrocode}
@@ -2889,11 +2503,6 @@
% issued. We have to make sure we don't put the argument into the
% conditional processing since it may be an |\if...| type function!
% \begin{macrocode}
-\__kernel_patch:nnNNpn { }
- {
- \__kernel_debug_log:x
- { Defining~\token_to_str:N #1~ \msg_line_context: }
- }
\cs_set_protected:Npn \__kernel_chk_if_free_cs:N #1
{
\cs_if_free:NF #1
@@ -3591,6 +3200,28 @@
% \end{macro}
% \end{macro}
%
+% \subsection{Starting a paragraph}
+%
+% \begin{macro}{\mode_leave_vertical:}
+% The approach here is different to that used by \LaTeXe{} or plain \TeX{},
+% which unbox a void box to force horizontal mode. That inserts the
+% \tn{everypar} tokens \emph{before} the re-inserted unboxing tokens. The
+% approach here uses either the \tn{quitvmode} primitive or the equivalent
+% protected macro. In vertical mode, the \tn{indent} primitive is inserted:
+% this will switch to horizontal mode and insert \tn{everypar} tokens and
+% nothing else. Unlike the \LaTeXe{} version, the availability of \eTeX{}
+% means using a mode test can be done at for example the start of an
+% \tn{halign}.
+% \begin{macrocode}
+\cs_new_protected:Npn \mode_leave_vertical:
+ {
+ \if_mode_vertical:
+ \exp_after:wN \tex_indent:D
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macrocode}
%</initex|package>
% \end{macrocode}