summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/semantex
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2020-09-28 03:04:08 +0000
committerNorbert Preining <norbert@preining.info>2020-09-28 03:04:08 +0000
commit34310603e5253ef5742542e3f0123b341a70ee20 (patch)
tree51076d298e97a9c86619db3ada2af17e81c074d1 /macros/latex/contrib/semantex
parentac0ae0fcbd5ee121e6b9134cced71d961e30ed68 (diff)
CTAN sync 202009280304
Diffstat (limited to 'macros/latex/contrib/semantex')
-rw-r--r--macros/latex/contrib/semantex/semantex.pdfbin361207 -> 356833 bytes
-rw-r--r--macros/latex/contrib/semantex/semantex.sty578
-rw-r--r--macros/latex/contrib/semantex/semantex.tex257
-rw-r--r--macros/latex/contrib/semantex/stripsemantex.lua71
-rw-r--r--macros/latex/contrib/semantex/stripsemantex.sty87
5 files changed, 534 insertions, 459 deletions
diff --git a/macros/latex/contrib/semantex/semantex.pdf b/macros/latex/contrib/semantex/semantex.pdf
index 71f086e8d0..7ccf0be800 100644
--- a/macros/latex/contrib/semantex/semantex.pdf
+++ b/macros/latex/contrib/semantex/semantex.pdf
Binary files differ
diff --git a/macros/latex/contrib/semantex/semantex.sty b/macros/latex/contrib/semantex/semantex.sty
index e705b06886..dcbf1f9193 100644
--- a/macros/latex/contrib/semantex/semantex.sty
+++ b/macros/latex/contrib/semantex/semantex.sty
@@ -1,5 +1,5 @@
\RequirePackage{xparse,l3keys2e,leftindex}
-\ProvidesExplPackage{semantex}{2020/09/13}{0.43}{}
+\ProvidesExplPackage{semantex}{2020/09/27}{0.44}{}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
@@ -20,6 +20,7 @@
semtexfile .choice:,
semtexfile / true .code:n = \semantex_turn_semtex_file_on:,
semtexfile / false .code:n = \semantex_turn_semtex_file_off:,
+ semtexfile / .code:n = \semantex_turn_semtex_file_on:,
semtexfile / unknown .code:n = \msg_error:nnnn { semantex } { semantex_setup_key_value_not_found } { semtexfile } { #1 },
unknown .code:n = \msg_error:nnx { semantex } { semantex_setup_key_not_found } { \l_keys_key_str }
}
@@ -29,110 +30,23 @@
\keys_set:nn { semantex } { #1 }
}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% THE FOLLOWING SECTION IS IDENTICAL TO THE semtex PACKAGE
-%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-% These are some essential commands that are needed for bullets and parentheses,
-% and they are the only ones that will not be stripped by running the
-% stripsemantex algorithm. Therefore, they are also available as a standalone
-% package, called "semtex". This name is meant to suggest "stripped SemanTeX",
-% and at the same time, semtex is the name of a plastic explosive, suggesting
-% "blown-up SemanTeX".
-% (Mathematicians are not famous for the quality of their humour.)
-
-% Bullets:
-
-\box_if_exist:NF \g__semantex_bullet_box
-{
- \box_new:N \g__semantex_bullet_box
- \hbox_set:Nn \g__semantex_bullet_box { $\cdot$ }
- \box_scale:Nnn \g__semantex_bullet_box {1.2} {1.2}
- \tl_set:Nn\g_semantex_bullet
- {
- \box_move_up:nn{-0.25ex}{\box_use:N \g__semantex_bullet_box}
- }
-
- \tl_set:Nn\g_semantex_double_bullet{\g_semantex_bullet \g_semantex_bullet}
-
- \tl_set_eq:NN\SemantexBullet \g_semantex_bullet
-
- \tl_set_eq:NN \SemantexDoubleBullet \g_semantex_double_bullet
-}
-
-% Parentheses:
-
-\cs_set:Npn\SemantexLeft { \mathopen{}\mathclose\bgroup\left }
-
-\cs_set:Npn\SemantexRight { \aftergroup\egroup\right }
-
-\tl_set:Nn\SemantexDelimiterSize{}
-
-\DeclareDocumentCommand\SemantexParentheses { mmmm }
-{
- \str_case:nnF { #1 } % This is where \big,\Big, etc. go.
- {
- { normal } {
- \group_begin:
- \tl_clear:N \SemantexDelimiterSize
- \str_if_eq:nnF { #2 } { . } { \mathopen #2 }
- #4
- \str_if_eq:nnF { #3 } { . } { \mathclose #3 }
- \group_end:
- }
- { auto } {
- \group_begin:
- \tl_set_eq:NN \SemantexDelimiterSize \middle
- \SemantexLeft #2
- #4
- \SemantexRight #3
- \group_end:
- }
- { * } {
- \group_begin:
- \tl_set_eq:NN \SemantexDelimiterSize \middle
- \SemantexLeft #2
- #4
- \SemantexRight #3
- \group_end:
- }
- }
- {
- \group_begin:
- \tl_set_eq:NN\SemantexDelimiterSize #1
- \mathopen #1 #2
- #4
- \mathclose #1 #3
- \group_end:
- }
-}
-
-\DeclareDocumentCommand\SemantexNoParentheses { m }
-{
- \group_begin:
- \tl_clear:N\SemantexDelimiterSize
- #1
- \group_end:
-}
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% THE .semtex FILE
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\bool_new:N \g__semantex_semtex_file_was_opened
+\bool_new:N \g__semantex_semtex_file_was_opened_bool
\iow_new:N \g__semantex_semtex_file_stream_temp_iow
\cs_new_protected:Npn \semantex_turn_semtex_file_on:
{
- \bool_if:NF \g__semantex_semtex_file_was_opened
+ \bool_if:NF \g__semantex_semtex_file_was_opened_bool
{
\iow_open:Nn \g__semantex_semtex_file_stream_temp_iow { \jobname.semtex }
\iow_now:Nn \g__semantex_semtex_file_stream_temp_iow { \DeclareClass {\SemantexBaseObject } }
+ \iow_now:Nn \g__semantex_semtex_file_stream_temp_iow { \DeclareObject {\SemantexDelimiterSize } }
}
\cs_set:Npn\semantex_write_to_semtex_file:n##1
@@ -140,23 +54,38 @@
\iow_now:Nn \g__semantex_semtex_file_stream_temp_iow { ##1 }
}
- \bool_set_true:N \g__semantex_semtex_file_was_opened
+ \cs_set:Npn\semantex_write_to_semtex_file_V:N ##1
+ {
+ % We use this command instead of a :V variant
+ % in order to save time; when semtexfile=false,
+ % there is no reason to V-expand the argument.
+ \semantex_write_to_semtex_file:V ##1
+ }
+
+ \bool_set_true:N \g__semantex_semtex_file_was_opened_bool
}
\cs_new_protected:Npn \semantex_turn_semtex_file_off:
{
- \bool_if:NT \g__semantex_semtex_file_was_opened
+ \bool_if:NT \g__semantex_semtex_file_was_opened_bool
{
\iow_close:N \g__semantex_semtex_file_stream_temp_iow
}
\cs_set:Npn\semantex_write_to_semtex_file:n##1 {}
- \bool_set_false:N \g__semantex_semtex_file_was_opened
+ \cs_set:Npn\semantex_write_to_semtex_file_V:N ##1 {}
+ % We use this command instead of a :V variant
+ % in order to save time; when semtexfile=false,
+ % there is no reason to V-expand the argument.
+
+ \bool_set_false:N \g__semantex_semtex_file_was_opened_bool
}
\semantex_turn_semtex_file_off:
+\cs_generate_variant:Nn \semantex_write_to_semtex_file:n { V }
+
\cs_new_protected:Npn\semantex_write_original_source_to_semtex_file:n#1
{
\semantex_write_to_semtex_file:n { \BeginSource }
@@ -170,6 +99,8 @@
\semantex_write_to_semtex_file:n { #1 }
}
+\cs_set_eq:NN\SemantexAddToRecordedSource\semantex_add_to_existing_original_source_in_semtex_file:n
+
\cs_new_protected:Npn\semantex_write_output_to_semtex_file:n#1
{
\semantex_write_to_semtex_file:n { \EndSource }
@@ -178,9 +109,15 @@
\semantex_write_to_semtex_file:n { \EndOutput }
}
-\cs_generate_variant:Nn\semantex_write_output_to_semtex_file:n { V }
+\cs_set_eq:NN\SemantexRecordOutput\semantex_write_output_to_semtex_file:n
-\cs_generate_variant:Nn\semantex_write_original_source_to_semtex_file:n { o }
+\cs_new_protected:Npn\semantex_write_output_to_semtex_file_V:N#1
+{
+ \semantex_write_to_semtex_file:n { \EndSource }
+ \semantex_write_to_semtex_file:n { \BeginOutput }
+ \semantex_write_to_semtex_file_V:N #1
+ \semantex_write_to_semtex_file:n { \EndOutput }
+}
\cs_new_protected:Npn\semantex_write_class_declaration_to_semtex_file:n#1
{
@@ -199,6 +136,99 @@
\cs_set_eq:NN\SemantexRecordObject\semantex_write_object_declaration_to_semtex_file:n
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% THE FOLLOWING SECTION IS IDENTICAL TO THE semtex PACKAGE
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% These are some essential commands that are needed for bullets and parentheses,
+% and they are the only ones that will not be stripped by running the
+% stripsemantex algorithm. Therefore, they are also available as a standalone
+% package, called "semtex". This name is meant to suggest "stripped SemanTeX",
+% and at the same time, semtex is the name of a plastic explosive, suggesting
+% "blown-up SemanTeX".
+% (Mathematicians are not famous for the quality of their humour.)
+
+% Bullets:
+
+\box_if_exist:NF \g__semantex_bullet_box
+{
+ \box_new:N \g__semantex_bullet_box
+ \hbox_set:Nn \g__semantex_bullet_box { $\cdot$ }
+ \box_scale:Nnn \g__semantex_bullet_box {1.2} {1.2}
+ \tl_set:Nn\g_semantex_bullet
+ {
+ \box_move_up:nn{-0.25ex}{\box_use:N \g__semantex_bullet_box}
+ }
+
+ \tl_set:Nn\g_semantex_double_bullet{\g_semantex_bullet \g_semantex_bullet}
+
+ \tl_set_eq:NN\SemantexBullet \g_semantex_bullet
+
+ \tl_set_eq:NN \SemantexDoubleBullet \g_semantex_double_bullet
+}
+
+% Parentheses:
+
+\cs_set:Npn\SemantexLeft { \mathopen{}\mathclose\bgroup\left }
+
+\cs_set:Npn\SemantexRight { \aftergroup\egroup\right }
+
+\DeclareDocumentCommand\SemantexDelimiterSize { }
+{
+ \semantex_write_original_source_to_semtex_file:n { \SemantexDelimiterSize }
+ \semantex_write_output_to_semtex_file_V:N \l_semantex_delimiter_size_temp_tl
+ \l_semantex_delimiter_size_temp_tl
+}
+
+\DeclareDocumentCommand\RecordSemantexDelimiterSize { }
+{
+ \semantex_write_output_to_semtex_file_V:N \l_semantex_delimiter_size_temp_tl
+}
+
+\DeclareDocumentCommand\SemantexDelimiterSizeNoRecord { }
+{
+ \l_semantex_delimiter_size_temp_tl
+}
+
+\DeclareDocumentCommand\SemantexMathOpen { mm }
+{
+ \group_begin:
+ \tl_set:Nn\l_semantex_delimiter_size_temp_tl { #1 }
+ \str_if_eq:nnF { #2 } { . } { \mathopen #1 #2 }
+}
+
+\DeclareDocumentCommand\SemantexMathClose { mm }
+{
+ \str_if_eq:nnF { #2 } { . } { \mathclose #1 #2 }
+ \group_end:
+}
+
+\DeclareDocumentCommand\SemantexMathOpenAuto { m }
+{
+ \group_begin:
+ \tl_set:Nn\l_semantex_delimiter_size_temp_tl { \middle }
+ \SemantexLeft #1
+}
+
+\DeclareDocumentCommand\SemantexMathCloseAuto { m }
+{
+ \SemantexRight #1
+ \group_end:
+}
+
+\DeclareDocumentCommand\SemantexMathOpenNoPar { }
+{
+ \group_begin:
+ \tl_clear:N\l_semantex_delimiter_size_temp_tl
+}
+
+\DeclareDocumentCommand\SemantexMathCloseNoPar { }
+{
+ \group_end:
+}
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% USER COMMANDS FOR CREATING NEW CLASSES
@@ -1572,20 +1602,6 @@
\semantex_data_bool_get:nnTF { #1 } { output } % Checks if the register is supposed to output
{
\semantex_inner_return:n { #1 }
- \semantex_data_int_if_positive:nnTF { #1 } { numberofarguments } % Checks if more than one argument has been received, i.e. whether we want to render any argument
- {
- \semantex_data_bool_get:nnTF { #1 } { leftargument } % Checks if left or right argument
- {
- \semantex_left_return:n { #1 }
- }
- {
- \semantex_right_return:n { #1 }
- }
- }
- {
- % do nothing
- }
- \tl_set:Nx\l__semantex_render_symbol_temp_tl { \semantex_data_tl_get_exp_not:nn { #1 } { symbol } } % Stores the symbol in a temporary command
\tl_set:Nx \l__semantex_render_output_class_temp_tl { \semantex_data_tl_get:nn { #1 } { output } } % The output class
\exp_args:NNx\cs_set:Nn\l__semantex_render_outputoptions_temp_cs:n
{ \semantex_data_tl_get_exp_not:nn { #1 } { outputoptions } }
@@ -1602,51 +1618,130 @@
{
\l__semantex_render_outputoptions_temp_tl
} % This was necessary, trust me.
- \tl_set:Nx \l__semantex_render_temp_tl
- {
- \exp_not:c {
- __semantex_make_object_of_\l__semantex_render_output_class_temp_tl _with_options:nnw
- }
- % This is for outputting -- the command
- % \__semantex_make_object_of_class_???_with_options:nnw
- % makes a one-time object of class ??? and allows us to
- % immediately pass options to it
- {
- \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
- { upperputleft } { \semantex_data_tl_get_exp_not:nn { #1 } { upper } }
- \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
- { lowerputleft } { \semantex_data_tl_get_exp_not:nn { #1 } { lower } }
- \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
- { upperleftputright } { \semantex_data_tl_get_exp_not:nn { #1 } { upperleft } }
- \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
- { lowerleftputright } { \semantex_data_tl_get_exp_not:nn { #1 } { lowerleft } }
- \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
- { preupper } { \semantex_data_tl_get_exp_not:nn { #1 } { preupper } }
- \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
- { postupper } { \semantex_data_tl_get_exp_not:nn { #1 } { postupper } }
- \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
- { prelower } { \semantex_data_tl_get_exp_not:nn { #1 } { prelower } }
- \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
- { postlower } { \semantex_data_tl_get_exp_not:nn { #1 } { postlower } }
- \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
- { preupperleft } { \semantex_data_tl_get_exp_not:nn { #1 } { preupperleft } }
- \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
- { postupperleft } { \semantex_data_tl_get_exp_not:nn { #1 } { postupperleft } }
- \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
- { prelowerleft } { \semantex_data_tl_get_exp_not:nn { #1 } { prelowerleft } }
- \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
- { postlowerleft } { \semantex_data_tl_get_exp_not:nn { #1 } { postlowerleft } }
- \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
- { heightphantom } { \semantex_data_tl_get_exp_not:nn { #1 } { heightphantom } }
- \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
- { slantingphantom } { \semantex_data_tl_get_exp_not:nn { #1 } { slantingphantom } }
- \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
- { texclass } { \semantex_data_tl_get_exp_not:nn { #1 } { texclass } }
- \exp_not:V \l__semantex_render_outputoptions_temp_tl
- % These are the options we pass to the output class so that it
- % can eventually render it
- }
- { \exp_not:V \l__semantex_render_symbol_temp_tl }
+ \semantex_data_int_if_positive:nnTF { #1 } { numberofarguments } % Checks if more than one argument has been received, i.e. whether we want to render any argument
+ {
+ \semantex_data_bool_get:nnTF { #1 } { leftargument } % Checks if left or right argument
+ {
+ \semantex_left_pre_return:n { #1 }
+ \tl_set:Nx\l__semantex_render_symbol_temp_tl { \semantex_data_tl_get_exp_not:nn { #1 } { symbol } } % Stores the symbol in a temporary command
+ \tl_set:Nx \l__semantex_render_temp_tl
+ {
+ \exp_not:c {
+ __semantex_make_object_of_\l__semantex_render_output_class_temp_tl _with_options:nnw
+ }
+ % This is for outputting -- the command
+ % \__semantex_make_object_of_class_???_with_options:nnw
+ % makes a one-time object of class ??? and allows us to
+ % immediately pass options to it
+ {
+ \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
+ { upperputleft } { \semantex_data_tl_get_exp_not:nn { #1 } { upper } }
+ \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
+ { lowerputleft } { \semantex_data_tl_get_exp_not:nn { #1 } { lower } }
+ \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
+ { preupper } { \semantex_data_tl_get_exp_not:nn { #1 } { preupper } }
+ \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
+ { postupper } { \semantex_data_tl_get_exp_not:nn { #1 } { postupper } }
+ \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
+ { prelower } { \semantex_data_tl_get_exp_not:nn { #1 } { prelower } }
+ \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
+ { postlower } { \semantex_data_tl_get_exp_not:nn { #1 } { postlower } }
+ \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
+ { texclass } { \semantex_data_tl_get_exp_not:nn { #1 } { texclass } }
+ \exp_not:V \l__semantex_render_outputoptions_temp_tl
+ % These are the options we pass to the output class so that it
+ % can eventually render it
+ }
+ { \exp_not:V \l__semantex_render_symbol_temp_tl }
+ }
+ }
+ {
+ \semantex_right_pre_return:n { #1 }
+ \tl_set:Nx\l__semantex_render_symbol_temp_tl { \semantex_data_tl_get_exp_not:nn { #1 } { symbol } } % Stores the symbol in a temporary command
+ \tl_set:Nx \l__semantex_render_temp_tl
+ {
+ \exp_not:c {
+ __semantex_make_object_of_\l__semantex_render_output_class_temp_tl _with_options:nnw
+ }
+ % This is for outputting -- the command
+ % \__semantex_make_object_of_class_???_with_options:nnw
+ % makes a one-time object of class ??? and allows us to
+ % immediately pass options to it
+ {
+ \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
+ { upperleftputright } { \semantex_data_tl_get_exp_not:nn { #1 } { upperleft } }
+ \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
+ { lowerleftputright } { \semantex_data_tl_get_exp_not:nn { #1 } { lowerleft } }
+ \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
+ { preupperleft } { \semantex_data_tl_get_exp_not:nn { #1 } { preupperleft } }
+ \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
+ { postupperleft } { \semantex_data_tl_get_exp_not:nn { #1 } { postupperleft } }
+ \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
+ { prelowerleft } { \semantex_data_tl_get_exp_not:nn { #1 } { prelowerleft } }
+ \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
+ { postlowerleft } { \semantex_data_tl_get_exp_not:nn { #1 } { postlowerleft } }
+ \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
+ { heightphantom } { \semantex_data_tl_get_exp_not:nn { #1 } { heightphantom } }
+ \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
+ { slantingphantom } { \semantex_data_tl_get_exp_not:nn { #1 } { slantingphantom } }
+ \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
+ { texclass } { \semantex_data_tl_get_exp_not:nn { #1 } { texclass } }
+ \exp_not:V \l__semantex_render_outputoptions_temp_tl
+ % These are the options we pass to the output class so that it
+ % can eventually render it
+ }
+ { \exp_not:V \l__semantex_render_symbol_temp_tl }
+ }
+ }
+ }
+ {
+ \tl_set:Nx\l__semantex_render_symbol_temp_tl { \semantex_data_tl_get_exp_not:nn { #1 } { symbol } } % Stores the symbol in a temporary command
+ \tl_set:Nx \l__semantex_render_temp_tl
+ {
+ \exp_not:c {
+ __semantex_make_object_of_\l__semantex_render_output_class_temp_tl _with_options:nnw
+ }
+ % This is for outputting -- the command
+ % \__semantex_make_object_of_class_???_with_options:nnw
+ % makes a one-time object of class ??? and allows us to
+ % immediately pass options to it
+ {
+ \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
+ { upperputleft } { \semantex_data_tl_get_exp_not:nn { #1 } { upper } }
+ \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
+ { lowerputleft } { \semantex_data_tl_get_exp_not:nn { #1 } { lower } }
+ \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
+ { upperleftputright } { \semantex_data_tl_get_exp_not:nn { #1 } { upperleft } }
+ \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
+ { lowerleftputright } { \semantex_data_tl_get_exp_not:nn { #1 } { lowerleft } }
+ \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
+ { preupper } { \semantex_data_tl_get_exp_not:nn { #1 } { preupper } }
+ \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
+ { postupper } { \semantex_data_tl_get_exp_not:nn { #1 } { postupper } }
+ \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
+ { prelower } { \semantex_data_tl_get_exp_not:nn { #1 } { prelower } }
+ \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
+ { postlower } { \semantex_data_tl_get_exp_not:nn { #1 } { postlower } }
+ \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
+ { preupperleft } { \semantex_data_tl_get_exp_not:nn { #1 } { preupperleft } }
+ \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
+ { postupperleft } { \semantex_data_tl_get_exp_not:nn { #1 } { postupperleft } }
+ \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
+ { prelowerleft } { \semantex_data_tl_get_exp_not:nn { #1 } { prelowerleft } }
+ \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
+ { postlowerleft } { \semantex_data_tl_get_exp_not:nn { #1 } { postlowerleft } }
+ \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
+ { heightphantom } { \semantex_data_tl_get_exp_not:nn { #1 } { heightphantom } }
+ \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
+ { slantingphantom } { \semantex_data_tl_get_exp_not:nn { #1 } { slantingphantom } }
+ \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
+ { texclass } { \semantex_data_tl_get_exp_not:nn { #1 } { texclass } }
+ \exp_not:V \l__semantex_render_outputoptions_temp_tl
+ % These are the options we pass to the output class so that it
+ % can eventually render it
+ }
+ { \exp_not:V \l__semantex_render_symbol_temp_tl }
+ }
}
}
{
@@ -1669,7 +1764,7 @@
}
}
\group_begin:
- \semantex_write_output_to_semtex_file:V \l__semantex_render_temp_tl
+ \semantex_write_output_to_semtex_file_V:N \l__semantex_render_temp_tl
% Adds the output to the .semtex file, if this has been turned on,
% which it is not by default.
\group_end:
@@ -1703,113 +1798,78 @@
\cs_new_protected:Npn \semantex_parentheses_store:nN#1#2
{
\semantex_data_tl_get_store:nnN { #1 } { parsize } \l__semantex_parentheses_store_temp_tl
- \semantex_data_bool_get:nnTF { #1 } { allowSemantexDelimiterSize }
+ \str_case:VnF { \l__semantex_parentheses_store_temp_tl } % This is where \big,\Big, etc. go.
{
- \tl_set:Nn#2 { \SemantexParentheses }
- \tl_put_right:Nx#2
- {
- { \exp_not:V \l__semantex_parentheses_store_temp_tl }
- { \semantex_data_tl_get_exp_not:nn { #1 } { leftpar } }
- { \semantex_data_tl_get_exp_not:nn { #1 } { rightpar } }
+ { normal } {
+ \tl_set:Nx #2
{
+ \exp_not:N \SemantexMathOpen { }
+ \semantex_data_tl_get_exp_not:nn { #1 } { leftpar }
\semantex_data_tl_get_exp_not:nn { #1 } { prearg }
\semantex_data_tl_get_exp_not:nn { #1 } { arg }
\semantex_data_tl_get_exp_not:nn { #1 } { postarg }
+ \exp_not:N \SemantexMathClose { }
+ \semantex_data_tl_get_exp_not:nn { #1 } { rightpar }
}
}
- }
- {
- \str_case:VnF { \l__semantex_parentheses_store_temp_tl } % This is where \big,\Big, etc. go.
- {
- { normal } {
- \tl_set:Nx#2
- {
- \semantex_data_tl_get_exp_not:nn { #1 } { prearg }
- \semantex_data_tl_get_exp_not:nn { #1 } { arg }
- \semantex_data_tl_get_exp_not:nn { #1 } { postarg }
- }
- \str_if_eq:xnF { \semantex_data_tl_get_exp_not:nn { #1 } { leftpar } } { . }
- {
- \tl_put_left:Nx#2
- {
- \exp_not:N \mathopen \semantex_data_tl_get_exp_not:nn { #1 } { leftpar }
- }
- }
- \str_if_eq:xnF { \semantex_data_tl_get_exp_not:nn { #1 } { rightpar } } { . }
- {
- \tl_put_right:Nx#2
- {
- \exp_not:N \mathclose \semantex_data_tl_get_exp_not:nn { #1 } { rightpar }
- }
- }
- }
- { auto } {
- \tl_set:Nx#2
- {
- \exp_not:N \SemantexLeft \semantex_data_tl_get_exp_not:nn { #1 } { leftpar }
- \semantex_data_tl_get_exp_not:nn { #1 } { prearg }
- \semantex_data_tl_get_exp_not:nn { #1 } { arg }
- \semantex_data_tl_get_exp_not:nn { #1 } { postarg }
- \exp_not:N \SemantexRight \semantex_data_tl_get_exp_not:nn { #1 } { rightpar }
- }
- }
- { * } {
- \tl_set:Nx#2
- {
- \exp_not:N \SemantexLeft \semantex_data_tl_get_exp_not:nn { #1 } { leftpar }
- \semantex_data_tl_get_exp_not:nn { #1 } { prearg }
- \semantex_data_tl_get_exp_not:nn { #1 } { arg }
- \semantex_data_tl_get_exp_not:nn { #1 } { postarg }
- \exp_not:N \SemantexRight \semantex_data_tl_get_exp_not:nn { #1 } { rightpar }
- }
- }
- }
- {
- \tl_set:Nx#2
+ { auto } {
+ \tl_set:Nx #2
{
- \exp_not:N \mathopen
- \exp_not:V \l__semantex_parentheses_store_temp_tl
+ \exp_not:N \SemantexMathOpenAuto
\semantex_data_tl_get_exp_not:nn { #1 } { leftpar }
\semantex_data_tl_get_exp_not:nn { #1 } { prearg }
\semantex_data_tl_get_exp_not:nn { #1 } { arg }
\semantex_data_tl_get_exp_not:nn { #1 } { postarg }
- \exp_not:N \mathclose
- \exp_not:V \l__semantex_parentheses_store_temp_tl
+ \exp_not:N \SemantexMathCloseAuto
\semantex_data_tl_get_exp_not:nn { #1 } { rightpar }
}
}
- }
-}
-
-\cs_generate_variant:Nn \str_case:nnF { VnF }
-
-\cs_generate_variant:Nn \str_if_eq:nnF { xnF }
-
-\cs_new_protected:Npn \semantex_no_parentheses_store:nN#1#2
-% The central command for handling the rendering of arguments with no parentheses around
-{
- \semantex_data_bool_get:nnTF { #1 } { allowSemantexDelimiterSize }
- {
- \tl_set:Nn#2 { \SemantexNoParentheses }
- \tl_put_right:Nx#2
- {
+ { * } {
+ \tl_set:Nx #2
{
+ \exp_not:N \SemantexMathOpenAuto
+ \semantex_data_tl_get_exp_not:nn { #1 } { leftpar }
\semantex_data_tl_get_exp_not:nn { #1 } { prearg }
\semantex_data_tl_get_exp_not:nn { #1 } { arg }
\semantex_data_tl_get_exp_not:nn { #1 } { postarg }
+ \exp_not:N \SemantexMathCloseAuto
+ \semantex_data_tl_get_exp_not:nn { #1 } { rightpar }
}
}
}
{
- \tl_set:Nx#2
+ \tl_set:Nx #2
{
+ \exp_not:N \SemantexMathOpen
+ \exp_not:V \l__semantex_parentheses_store_temp_tl
+ \semantex_data_tl_get_exp_not:nn { #1 } { leftpar }
\semantex_data_tl_get_exp_not:nn { #1 } { prearg }
\semantex_data_tl_get_exp_not:nn { #1 } { arg }
\semantex_data_tl_get_exp_not:nn { #1 } { postarg }
+ \exp_not:N \SemantexMathClose
+ \exp_not:V \l__semantex_parentheses_store_temp_tl
+ \semantex_data_tl_get_exp_not:nn { #1 } { rightpar }
}
}
}
+\cs_generate_variant:Nn \str_case:nnF { VnF }
+
+\cs_generate_variant:Nn \str_if_eq:nnF { xnF }
+
+\cs_new_protected:Npn \semantex_no_parentheses_store:nN#1#2
+% The central command for handling the rendering of arguments with no parentheses around
+{
+ \tl_set:Nx#2
+ {
+ \exp_not:N\SemantexMathOpenNoPar
+ \semantex_data_tl_get_exp_not:nn { #1 } { prearg }
+ \semantex_data_tl_get_exp_not:nn { #1 } { arg }
+ \semantex_data_tl_get_exp_not:nn { #1 } { postarg }
+ \exp_not:N\SemantexMathCloseNoPar
+ }
+}
+
\cs_new_protected:Npn \__semantex_symbol_parentheses_store:nnnnN#1#2#3#4#5
% The central command handling the rendering of symbol parentheses
{
@@ -2188,7 +2248,6 @@
\cs_new_protected:Npn \_semantex_arg_return_store:nN#1#2
{
- \semantex_data_tl_get_store:nnN { #1 } { parsize } \l__arg_return_store_parsize_temp_tl
\semantex_data_bool_get:nnTF { #1 } { par }
{
\semantex_data_int_if_positive:nnTF { #1 } { numberofarguments }
@@ -5621,8 +5680,6 @@
dataprovide=parseoptions,
dataprovide=texclass,
boolprovide=leftargument,
- boolprovide=allowSemantexDelimiterSize,
- boolsettrue=allowSemantexDelimiterSize,
dataprovide=heightphantom,
dataprovide=slantingphantom,
execute={ \semantex_data_seq_provide:nn { \semantex_this: } { commands_sequence } },
@@ -5692,21 +5749,6 @@
},
},
},
- {allowSemantexDelimiterSize}{
- strifeqTF={#1}{true}
- {
- boolsettrue={allowSemantexDelimiterSize},
- }
- {
- strifeqTF={#1}{false}
- {
- boolsetfalse={allowSemantexDelimiterSize},
- }
- {
- ERRORkeyvaluenotfound={allowSemantexDelimiterSize}{#1},
- }
- },
- },
{default}{si={#1}},
{degreedefault}{sd={#1}},
{arg}{ execute={ \semantex_arg_singlekeys_set:nn { ##1 } { #1 } } },
@@ -5893,7 +5935,9 @@
},
},
{parsize}{
- execute={ \semantex_data_tl_set:nnn { ##1 } { parsize } { #1 } },
+ execute={
+ \semantex_data_tl_set:nnn { ##1 } { parsize } { #1 }
+ },
},
{leftpar}{
execute={ \semantex_data_tl_set:nnn { ##1 } { leftpar } { #1 } },
@@ -6023,12 +6067,16 @@
},
{preupper}{
execute={
- \semantex_data_tl_put_left:nnn { ##1 } { preupper } { #1 }
+ \tl_if_blank:nF{#1}{
+ \semantex_data_tl_put_left:nnn { ##1 } { preupper } { #1 }
+ }
},
},
{postupper}{
execute={
- \semantex_data_tl_put_right:nnn { ##1 } { postupper } { #1 }
+ \tl_if_blank:nF{#1}{
+ \semantex_data_tl_put_right:nnn { ##1 } { postupper } { #1 }
+ }
},
},
{upperputleft}{
@@ -6203,12 +6251,16 @@
},
{prelower}{
execute={
- \semantex_data_tl_put_left:nnn { ##1 } { prelower } { #1 }
+ \tl_if_blank:nF{#1}{
+ \semantex_data_tl_put_left:nnn { ##1 } { prelower } { #1 }
+ }
},
},
{postlower}{
execute={
- \semantex_data_tl_put_right:nnn { ##1 } { postlower } { #1 }
+ \tl_if_blank:nF{#1}{
+ \semantex_data_tl_put_right:nnn { ##1 } { postlower } { #1 }
+ }
},
},
{lowerputleft}{
@@ -6383,12 +6435,16 @@
},
{preupperleft}{
execute={
- \semantex_data_tl_put_left:nnn { ##1 } { preupperleft } { #1 }
+ \tl_if_blank:nF{#1}{
+ \semantex_data_tl_put_left:nnn { ##1 } { preupperleft } { #1 }
+ }
},
},
{postupperleft}{
execute={
- \semantex_data_tl_put_right:nnn { ##1 } { postupperleft } { #1 }
+ \tl_if_blank:nF{#1}{
+ \semantex_data_tl_put_right:nnn { ##1 } { postupperleft } { #1 }
+ }
},
},
{upperleftputright}{
@@ -6563,12 +6619,16 @@
},
{prelowerleft}{
execute={
- \semantex_data_tl_put_left:nnn { ##1 } { prelowerleft } { #1 }
+ \tl_if_blank:nF{#1}{
+ \semantex_data_tl_put_left:nnn { ##1 } { prelowerleft } { #1 }
+ }
},
},
{postlowerleft}{
execute={
- \semantex_data_tl_put_right:nnn { ##1 } { postlowerleft } { #1 }
+ \tl_if_blank:nF{#1}{
+ \semantex_data_tl_put_right:nnn { ##1 } { postlowerleft } { #1 }
+ }
},
},
{lowerleftputright}{
diff --git a/macros/latex/contrib/semantex/semantex.tex b/macros/latex/contrib/semantex/semantex.tex
index 1ce506b54f..e692b55010 100644
--- a/macros/latex/contrib/semantex/semantex.tex
+++ b/macros/latex/contrib/semantex/semantex.tex
@@ -38,7 +38,7 @@
\usepackage[nameinlink]{cleveref}
-\title{Seman\!\TeX: semantic, keyval-based mathematics (v0.43)}
+\title{Seman\!\TeX: semantic, keyval-based mathematics (v0.44)}
\date{\today}
\author{Sebastian Ørsted (\href{mailto:sorsted@gmail.com}{sorsted@gmail.com})}
@@ -220,8 +220,6 @@
\makeatother
-
-
\begin{document}
\maketitle
@@ -890,8 +888,8 @@ Adding support for free algebras, power series, and Laurent series is almost as
{laurent}{
par,
leftpar=(, rightpar=),
- prearg={\!\!\mathopen\SemantexDelimiterSize(},
- postarg={\mathclose\SemantexDelimiterSize)\!\!},
+ prearg={\!\!\mathopen{}\SemantexDelimiterSize(},
+ postarg={\SemantexDelimiterSize)\mathclose{}\!\!},
% The "prearg" and "postarg" are printed before after
% the argument, if the argument is non-empty.
% The command "\SemantexDelimiterSize" is substituted
@@ -916,8 +914,8 @@ Adding support for free algebras, power series, and Laurent series is almost as
{laurent}{
par,
leftpar=(, rightpar=),
- prearg={\!\!\mathopen\SemantexDelimiterSize(},
- postarg={\mathclose\SemantexDelimiterSize)\!\!},
+ prearg={\!\!\mathopen{}\SemantexDelimiterSize(},
+ postarg={\SemantexDelimiterSize)\mathclose{}\!\!},
% These are printed before and after the argument.
% The command "\SemantexDelimiterSize" is substituted
% by \big, \Big, ..., or whatever size the
@@ -1933,17 +1931,20 @@ $\norm{\va}$,
$\inner{\va,\vb}$,
$\inner{slot,slot}$
\end{LTXexample}
+
We can also use it for more complicated constructions, like sets.
-The following is inspired from the \pack{mathtools} package where a similar construction is created using the commands from that package. My impression is that Lars Madsen is the main mastermind behind the code I use for the \lstinline!\where!~command:
+The following is inspired from the \pack{mathtools} package where a similar construction is created using the commands from that package. My impression is that Lars Madsen is the main mastermind behind the code I use for the \lstinline!\where!~construction:
\begin{lstlisting}
-\newcommand\where{
+\newcommand\wherecommand[1]{
\nonscript\:
- \SemantexDelimiterSize\vert
+ #1\vert
\allowbreak
\nonscript\:
\mathopen{}
}
+\NewObject\MyVar\where{ \wherecommand{\SemantexDelimiterSize} }
+
\NewObject\MyDelim\Set{\lbrace}{\rbrace}[
prearg={\,},postarg={\,},
% adds \, inside {...}, as recommended by D. Knuth
@@ -1951,20 +1952,24 @@ The following is inspired from the \pack{mathtools} package where a similar cons
% this turns off all keyval syntax in the argument
]
\end{lstlisting}
-\newcommand\where{
+\newcommand\wherecommand[1]{
\nonscript\:
- \SemantexDelimiterSize\vert
+ #1\vert
\allowbreak
\nonscript\:
\mathopen{}
}
+\NewObject\MyVar\where{ \wherecommand{\SemantexDelimiterSize} }
+
\NewObject\MyDelim\Set{\lbrace}{\rbrace}[
prearg={\,},postarg={\,},
% adds \, inside {...}, as recommended by D. Knuth
argkeyval=false,
% this turns off all keyval syntax in the argument
]
+
+\noindent
As we briefly mentioned previously,
\lstinline!\SemantexDelimiterSize!~is a command
that returns the size of the delimiters in the
@@ -1975,7 +1980,7 @@ $\Set{ \vx\in\vY \where \vx\ge0 }$,
$\Set[par=\big]{ \vx\in\vY \where \vx\ge0 }$
\end{LTXexample}
Don't forget that, since the class~\lstinline!\MyDelim! inherits from~\lstinline!\MyVar!,
-the output of any of these commands has class~\lstinline!\MyVar!.
+the output of any of these commands also belongs to class~\lstinline!\MyVar!.
So you can do stuff like
\begin{LTXexample}
$\Set{
@@ -2755,6 +2760,8 @@ Let us see it in action:
\partialdif[\vu^2,\vv^2,
d=4,raise=false]{
\vf },
+\]
+\[
\partialdif[\vx[1],
\vx[2],...,\vx[\vn],
d=\vn,raise=false]{
@@ -2794,27 +2801,21 @@ The system has the following limitations:
\item It is currently only able to strip the \semantex markup from your main document (so it will ignore anything in \lstinline!\input{...}! and~\lstinline!\include{...}!). So prior to running \pack{stripsemantex},
you should include your entire document body in your
main \texttt{.tex}~file.
+ \item Partly because of the previous point, no attempt is made to remove
+ the \emph{setup} of \semantex,
+ so commands like \lstinline!\NewObject!, \lstinline!\SetupObject!, and~\lstinline!\SetupClass!
+ will remain in the document body.
+ You will then have to remove these yourself afterwards.
+ But the \semantex markup itself should be stripped completely from your document.
\item As mentioned, as long as you do normal, supported things,
everything should work fine. Non-normal, non-supported
things are tings like
\begin{lstlisting}
\va[execute={\vb}]
\end{lstlisting}
- \item Occasionally, you will have to run the stripping algorithm
- multiple times. This happens e.g.~if you have
- a key that does stuff like \lstinline!symbolputleft=\vH[d=0]!,
- i.e.~keys that are defined using other objects. When you run
- \pack{stripsemantex}, such objects will remain in the text until you run it again.
- \item Partly because of the previous point, no attempt is made to remove
- the \emph{setup} of \semantex,
- so commands like \lstinline!\NewObject!, \lstinline!\SetupObject!, and~\lstinline!\SetupClass!
- will remain in the document body.
- You will then have to remove these yourself afterwards.
- But the \semantex markup itself should be stripped completely from your document
- (possibly after more than one run of the algorithm).
\item Things might go wrong if you define new keys
between \lstinline!\begin{document}! and~\lstinline!\end{document}!
- whose definitions make use of \semantex objects or classes,
+ whose definitions make use of other \semantex objects or classes,
since the algorithm will try to strip these from the definitions.
For instance, don't do stuff like this
after~\lstinline!\begin{document}!:
@@ -2833,9 +2834,20 @@ The system has the following limitations:
\item When the document has just been stripped,
it will load a small package called \pack{semtex},
which contains a couple of commands that the output will need
- in order to run. You should be able to replace most (often all) of these commands
+ in order to run. You will be able to replace all of these commands
by other commands and then render the package \pack{semtex}
unnecessary. More on this in \cref{sec:semtex_package}.
+ \item When \semantex runs, the content of any argument is being wrapped
+ between \lstinline!\begingroup! and~\lstinline!\endgroup!. This is part of what
+ makes it possible to use the command~\lstinline!\SemantexDelimiterSize!.
+ However, these \lstinline!\begingroup! and~\lstinline!\endgroup! will not appear
+ in the stripped document. This means that if you do stuff like
+ \begin{lstlisting}
+$ \def\foo{bar} \va{ \def\foo{barbar} \vx } \foo $
+ \end{lstlisting}
+ then this will print~\( \va{\vx} bar \) before running \pack{stripsemantex},
+ but~\( \va{\vx} barbar \) after. In order to avoid this, simply don't define
+ commands inside arguments, which you should never do in the first place (and why would you anyway?).
\end{itemize}
As a small proof of concept, this is what the example in the introduction
@@ -2870,9 +2882,9 @@ you can have a look at my latest paper, which was stripped with
When you have stripped your document and removed all \semantex package setup, it should be safe to remove
the loading of \semantex from your preamble.
However, the stripping algorithm will automatically
-add the following right before~\lstinline!\begin{document}!:
+add the following lines to your document right before~\lstinline!\begin{document}!:
\begin{lstlisting}
-% The following was added by "stripsemantex"
+% The following was added by "stripsemantex":
\usepackage{semtex,leftindex,graphicx}
@@ -2896,18 +2908,12 @@ possible left indices. The package~\pack{graphicx}
is loaded to provide the command~\lstinline!\scalebox!.
This package~\pack{semtex} is a small package whose sole purpose
is to be loaded by stripped \semantex documents.
-It contains a couple of simple commands that the document
-needs immediately after the stripping.
-Depending on your document,
-you should be able to completely replace these commands
-by commands from other packages, or define them yourself, rendering the package~\pack{semtex}
-unnecessary.
-And actually, four of those commands are the commands
+All it does is define the four commands
\lstinline!\SemantexLeft!, \lstinline!\SemantexRight!,
\lstinline!\SemantexBullet!, and~\lstinline!\SemantexDoubleBullet!
-which are provided right below, making it even faster to just remove~\pack{semtex}.
+so that you can remove these definitions from your document and just rely on the package instead.
-In total, the package~\pack{semtex} adds the following commands:
+Let us take a look at the commands defined by \pack{semtex}:
\begin{itemize}
\item
@@ -2929,74 +2935,8 @@ In total, the package~\pack{semtex} adds the following commands:
from the package~\pack{mleftright}, so it is safe to just load that package
and replace the above commands by \lstinline!\mleft...\mright! instead,
or use the redefinitions mentioned above.
-
- \item
- \mylst!\SemantexParentheses{$\values\<normal|auto|*|{\textit{other}}\>$}{$\<left parenthesis\>$}!\\
- \mbox{\qquad}\mylst!{$\<right parenthesis\>$}{$\<content\>$}!,
-
- This one writes \<content\> enclosed in the pair of parentheses
- and with the size given by the first argument.
- Here,~\lstinline!normal! means normal size
- parentheses,
- and
- \lstinline!auto! and~\lstinline!*!
- mean auto-scaled parentheses using the commands~\lstinline!\SemantexLeft...\SemantexRight!.
- If another value is received, that value
- is used for the parenthesis size,
- so the intended values are~\lstinline!\big!, \lstinline!\Big!,
- \lstinline!\bigg!,~\lstinline!\Bigg!.
- The important property of this command is that
- inside the~\<content\>, you can access the delimiter size
- at any point using the command~\lstinline!\SemantexDelimiterSize!. In other words, when
- no~\lstinline!\SemantexDelimiterSize! is found inside the~\<content\>,
- the command is completely redundant. We shall see
- in a moment how to make sure it does not appear in your output
- unless absolutely necessary.
-
- \item
- \mylst!\SemantexNoParentheses{$\<content\>$}!
-
- This command prints the content with no parentheses, but importantly, it also resets
- the command \lstinline!\SemantexDelimiterSize!
- to~\lstinline!{}!, i.e.~blank.
- As with the command~\lstinline!\SemantexParentheses!,
- we shall see in a moment how to make this
- command not appear in your output
- unless absolutely necessary.
\end{itemize}
-As you see, most of these commands can be removed completely
-or replaced by commands from other packages. The one
-issue is with the annoying
-commands \lstinline!\SemantexParentheses!
-and~\lstinline!\SemantexNoParentheses!.
-These exist solely for the purpose of allowing the use of
-the command~\lstinline!\SemantexDelimiterSize! in the content.
-However, there are very few cases, such as set constructions, where
-\lstinline!\SemantexDelimiterSize! is even necessary. Therefore,
-\textbf{it is possible to turns the use of these commands off}.
-More precisely, there is a key that can be
-activated for any object or class:
-\begin{center}
- \mylst!allowSemantexDelimiterSize=$\values\<\default{true}|false\>$!
-\end{center}
-When this is set to false, \semantex will not use the
-commands~\lstinline!\SemantexParentheses!
-and~\lstinline!\SemantexNoParentheses! internally,
-and consequently, \lstinline!\SemantexDelimiterSize! will not work in that class or object.
-Instead, it will simply print the parentheses as raw code,
-and this is what will appear in your stripped document instead.
-The natural thing to do is to turn it off by default and
-only turn it back on for the few cases where you really need it:
-
-\begin{lstlisting}
-\SetupClass\MyVar{allowSemantexDelimiterSize=false}
-
-% We turn it back on for the set constructions
-% as defined above.
-\SetupObject\Set{allowSemantexDelimiterSize=true}
-\end{lstlisting}
-
\section{The \texttt{stripsemantex} algorithm}
The stripping algorithm works like this.
@@ -3009,18 +2949,12 @@ Suppose in the following that you \TeX\ document is called~\texttt{mydoc.tex}.
\item Make sure to collect all of the \semantex markup you want
stripped in the main document,~\texttt{mydoc.tex}.
Also make sure to follow the recommendations
- in \cref{sec:UseClassInCommand}, in case you have created keys
+ in \cref{sec:UseClassInCommand}, in case you have created commands
of the form described there.
- \item Set~\lstinline!allowSemantexDelimiterSize=false!
- for your main class~\lstinline!\MyVar!, and only
- turn it back on in the few cases where you need it,
- i.e.~when you need to use the command~\lstinline!\SemantexDelimiterSize!.
\item Put the following somewhere in your preamble, after
the loading of \semantex:
\begin{lstlisting}
-\SemantexSetup{
- semtexfile=true,
-}
+\SemantexSetup{semtexfile=true}
\end{lstlisting}
\item Compile your document \texttt{mydoc.tex} using your preferred \TeX\ engine (\hologo{pdfTeX}, \hologo{XeTeX}, \hologo{LuaTeX}, or whatever).
Because of the previous step, there
@@ -3039,58 +2973,59 @@ Suppose in the following that you \TeX\ document is called~\texttt{mydoc.tex}.
\begin{document}
-\StripSemantexCopyFile{mydoc}
-
-%\StripSemantexStripFile{mydoc}
+\StripSemantex{mydoc}
\end{document}
\end{lstlisting}
Then compile it \textbf{with \hologo{LuaTeX}}.
- \item After the previous step, another document will have been created in the same
+
+ After this step, another document will have been created in the same
folder, called~\lstinline!mydoc_prestripped.tex!. It will look just like \texttt{mydoc.tex},
but in the document body, each \semantex markup command will now
have a command \mylst!\SemantexIDcommand{$\<a unique ID\>$}!
- preceding it. Compile this new document \lstinline!mydoc_prestripped.tex! using the same \TeX\ engine as the one you used
+ preceding it.
+
+ \item\label{pt:pre_strip_point}
+ Compile the document \lstinline!mydoc_prestripped.tex! using the same \TeX\ engine as the one you used
for \texttt{mydoc.tex}.
- \item\label{pt:strip_point} Edit~\texttt{stripdoc.tex}, commenting out the line~\lstinline!\StripSemantexCopyFile{mydoc}!, and
- uncommentng the next one, so that the file now looks like this:
- \begin{lstlisting}
+ \item\label{pt:strip_point}
+ Compile the document~\lstinline!stripdoc.tex! again, this time also \textbf{using \hologo{LuaTeX}}.
+
+ \item After the previous step, some (but usually not all) \semantex markup will have been
+ removed from the file~\lstinline!mydoc_prestripped.tex!.
+ If the stripping algorithm has terminated (which it almost never does after a single run), there will now be a new document in your folder,
+ called~\lstinline!mydoc_stripped.tex!.
+ If this document is not there, repeat the steps \ref{pt:pre_strip_point} and~\ref{pt:strip_point}.
+
+ Continue this way until the file \lstinline!mydoc_stripped.tex! appears. It can easily require three or more iterations, but each iteration will usually be faster than the previous one, and eventually, the file~\lstinline!mydoc_stripped.tex! will appear.
+ (Note that at the point~\ref{pt:strip_point}, \pack{stripsemantex} will also issue a warning if the algorithm has not yet terminated, asking you to repeat the steps \ref{pt:pre_strip_point} and~\ref{pt:strip_point}).
+
+ Note again that your \semantex \textbf{setup}
+ will not be removed, so there
+ will still be commands like \lstinline!\NewObject!,
+ \lstinline!\SetupObject!, \lstinline!\SetupClass!,~etc.
+ left. You will then have to remove these few commands from your document manually.
+\end{enumerate}
+
+Apart from the machinery for stripping \semantex markup from documents,
+the package \pack{stripsemantex} also provides the command~\lstinline!\StripSemantexStripComments!,
+which is in principle completely unrelated to \semantex itself.
+This command allows you to strip all comments between \lstinline!\begin{document}! and~\lstinline!\end{document}!.
+If your document is again called~\lstinline!mydoc.tex!,
+you can create the following document and compile it \textbf{with \hologo{LuaTeX}}:
+\begin{lstlisting}
\documentclass{article}
\usepackage{stripsemantex}
\begin{document}
-%\StripSemantexCopyFile{mydoc}
-
-\StripSemantexStripFile{mydoc}
+\StripSemantexStripComments{mydoc}
\end{document}
- \end{lstlisting}
- Then compile this document again, this time also \textbf{using \hologo{LuaTeX}}.
- This will create a document called \lstinline!mydoc_stripped.tex!, which should (hopefully)
- be completely stripped of \semantex markup in the document body.
- Occasionally, as mentioned above, a few such commands may remain, in which case you will simply
- have to repeat the above steps, this time with the document~\texttt{mydoc.tex}
- replaced by~\lstinline!mydoc_stripped.tex!.
- Note again that your \semantex \textbf{setup}
- will not be removed, so there
- will still be commands like \lstinline!\NewObject!,
- \lstinline!\SetupObject!, \lstinline!\SetupClass!,~etc.
- left. You will then have to remove these few commands from your document manually.
-\end{enumerate}
-
-There is also another command in the \pack{stripsemantex} package,
-called simply \mylst!\StripSemantex!, which will
-run either the command \mylst!\StripSemantexCopyFile! or the command \mylst!\StripSemantexStripFile!,
-depending on which of the files \lstinline!mydoc.semtex!
-and~\mylst!mydoc_prestripped.semtex! is newer.
-This will allow you to not have to edit
-the file \texttt{stripdoc.tex}
-at point~\ref{pt:strip_point}.
-Unfortunately, due to a bug in \LaTeX3,
-this command does not work right now (in~\hologo{LuaTeX}). This bug has been reported
-and has hopefully already been fixed by the time you read this.
+\end{lstlisting}
+This will create a new document, called \lstinline!mydoc_comments_stripped.tex!, where all comments
+in the document body have been removed.
\chapter{Known bugs}
@@ -3503,19 +3438,6 @@ In the following sections, we include the full list.
The intended values are \lstinline!\mathord!, \lstinline!\mathop!, \lstinline!\mathbin!, \lstinline!\mathrel!, \lstinline!\mathopen!, \lstinline!\mathclose!, and~\lstinline!\mathpunct!.
\item
- \mylst!allowSemantexDelimiterSize={$\values\<\default{true}|false\>$}!
-
- Sets whether to allow the command \lstinline!\SemantexDelimiterSize!
- inside the argument.
- The default is~\lstinline!true!.
- The only real reason to turn this off is if you are using
- \lstinline!stripsemantex! to strip the document of \semantex markup.
- For if it is set to false, the system will not
- add \lstinline!\SemantexParentheses! and \lstinline!\SemantexNoParentheses!
- all over the place to set the value of \lstinline!\SemantexDelimiterSize!,
- and this probably looks better in the outputted code.
-
- \item
\mylst!default={$\<value\>$}!
This is the key that is applied whenever the
@@ -5872,19 +5794,6 @@ the programming keys and commands:
(boolean):
If true, the next lower upper index will have a separator printed in front of it.
\item
- \mylst!allowSemantexDelimiterSize!
- (boolean):
- if true, the argument will
- allow the command \lstinline!\SemantexDelimiterSize!
- inside the argument;
- the default is~\lstinline!true!.
- The only real reason to turn this off is if you are using
- \lstinline!stripsemantex! to strip the document of \semantex markup.
- For if it is set to false, the system will not
- add \lstinline!\SemantexParentheses! and \lstinline!\SemantexNoParentheses!
- all over the place to set the value of \lstinline!\SemantexDelimiterSize!,
- and this probably looks better in the outputted code.
- \item
\mylst!numberofarguments!
(integer):
the number of arguments.
diff --git a/macros/latex/contrib/semantex/stripsemantex.lua b/macros/latex/contrib/semantex/stripsemantex.lua
index 1ebce1f716..0ecb5e6240 100644
--- a/macros/latex/contrib/semantex/stripsemantex.lua
+++ b/macros/latex/contrib/semantex/stripsemantex.lua
@@ -64,6 +64,11 @@ addIDsToRegisters = function(str)
end
removeSuperfluousIDs = function()
+ local p = content:find('([^\\]%%[^\n]-)\\SemantexIDcommand{}([^\n]-\n)')
+ while p do
+ content = content:gsub('([^\\]%%[^\n]-)\\SemantexIDcommand{}([^\n]-\n)','%1%2')
+ p = content:find('([^\\]%%[^\n]-)\\SemantexIDcommand{}([^\n]-\n)')
+ end
content = content:gsub('parent(%s*)=(%s*)\\SemantexIDcommand{}','parent%1=%2')
content = content:gsub('class(%s*)=(%s*)\\SemantexIDcommand{}','class%1=%2')
content = content:gsub('clone(%s*)=(%s*)\\SemantexIDcommand{}','clone%1=%2')
@@ -75,12 +80,12 @@ removeSuperfluousIDs = function()
end
addNumbersToIDs = function()
- local n = 1
+ local n = 0
local p,q = string.find(content,'\\SemantexIDcommand{}')
while q do
+ n = n + 1
content = content:sub(1,q-1) .. n .. content:sub(q,-1)
p, q = string.find(content,'\\SemantexIDcommand{}')
- n = n + 1
end
end
@@ -154,7 +159,7 @@ semantexIDluacommand = function(id, source, output)
netto = netto + 1
elseif e == '\\' then
q = q + 1
- -- there is no chance that the source contains a %, so we do not
+ -- there is no chance that the source contains an unescaped %, so we do not
-- check for this
end
end
@@ -187,14 +192,18 @@ semantexIDluacommand = function(id, source, output)
output = output:gsub('\\mathclose \\}', '\\}')
output = output:gsub('\\mathopen \\lbrace', '\\lbrace')
output = output:gsub('\\mathclose \\rbrace', '\\rbrace')
- output = output:gsub('\\mathopen \\lbrack', '\\rbrack')
+ output = output:gsub('\\mathopen \\lbrack', '\\lbrack')
output = output:gsub('\\mathclose \\rbrack', '\\rbrack')
output = output:gsub('\\mathopen \\langle', '\\langle')
output = output:gsub('\\mathclose \\rangle', '\\rangle')
- output = output:gsub('\\mathopen \\lvert', '\\rvert')
+ output = output:gsub('\\mathopen \\lvert', '\\lvert')
output = output:gsub('\\mathclose \\rvert', '\\rvert')
- output = output:gsub('\\mathopen \\lVert', '\\rVert')
+ output = output:gsub('\\mathopen \\vert', '\\lvert')
+ output = output:gsub('\\mathclose \\vert', '\\rvert')
+ output = output:gsub('\\mathopen \\lVert', '\\lVert')
output = output:gsub('\\mathclose \\rVert', '\\rVert')
+ output = output:gsub('\\mathopen \\Vert', '\\lVert')
+ output = output:gsub('\\mathclose \\Vert', '\\rVert')
output = output:gsub('%^{\\prime }', '\'')
output = output:gsub('%^{\\prime \\prime }', '\'\'')
output = output:gsub('%^{\\prime \\prime \\prime }', '\'\'\'')
@@ -227,8 +236,56 @@ stripRemainingSemantexIDs = function()
content = content:gsub('\\SemantexIDcommand{%d+}', '')
end
+removeParenthesisCommands = function()
+ content = content:gsub('\\SemantexMathOpen \\bigg%s?', '\\biggl')
+ content = content:gsub('\\SemantexMathClose \\bigg%s?', '\\biggr')
+ content = content:gsub('\\SemantexMathOpen \\Bigg%s?', '\\Biggl')
+ content = content:gsub('\\SemantexMathClose \\Bigg%s?', '\\Biggr')
+ content = content:gsub('\\SemantexMathOpen \\big%s?', '\\bigl')
+ content = content:gsub('\\SemantexMathClose \\big%s?', '\\bigr')
+ content = content:gsub('\\SemantexMathOpen \\Big%s?', '\\Bigl')
+ content = content:gsub('\\SemantexMathClose \\Big%s?', '\\Bigr')
+ content = content:gsub('\\SemantexMathOpen{} %(', '(')
+ content = content:gsub('%s*\\SemantexMathClose{}%)', ')')
+ content = content:gsub('\\SemantexMathOpen{} %[', '[')
+ content = content:gsub('%s*\\SemantexMathClose{}%]', ']')
+ content = content:gsub('\\SemantexMathOpen{} \\{', '\\{')
+ content = content:gsub('%s*\\SemantexMathClose{} \\}', '\\}')
+ content = content:gsub('\\SemantexMathOpen{} \\lbrace', '\\lbrace')
+ content = content:gsub('\\SemantexMathClose{} \\rbrace', '\\rbrace')
+ content = content:gsub('\\SemantexMathOpen{} \\lbrack', '\\rbrack')
+ content = content:gsub('\\SemantexMathClose{} \\rbrack', '\\rbrack')
+ content = content:gsub('\\SemantexMathOpen{} \\langle', '\\langle')
+ content = content:gsub('\\SemantexMathClose{} \\rangle', '\\rangle')
+ content = content:gsub('\\SemantexMathOpen{} \\lvert', '\\lvert')
+ content = content:gsub('\\SemantexMathClose{} \\rvert', '\\rvert')
+ content = content:gsub('\\SemantexMathOpen{} \\vert', '\\lvert')
+ content = content:gsub('\\SemantexMathClose{} \\vert', '\\rvert')
+ content = content:gsub('\\SemantexMathOpen{} \\lVert', '\\lVert')
+ content = content:gsub('\\SemantexMathClose{} \\rVert', '\\rVert')
+ content = content:gsub('\\SemantexMathOpen{} \\Vert', '\\lVert')
+ content = content:gsub('\\SemantexMathClose{} \\Vert', '\\rVert')
+ content = content:gsub('\\SemantexMathOpen{} .%s?', '')
+ content = content:gsub('\\SemantexMathClose{} .%s?', '')
+ content = content:gsub('\\SemantexMathOpen{}', '\\mathopen ')
+ content = content:gsub('\\SemantexMathClose{}', '\\mathclose ')
+ content = content:gsub('\\SemantexMathOpenAuto%s?', '\\SemantexLeft')
+ content = content:gsub('\\SemantexMathCloseAuto%s?', '\\SemantexRight')
+ content = content:gsub('\\SemantexMathOpenNoPar%s?', '')
+ content = content:gsub('\\SemantexMathCloseNoPar%s?', '')
+ content = content:gsub('\\SemantexMathOpen%s?', '\\mathopen')
+ content = content:gsub('\\SemantexMathClose%s?', '\\mathclose')
+end
+
+stripComments = function()
+ content = content:gsub('\\%%', '\\StripSemantexEscapedPercent')
+ content = content:gsub('(\\%w+)%%.-\n%s*', '%1 ')
+ content = content:gsub('%%.-\n%s*', '')
+ content = content:gsub('\\StripSemantexEscapedPercent', '\\%%')
+end
+
addSemtexPackageToFile = function()
- content = [[% The following was added by "stripsemantex"
+ content = [[% The following was added by "stripsemantex":
\usepackage{semtex,leftindex,graphicx}
diff --git a/macros/latex/contrib/semantex/stripsemantex.sty b/macros/latex/contrib/semantex/stripsemantex.sty
index 2599c108c2..419a4dd75a 100644
--- a/macros/latex/contrib/semantex/stripsemantex.sty
+++ b/macros/latex/contrib/semantex/stripsemantex.sty
@@ -1,5 +1,5 @@
\RequirePackage{xparse}
-\ProvidesExplPackage{stripsemantex}{2020/09/13}{0.43}{}
+\ProvidesExplPackage{stripsemantex}{2020/09/27}{0.44}{}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
@@ -18,6 +18,8 @@
\msg_new:nnn { stripsemantex } { begin_document_not_found } { No~\token_to_str:N\begin{document}~found~in~the~file~#1;~it~has~to~be~in~the~main~document. }
+\msg_new:nnn { stripsemantex } { rerun_stripsemantex } { Some~SemanTeX~commands~are~still~remaining~in~your~document;~please~(re)run~TeX~on~the~file~#1_prestripped.tex,~and~then~rerun~LuaTeX~on~the~file~\jobname.tex. }
+
\sys_if_engine_luatex:F { \msg_fatal:nn { stripsemantex } { not_luatex } }
\lua_now:n { require('stripsemantex.lua') }
@@ -31,6 +33,10 @@
\lua_now:e {
copy_file('\lua_escape:e{#1}.tex', '\lua_escape:e{#1}_prestripped.tex')
+ }
+
+ \lua_now:e
+ {
openFile('\lua_escape:e{#1}_prestripped.tex')
}
@@ -53,9 +59,13 @@
addNumbersToIDs()
closeFile('\lua_escape:e{#1}_prestripped.tex')
}
+
+ \msg_warning:nnn { stripsemantex } { rerun_stripsemantex } { #1 }
}
-\cs_new_protected:Npn\stripsemantex_create_stripped_file:n#1
+\bool_new:N\g_stripsemantex_something_left_to_strip_bool
+
+\cs_new_protected:Npn\stripsemantex_strip_file:n#1
{
\file_if_exist:nF { #1_prestripped.semtex }
{
@@ -63,8 +73,7 @@
}
\lua_now:e {
- copy_file('\lua_escape:e{#1}_prestripped.tex', '\lua_escape:e{#1}_stripped.tex')
- openFile('\lua_escape:e{#1}_stripped.tex')
+ openFile('\lua_escape:e{#1}_prestripped.tex')
}
\DeclareDocumentCommand\SemantexID{ m t{\BeginSource} }
@@ -78,6 +87,7 @@
\cs_set:Npn\strip_semantex_id_command:w##1\BeginSource##2\EndSource\BeginOutput##3\EndOutput
{
+ \bool_set_true:N \g_stripsemantex_something_left_to_strip_bool
\lua_now:e
{
semantexIDluacommand( '\lua_escape:e{\tl_trim_spaces:n{##1}}' , '\lua_escape:e{\exp_not:n{##2}}' , '\lua_escape:e{\exp_not:n{##3}}' )
@@ -95,30 +105,69 @@
\lua_now:e
{
stripRemainingSemantexIDs()
- addSemtexPackageToFile()
- closeFile('\lua_escape:e{#1}_stripped.tex')
+ }
+
+ \bool_if:NTF \g_stripsemantex_something_left_to_strip_bool
+ {
+ \cs_set:Npn\DeclareObject##1
+ {
+ \lua_now:e { addIDsToRegisters ( '\cs_to_str:N ##1' ) }
+ }
+
+ \cs_set:Npn\DeclareClass##1
+ {
+ \lua_now:e { addIDsToRegisters ( '\cs_to_str:N ##1' ) }
+ }
+
+ \cs_set:Npn\SemantexID##1 {}
+
+ \cs_set:Npn\BeginSource##1\EndSource\BeginOutput##2\EndOutput {}
+
+ \file_input:n { #1.semtex }
+
+ \lua_now:e
+ {
+ removeSuperfluousIDs()
+ addNumbersToIDs()
+ closeFile('\lua_escape:e{#1}_prestripped.tex')
+ }
+
+ \msg_warning:nnn { stripsemantex } { rerun_stripsemantex } { #1 }
+ }
+ {
+ \lua_now:e
+ {
+ removeParenthesisCommands()
+ addSemtexPackageToFile()
+ closeFile('\lua_escape:e{#1}_prestripped.tex')
+ copy_file('\lua_escape:e{#1}_prestripped.tex', '\lua_escape:e{#1}_stripped.tex')
+ }
}
}
-\cs_set_eq:NN\StripSemantexCopyFile\stripsemantex_create_prestripped_file:n
-
-\cs_new_protected:Npn\StripSemantexStripFile#1
-{
- \begingroup
- \ExplSyntaxOn
- \stripsemantex_create_stripped_file:n { #1 }
-% \ExplSyntaxOff
- \endgroup
-}
\cs_new_protected:Npn\StripSemantex#1
{
- % This will only work after a bug has been corrected in expl3
+ \group_begin:
+ \ExplSyntaxOn % this will prevent the inserting of the annoying extra spaces
+ % from the .semtex file into the document.
\file_compare_timestamp:nNnTF { #1.semtex } < { #1_prestripped.semtex }
{
- \StripSemantexStripFile { #1 }
+ \stripsemantex_strip_file:n { #1 }
+ }
+ {
+ \stripsemantex_create_prestripped_file:n { #1 }
}
+ \group_end:
+}
+
+\cs_new_protected:Npn\StripSemantexStripComments#1
+{
+ \lua_now:e
{
- \StripSemantexCopyFile { #1 }
+ copy_file('\lua_escape:e{#1}.tex', '\lua_escape:e{#1}_comments_stripped.tex')
+ openFile('\lua_escape:e{#1}_comments_stripped.tex')
+ stripComments()
+ closeFile('\lua_escape:e{#1}_comments_stripped.tex')
}
} \ No newline at end of file