diff options
author | Karl Berry <karl@freefriends.org> | 2019-07-21 20:50:55 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2019-07-21 20:50:55 +0000 |
commit | aad5d81ab8c0e290b133dca9e566845bf37c09e3 (patch) | |
tree | 29cd7d69fb677e55a6238a621d384ccf9e10515e /Master/texmf-dist/tex/latex | |
parent | d2cedbb9100be2efe2cf00e209c623a190e0551a (diff) |
derivative (21jul19)
git-svn-id: svn://tug.org/texlive/trunk@51696 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex')
-rw-r--r-- | Master/texmf-dist/tex/latex/derivative/derivative.sty | 1337 |
1 files changed, 1337 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/latex/derivative/derivative.sty b/Master/texmf-dist/tex/latex/derivative/derivative.sty new file mode 100644 index 00000000000..00341140977 --- /dev/null +++ b/Master/texmf-dist/tex/latex/derivative/derivative.sty @@ -0,0 +1,1337 @@ +% derivative.sty +% Copyright 2019 Simon Jensen +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) 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 +% version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Simon Jensen. + +\NeedsTeXFormat{LaTeX2e} + +\RequirePackage{xparse}[2018/05/09] +\ProvidesExplPackage{derivative}{2019/07/21}{0.9}{Nice and easy derivatives} + +%%%%% Useful conditionals %%%%% + +\prg_new_conditional:Npnn \__if_novalue_blank:n #1 { T , F , TF } +{ + \tl_if_novalue:nTF {#1} + { \prg_return_true: } + { + \tl_if_blank:nTF {#1} + { \prg_return_true: } + { \prg_return_false: } + } +} + +\prg_new_conditional:Npnn \__if_novalue_blank_or:nn #1 #2 { F, TF } +{ + \__if_novalue_blank:nTF {#1} + { + \__if_novalue_blank:nTF {#2} + { \prg_return_true: } + { \prg_return_false: } + } + { \prg_return_false: } +} + +\prg_new_conditional:Npnn \__show_order:N #1 { T, TF } +{ + \quark_if_no_value:NTF #1 + { \prg_return_false: } + { + \str_if_eq:NNTF #1 1 + { \prg_return_false: } + { + \exp_args:NV \tl_if_novalue:nTF #1 + { \prg_return_false: } + { + \tl_if_blank:VTF #1 + { \prg_return_false: } + { \prg_return_true: } + } + } + } +} + +\cs_new:Npn \__deriv_case:n #1 +{ \exp:w \__deriv_case_begin:nTF {#1} { } { } } + +\cs_new:Npn \__deriv_case:nT #1#2 +{ \exp:w \__deriv_case_begin:nTF {#1} {#2} { } } + +\cs_new:Npn \__deriv_case:nF #1#2 +{ \exp:w \__deriv_case_begin:nTF {#1} { } {#2} } + +\cs_new:Npn \__deriv_case:nTF #1 +{ \exp:w \__deriv_case_begin:nTF {#1} } + +\cs_new:Npn \__deriv_case_begin:nTF #1#2#3 +{ \__deriv_case:w #1 \c_true_bool { } \q_mark {#2} \q_mark {#3} \q_stop } + +\cs_new:Npn \__deriv_case:w #1#2 +{ + \bool_if:nTF {#1} + { \__deriv_case_end:nw {#2} } + { \__deriv_case:w } +} + +\cs_new:Npn \__deriv_case_end:nw #1#2#3 \q_mark #4#5 \q_stop +{ \exp_end: #1 #4 } + +%%%%% slash frac %%%%% + +\DeclareDocumentCommand{\slashfrac}{ o m m } +{ + \tl_if_novalue:nTF {#1} + { \__deriv_slashfrac_auto:nn {#2} {#3} } + { + \str_case:nnF {#1} + { + { auto } { \__deriv_slashfrac_auto:nn {#2} {#3} } + { none } { \__deriv_slashfrac_none:nn {#2} {#3} } + } + { \__deriv_slashfrac_scale:nnn {#1} {#2} {#3} } + } +} +% numerator , denominator +\cs_new_protected:Npn \__deriv_slashfrac_auto:nn #1 #2 +{ + \__deriv_auto_left:n . \kern-\nulldelimiterspace + {#1} \middle/ {#2} + \__deriv_auto_right:n . \kern-\nulldelimiterspace +} +% numerator , denominator +\cs_new_protected:Npn \__deriv_slashfrac_none:nn #1 #2 +{ + {#1} / {#2} +} +% scale , numerator , denominator +\cs_new_protected:Npn \__deriv_slashfrac_scale:nnn #1 #2 #3 +{ + \cs:w #1 l \cs_end: . + {#2} + \cs:w #1 \cs_end: / + {#3} + \cs:w #1 r \cs_end: . +} + +%%%%% Variables for settings of odv, pdv and variants %%%%% + +\cs_new_protected:Npn \__deriv_auto_left:n #1 { \left #1 } +\cs_new_protected:Npn \__deriv_auto_right:n #1 { \right #1 } + +\tl_new:N \l__deriv_dv_tmp_tl +\tl_new:N \l__deriv_derivset_tl + +\seq_new:N \l__deriv_var_seq +\seq_new:N \l__deriv_rubber_seq + +%%%%% Variables for odv %%%%% + +\seq_new:N \l__deriv_d_variant_seq + +\tl_new:N \l__deriv_d_order_tl + +%%%%% Variables for pdv and mixed order (mo) %%%%% + +\seq_new:N \l__deriv_p_variant_seq + +\tl_new:N \l__deriv_p_tmpa_tl +\tl_new:N \l__deriv_p_mo_tl +\tl_new:N \l__deriv_p_denom_tl + +\seq_new:N \l__deriv_p_var_seq +\seq_new:N \l__deriv_p_order_seq +\seq_new:N \l__deriv_p_mo_seq + +\int_new:N \l__deriv_vmo_int + +\tl_new:N \l__deriv_sym_tmpa_tl +\tl_new:N \l__deriv_num_tmpa_tl +\tl_new:N \l__deriv_sym_tmpb_tl +\tl_new:N \l__deriv_num_tmpb_tl +\tl_new:N \l__deriv_input_tl + +\seq_new:N \l__deriv_input_seq +\seq_new:N \l__deriv_extract_seq +\seq_new:N \l__deriv_unsorted_seq +\seq_new:N \l__deriv_sorted_seq + +\seq_new:N \l__deriv_symbol_seq +\seq_new:N \l__deriv_number_seq +\seq_new:N \l__deriv_rebuild_seq + +\int_new:N \l__deriv_tmpa_int + +\int_new:N \l__deriv_numerical_int +\int_new:N \l__deriv_sort_counter_int +\int_new:N \l__deriv_sort_max_int + +\int_new:N \l__deriv_position_int +\int_new:N \l__deriv_rebuild_int + +\regex_const:Nn \c__deriv_pattern_regex { \A([\+\-]?\d*)(.*) } + +%%%%%% Key-val for all %%%%%% + +\keys_define:nn { deriv-all-settings } +{ + scale-auto .choice:, + scale-auto / leftright .code:n = + { + \cs_set_eq:NN \__deriv_auto_left:n \left + \cs_set_eq:NN \__deriv_auto_right:n \right + }, + scale-auto / mleftmright .code:n = + { + \cs_set_eq:NN \__deriv_auto_left:n \mleft + \cs_set_eq:NN \__deriv_auto_right:n \mright + }, + scale-auto .default:n = { leftright } +} + +%%%%% Key-val for odv and variants %%%%% +\cs_new:Npn \__deriv_d_define_keys:n #1 +{ + \keys_define:nn { deriv-d-#1 } + { + style-inf .code:n = { \cs_set_eq:cN { __deriv_#1_style_inf:n } ##1 }, + + style-frac .code:n = { \cs_set_eq:cN { __deriv_#1_style_frac:n } ##1 }, + style-frac .default:n = { \frac }, + + style-frac-/ .code:n = { \cs_set_eq:cN { __deriv_#1_style_frac_slash:n } ##1 }, + style-frac-/ .default:n = { \slashfrac }, + + scale-eval .choices:nn = + { auto, none, big, Big, bigg, Bigg } + { \tl_set_eq:cN { l__deriv_#1_scale_eval_tl } \l_keys_choice_tl }, + + scale-eval .default:n = { auto }, + + scale-eval-/ .choices:nn = + { auto, none, big, Big, bigg, Bigg } + { \tl_set_eq:cN { l__deriv_#1_scale_eval_slash_tl } \l_keys_choice_tl }, + scale-eval-/ .default:n = { auto }, + + scale-fun .choices:nn = + { auto, none, big, Big, bigg, Bigg } + { \tl_set_eq:cN { l__deriv_#1_scale_fun_tl } \l_keys_choice_tl }, + scale-fun .default:n = { auto }, + + scale-var .choices:nn = + { auto, none, big, Big, bigg, Bigg } + { \tl_set_eq:cN { l__deriv_#1_scale_var_tl } \l_keys_choice_tl }, + scale-var .default:n = { auto }, + + scale-frac .choices:nn = + { auto, none, big, Big, bigg, Bigg } + { \tl_set_eq:cN { l__deriv_#1_scale_frac_tl } \l_keys_choice_tl }, + scale-frac .default:n = { auto }, + + scale-frac-/ .choices:nn = + { auto, none, big, Big, bigg, Bigg } + { \tl_set_eq:cN { l__deriv_#1_scale_frac_slash_tl } \l_keys_choice_tl }, + scale-frac-/ .default:n = { auto }, + + delims-eval .code:n = { \tl_set:cn { l__deriv_#1_delims_eval_tl } { ##1 } }, + delims-eval .default:n = { .\rvert }, + delims-eval-/ .code:n = { \tl_set:cn { l__deriv_#1_delims_eval_slash_tl } { ##1 } }, + delims-eval-/ .default:n = { .\rvert }, + delims-fun .code:n = { \tl_set:cn { l__deriv_#1_delims_fun_tl } { ##1 } }, + delims-fun .default:n = { () }, + delims-var .code:n = { \tl_set:cn { l__deriv_#1_delims_var_tl } { ##1 } }, + delims-var .default:n = { () }, + delims-frac .code:n = { \tl_set:cn { l__deriv_#1_delims_frac_tl } { ##1 } }, + delims-frac .default:n = { () }, + delims-frac-/ .code:n = { \tl_set:cn { l__deriv_#1_delims_frac_slash_tl } { ##1 } }, + delims-frac-/ .default:n = { () }, + + sep-inf-ord .code:n = { \__deriv_set_rubber_length:cn { l__deriv_#1_sep_inf_ord_muskip } {##1} }, + sep-inf-ord .default:n = { 0 }, + sep-inf-fun .code:n = { \__deriv_set_rubber_length:cn { l__deriv_#1_sep_inf_fun_muskip } {##1} }, + sep-inf-fun .default:n = { 0 }, + sep-ord-fun .code:n = { \__deriv_set_rubber_length:cn { l__deriv_#1_sep_ord_fun_muskip } {##1} }, + sep-ord-fun .default:n = { 0 }, + sep-var-ord .code:n = { \__deriv_set_rubber_length:cn { l__deriv_#1_sep_var_ord_muskip } {##1} }, + sep-var-ord .default:n = { 0 }, + sep-inf-var .code:n = { \__deriv_set_rubber_length:cn { l__deriv_#1_sep_inf_var_muskip } {##1} }, + sep-inf-var .default:n = { 0 }, + sep-eval-sb .code:n = { \__deriv_set_rubber_length:cn { l__deriv_#1_sep_eval_sb_muskip } {##1} }, + sep-eval-sb .default:n = { 0 }, + sep-eval-sp .code:n = { \__deriv_set_rubber_length:cn { l__deriv_#1_sep_eval_sp_muskip } {##1} }, + sep-eval-sp .default:n = { 0 }, + + switch-* .bool_set:c = { l__deriv_#1_switch_star_bool }, + switch-* .default:n = { false }, + switch-/ .bool_set:c = { l__deriv_#1_switch_slash_bool }, + switch-/ .default:n = { false }, + + misc-add-delims .multichoices:nn = + { fun, var, frac } + { \bool_set_true:c { l__deriv_#1_mics_##1_bool } }, + + misc-remove-delims .multichoices:nn = + { fun, var, frac } + { \bool_set_false:c { l__deriv_#1_mics_##1_bool } }, + misc-remove-delims .default:n = { fun, var, frac } + } + \bool_lazy_or:nnT { \sys_if_engine_luatex_p: } { \sys_if_engine_xetex_p: } + { + \keys_define:nn { deriv-d-#1 } + { style-inf .default:n = { \symnormal } } + } + \sys_if_engine_pdftex:T + { + \keys_define:nn { deriv-d-#1 } + { style-inf .default:n = { \mathnormal } } + } +} +%%%%%% Key-val for pdv and variants %%%%%% +\cs_new:Npn \__deriv_p_define_keys:n #1 +{ + \keys_define:nn { deriv-p-#1 } + { + style-inf .code:n = { \cs_set_eq:cN { __deriv_#1_style_inf:n } ##1 }, + + style-frac .code:n = { \cs_set_eq:cN { __deriv_#1_style_frac:n } ##1 }, + style-frac .default:n = { \frac }, + + style-frac-/ .code:n = { \cs_set_eq:cN { __deriv_#1_style_frac_slash:n } ##1 }, + style-frac-/ .default:n = { \slashfrac }, + + scale-eval .choices:nn = + { auto, none, big, Big, bigg, Bigg } + { \tl_set_eq:cN { l__deriv_#1_scale_eval_tl } \l_keys_choice_tl }, + scale-eval .default:n = { auto }, + + scale-eval-/ .choices:nn = + { auto, none, big, Big, bigg, Bigg } + { \tl_set_eq:cN { l__deriv_#1_scale_eval_slash_tl } \l_keys_choice_tl }, + scale-eval-/ .default:n = { auto }, + + scale-fun .choices:nn = + { auto, none, big, Big, bigg, Bigg } + { \tl_set_eq:cN { l__deriv_#1_scale_fun_tl } \l_keys_choice_tl }, + scale-fun .default:n = { auto }, + + scale-var .choices:nn = + { auto, none, big, Big, bigg, Bigg } + { \tl_set_eq:cN { l__deriv_#1_scale_var_tl } \l_keys_choice_tl }, + scale-var .default:n = { auto }, + + scale-frac .choices:nn = + { auto, none, big, Big, bigg, Bigg } + { \tl_set_eq:cN { l__deriv_#1_scale_frac_tl } \l_keys_choice_tl }, + scale-frac .default:n = { auto }, + + scale-frac-/ .choices:nn = + { auto, none, big, Big, bigg, Bigg } + { \tl_set_eq:cN { l__deriv_#1_scale_frac_slash_tl } \l_keys_choice_tl }, + scale-frac-/ .default:n = { auto }, + + delims-eval .code:n = { \tl_set:cn { l__deriv_#1_delims_eval_tl } {##1} }, + delims-eval .default:n = { () }, + delims-eval-/ .code:n = { \tl_set:cn { l__deriv_#1_delims_eval_slash_tl } {##1} }, + delims-eval-/ .default:n = { () }, + delims-fun .code:n = { \tl_set:cn { l__deriv_#1_delims_fun_tl } {##1} }, + delims-fun .default:n = { () }, + delims-var .code:n = { \tl_set:cn { l__deriv_#1_delims_var_tl } {##1} }, + delims-var .default:n = { () }, + delims-frac .code:n = { \tl_set:cn { l__deriv_#1_delims_frac_tl } {##1} }, + delims-frac .default:n = { () }, + delims-frac-/ .code:n = { \tl_set:cn { l__deriv_#1_delims_frac_slash_tl } {##1} }, + delims-frac-/ .default:n = { () }, + + sep-inf-ord .code:n = { \__deriv_set_rubber_length:cn { l__deriv_#1_sep_inf_ord_muskip } {##1} }, + sep-inf-ord .default:n = { 0 }, + sep-inf-fun .code:n = { \__deriv_set_rubber_length:cn { l__deriv_#1_sep_inf_fun_muskip } {##1} }, + sep-inf-fun .default:n = { 0 }, + sep-ord-fun .code:n = { \__deriv_set_rubber_length:cn { l__deriv_#1_sep_ord_fun_muskip } {##1} }, + sep-ord-fun .default:n = { 0 }, + sep-inf-var .code:n = { \__deriv_set_rubber_length:cn { l__deriv_#1_sep_inf_ord_muskip } {##1} }, + sep-inf-var .default:n = { 0 }, + sep-var-ord .code:n = { \__deriv_set_rubber_length:cn { l__deriv_#1_sep_var_ord_muskip } {##1} }, + sep-var-ord .default:n = { 0 }, + sep-var-inf .code:n = { \__deriv_set_rubber_length:cn { l__deriv_#1_sep_var_inf_muskip } {##1} }, + sep-var-inf .default:n = { 3 }, + sep-ord-inf .code:n = { \__deriv_set_rubber_length:cn { l__deriv_#1_sep_ord_inf_muskip } {##1} }, + sep-ord-inf .default:n = { 3 }, + sep-eval-sb .code:n = { \__deriv_set_rubber_length:cn { l__deriv_#1_sep_eval_sb_muskip } {##1} }, + sep-eval-sb .default:n = { -4 }, + sep-eval-sp .code:n = { \__deriv_set_rubber_length:cn { l__deriv_#1_sep_eval_sp_muskip } {##1} }, + sep-eval-sp .default:n = { -4 }, + + switch-* .bool_set:c = { l__deriv_#1_switch_star_bool }, + switch-* .default:n = { false }, + switch-/ .bool_set:c = { l__deriv_#1_switch_slash_bool }, + switch-/ .default:n = { false }, + + misc-add-delims .multichoices:nn = + { fun, var, frac } + { \bool_set_true:c { l__deriv_#1_mics_##1_bool } }, + + misc-remove-delims .multichoices:nn = + { fun, var, frac } + { \bool_set_false:c { l__deriv_#1_mics_##1_bool } }, + misc-remove-delims .default:n = { fun, var, frac }, + + sort-method .clist_set:c = { l__deriv_#1_sort_method_clist }, % måske seq + sort-method .default:n = { abs, sign, symbol }, + + sort-numerical .choices:nn = + { auto, first, last } + { \tl_set_eq:cN { l__deriv_#1_sort_numerical_tl } \l_keys_choice_tl }, + sort-numerical .default:n = { auto }, + + sort-sign-reverse .bool_set:c = { l__deriv_#1_sort_sign_reverse_bool }, + sort-sign-reverse .default:n = { false }, + sort-symbol-reverse .bool_set:c = { l__deriv_#1_sort_symbol_reverse_bool }, + sort-symbol-reverse .default:n = { false }, + sort-abs-reverse .bool_set:c = { l__deriv_#1_sort_abs_reverse_bool }, + sort-abs-reverse .default:n = { false } + } + \bool_lazy_or:nnT { \sys_if_engine_luatex_p: } { \sys_if_engine_xetex_p: } + { + \keys_define:nn { deriv-p-#1 } + { style-inf .default:n = { \symnormal } } + } + \sys_if_engine_pdftex:T + { + \keys_define:nn { deriv-p-#1 } + { style-inf .default:n = { \mathnormal } } + } +} + +\DeclareDocumentCommand{\derivset}{ m o } +{ + \token_if_macro:NTF {#1} + { \tl_set:Nx \l__deriv_derivset_tl { \cs_to_str:N #1 } } + { \tl_set:Nx \l__deriv_derivset_tl { \tl_to_str:n {#1} } } + + \__deriv_derivset:Vn \l__deriv_derivset_tl {#2} +} + +\cs_new_protected:Npn \__deriv_derivset:nn #1 #2 +{ + \seq_if_in:NnTF \l__deriv_d_variant_seq {#1} + { \__deriv_d_set_keys:nn {#1} {#2} } + { + \seq_if_in:NnTF \l__deriv_p_variant_seq {#1} + { \__deriv_p_set_keys:nn {#1} {#2} } + { + \str_if_eq:nnTF {#1} { all } + { \__deriv_all_set_keys:n {#2} } + { + \msg_error:nnxx { deriv } { derivative-not-defined } + { \token_to_str:N #1 } + { \token_to_str:N \derivset } + } + } + } +} +% dv , key=val clist +\cs_new_protected:Npn \__deriv_d_set_keys:nn #1 #2 +{ + \tl_if_novalue:nTF {#2} + { + \keys_set:nn { deriv-d-#1 } + { + style-inf , style-frac , style-frac-/ , + scale-eval , scale-eval-/ , scale-fun , scale-var , scale-frac , scale-frac-/ , + delims-eval , delims-eval-/ , delims-fun , delims-var , delims-frac , delims-frac-/ , + sep-inf-ord , sep-inf-fun , sep-ord-fun , sep-var-ord , sep-inf-var , sep-eval-sb , sep-eval-sp , + switch-* , switch-/ , + misc-remove-delims + } + } + { \keys_set:nn { deriv-d-#1 } {#2} } +} +% key=val clist +\cs_new_protected:Npn \__deriv_p_set_keys:nn #1 #2 +{ + \tl_if_novalue:nTF {#2} + { + \keys_set:nn { deriv-p-#1 } + { + style-inf , style-frac , style-frac-/ , + scale-eval , scale-eval-/ , scale-fun , scale-var , scale-frac , scale-frac-/ , + delims-eval , delims-eval-/ , delims-fun , delims-var , delims-frac , delims-frac-/ , + sep-inf-ord , sep-inf-fun , sep-ord-fun , sep-inf-var , sep-var-ord , sep-var-inf , sep-ord-inf , sep-eval-sb , sep-eval-sp , + switch-* , switch-/ , + sort-method , sort-numerical , sort-sign-reverse , sort-symbol-reverse , sort-abs-reverse , + misc-remove-delims + } + } + { \keys_set:nn { deriv-p-#1 } {#2} } +} +% key=val clist +\cs_new_protected:Npn \__deriv_all_set_keys:n #1 +{ + \tl_if_novalue:nTF {#1} + { \keys_set:nn { deriv-all-settings } { scale-auto } } + { \keys_set:nn { deriv-all-settings } {#1} } +} + +%%%%% Declaring variants %%%%% + +\DeclareDocumentCommand{\NewOdvVariant}{ m m o } +{ + \cs_if_exist:NTF #1 + { + \msg_error:nnxx { deriv } { command-already-defined } + { \token_to_str:N #1 } + { \token_to_str:N \NewOdvVariant } + } + { + \deriv_d_preamble:Nnn \l__deriv_dv_tmp_tl {#1} {#3} + \deriv_d_define:Vnnn \l__deriv_dv_tmp_tl { New } {#1} {#2} + } +} + +\DeclareDocumentCommand{\RenewOdvVariant}{ m m o } +{ + \cs_if_exist:NTF #1 + { + \deriv_d_preamble:Nnn \l__deriv_dv_tmp_tl {#1} {#3} + \deriv_d_define:Vnnn \l__deriv_dv_tmp_tl { Renew } {#1} {#2} + } + { + \msg_error:nnxx { deriv } { command-not-defined } + { \token_to_str:N #1 } + { \token_to_str:N \RenewOdvVariant } + } +} + +\DeclareDocumentCommand{\ProvideOdvVariant}{ m m o } +{ + \cs_if_exist:NF #1 + { + \deriv_d_preamble:Nnn \l__deriv_dv_tmp_tl {#1} {#3} + \deriv_d_define:Vnnn \l__deriv_dv_tmp_tl { Provide } {#1} {#2} + } +} + +\DeclareDocumentCommand{\DeclareOdvVariant}{ m m o } +{ + \deriv_d_preamble:Nnn \l__deriv_dv_tmp_tl {#1} {#3} + \deriv_d_define:Vnnn \l__deriv_dv_tmp_tl { Declare } {#1} {#2} +} + +\cs_new_protected:Npn \deriv_d_preamble:Nnn #1 #2 #3 +{ + \tl_set:Nx #1 { \cs_to_str:N #2 } + \seq_if_in:NVF \l__deriv_d_variant_seq #1 + { + \seq_put_left:NV \l__deriv_d_variant_seq #1 + \__deriv_d_variables:V #1 + \__deriv_d_define_keys:V #1 + } + \__deriv_derivset:VV #1 \c_novalue_tl + \tl_if_novalue:nF {#3} { \__deriv_derivset:Vn #1 {#3} } +} + +\cs_new_protected:Npn \deriv_d_define:nnnn #1 #2 #3 #4 +{ + \use:c { #2 DocumentCommand }{#3}{ s o m t/ m !e{\sb^} } + { + \group_begin: + \exp_args:Nnc \bool_xor:nnTF {##4} { l__deriv_#1_switch_slash_bool } + { + \exp_args:Nnc \bool_xor:nnTF {##1} { l__deriv_#1_switch_star_bool } + { \__deriv_odv_both:Nnnnnnn #4 {#1} {##2} {##3} {##5} {##6} {##7} } + { \__deriv_odv_slash:Nnnnnnn #4 {#1} {##2} {##3} {##5} {##6} {##7} } + } + { + \exp_args:Nnc \bool_xor:nnTF {##1} { l__deriv_#1_switch_star_bool } + { \__deriv_odv_star:Nnnnnnn #4 {#1} {##2} {##3} {##5} {##6} {##7} } + { \__deriv_odv_none:Nnnnnnn #4 {#1} {##2} {##3} {##5} {##6} {##7} } + } + \group_end: + } +} + +\DeclareDocumentCommand{\NewPdvVariant}{ m m o } +{ + \cs_if_exist:NTF #1 + { + \msg_error:nnxx { deriv } { command-already-defined } + { \token_to_str:N #1 } + { \token_to_str:N \NewPdvVariant } + } + { + \deriv_p_preamble:Nnn \l__deriv_dv_tmp_tl {#1} {#3} + \deriv_p_define:Vnnn \l__deriv_dv_tmp_tl { New } {#1} {#2} + } +} + +\DeclareDocumentCommand{\RenewPdvVariant}{ m m o } +{ + \cs_if_exist:NTF #1 + { + \deriv_p_preamble:Nnn \l__deriv_dv_tmp_tl {#1} {#3} + \deriv_p_define:Vnnn \l__deriv_dv_tmp_tl { Renew } {#1} {#2} + } + { + \msg_error:nnxx { deriv } { command-already-defined } + { \token_to_str:N #1 } + { \token_to_str:N \RenewPdvVariant } + } +} + +\DeclareDocumentCommand{\ProvidePdvVariant}{ m m o } +{ + \cs_if_exist:NF #1 + { + \deriv_p_preamble:Nnn \l__deriv_dv_tmp_tl {#1} {#3} + \deriv_p_define:Vnnn \l__deriv_dv_tmp_tl { Provide } {#1} {#2} + } +} + +\DeclareDocumentCommand{\DeclarePdvVariant}{ m m o } +{ + \deriv_p_preamble:Nnn \l__deriv_dv_tmp_tl {#1} {#3} + \deriv_p_define:Vnnn \l__deriv_dv_tmp_tl { Declare } {#1} {#2} +} + +\cs_new_protected:Npn \deriv_p_preamble:Nnn #1 #2 #3 +{ + \tl_set:Nx #1 { \cs_to_str:N #2 } + \seq_if_in:NVF \l__deriv_p_variant_seq #1 + { + \seq_put_left:NV \l__deriv_p_variant_seq #1 + \__deriv_p_variables:V #1 + \__deriv_p_define_keys:V #1 + } + \__deriv_derivset:VV #1 \c_novalue_tl + \tl_if_novalue:nF {#3} { \__deriv_derivset:Vn #1 {#3} } +} + +\cs_new_protected:Npn \deriv_p_define:nnnn #1 #2 #3 #4 +{ + \use:c { #2 DocumentCommand }{#3}{ s o o m t/ m !e{\sb^} } + { + \group_begin: + \exp_args:Nnc \bool_xor:nnTF {##5} { l__deriv_#1_switch_slash_bool } + { + \exp_args:Nnc \bool_xor:nnTF {##1} { l__deriv_#1_switch_star_bool } + { \__deriv_pdv_both:Nnnnnnnn #4 {#1} {##2} {##3} {##4} {##6} {##7} {##8} } + { \__deriv_pdv_slash:Nnnnnnnn #4 {#1} {##2} {##3} {##4} {##6} {##7} {##8} } + } + { + \exp_args:Nnc \bool_xor:nnTF {##1} { l__deriv_#1_switch_star_bool } + { \__deriv_pdv_star:Nnnnnnnn #4 {#1} {##2} {##3} {##4} {##6} {##7} {##8} } + { \__deriv_pdv_none:Nnnnnnnn #4 {#1} {##2} {##3} {##4} {##6} {##7} {##8} } + } + \group_end: + } +} +% dv +\cs_new_protected:Npn \__deriv_d_variables:n #1 +{ + \__deriv_new:nnnn {#1} { scale } { tl } { eval, eval_slash, fun, var, frac, frac_slash } + \__deriv_new:nnnn {#1} { delims } { tl } { eval, eval_slash, fun, var, frac, frac_slash } + \__deriv_new:nnnn {#1} { sep } { muskip } { inf_ord, inf_fun, ord_fun, var_ord, inf_var, eval_sb, eval_sp } + \__deriv_new:nnnn {#1} { switch } { bool } { star, slash } + \__deriv_new:nnnn {#1} { mics } { bool } { fun, var, frac } +} +% dv +\cs_new_protected:Npn \__deriv_p_variables:n #1 +{ + \__deriv_new:nnnn {#1} { scale } { tl } { eval, eval_slash, fun, var, frac, frac_slash } + \__deriv_new:nnnn {#1} { delims } { tl } { eval, eval_slash, fun, var, frac, frac_slash } + \__deriv_new:nnnn {#1} { sep } { muskip } { inf_ord, inf_fun, ord_fun, inf_var, var_ord, var_inf, ord_inf, eval_sb, eval_sp } + \__deriv_new:nnnn {#1} { switch } { bool } { star, slash } + \__deriv_new:nnnn {#1} { sort } { clist } { method } + \__deriv_new:nnnn {#1} { sort } { tl } { numerical } + \__deriv_new:nnnn {#1} { sort } { bool } { sign_reverse, symbol_reverse, abs_reverse } + \__deriv_new:nnnn {#1} { mics } { bool } { fun, var, frac } +} +% dv , sub-category , data-type , cs-var-list +\cs_new:Npn \__deriv_new:nnnn #1 #2 #3 #4 +{ + \seq_set_from_clist:Nn \l__deriv_var_seq {#4} + \seq_map_inline:Nn \l__deriv_var_seq + { \cs:w #3_new:c \cs_end: { l__deriv_#1_#2_##1_#3 } } +} + +%%%%% Ordinary derivative definition %%%%% + +% inf , dv , order , function , variable , sb-point , sp-point +\cs_new_protected:Npn \__deriv_odv_both:Nnnnnnn #1 #2 #3 #4 #5 #6 #7 +{ + \__deriv_set_order:Nn \l__deriv_d_order_tl {#3} + \__deriv_evaluation_slash:nnnn {#2} {#6} {#7} + { + \__deriv_fraction_slash:nn {#2} + { + \use:c { __deriv_#2_style_frac_slash:n } + { \__deriv_d_numerator_nofun:Nn #1 {#2} } + { \__deriv_d_denominator:Nnn #1 {#2} {#5} } + } + + \__deriv_function:nn {#2} {#4} + } +} +% inf , dv , order , function , variable , sb-point , sp-point +\cs_new_protected:Npn \__deriv_odv_star:Nnnnnnn #1 #2 #3 #4 #5 #6 #7 +{ + \__deriv_set_order:Nn \l__deriv_d_order_tl {#3} + \__deriv_evaluation:nnnn {#2} {#6} {#7} + { + \__deriv_fraction:nn {#2} + { + \use:c { __deriv_#2_style_frac:n } + { \__deriv_d_numerator_nofun:Nn #1 {#2} } + { \__deriv_d_denominator:Nnn #1 {#2} {#5} } + } + \__deriv_function:nn {#2} {#4} + } +} +% inf , dv , order , function , variable , sb-point , sp-point +\cs_new_protected:Npn \__deriv_odv_slash:Nnnnnnn #1 #2 #3 #4 #5 #6 #7 +{ + \__deriv_set_order:Nn \l__deriv_d_order_tl {#3} + \__deriv_evaluation_slash:nnnn {#2} {#6} {#7} + { + \__deriv_fraction_slash:nn {#2} + { + \use:c { __deriv_#2_style_frac_slash:n } + { \__deriv_d_numerator_fun:Nnn #1 {#2} {#4} } + { \__deriv_d_denominator:Nnn #1 {#2} {#5} } + } + } +} +% inf , dv , order , function , variable , sb-point , sp-point +\cs_new_protected:Npn \__deriv_odv_none:Nnnnnnn #1 #2 #3 #4 #5 #6 #7 +{ + \__deriv_set_order:Nn \l__deriv_d_order_tl {#3} + \__deriv_evaluation:nnnn {#2} {#6} {#7} + { + \__deriv_fraction:nn {#2} + { + \use:c { __deriv_#2_style_frac:n } + { \__deriv_d_numerator_fun:Nnn #1 {#2} {#4} } + { \__deriv_d_denominator:Nnn #1 {#2} {#5} } + } + } +} +% inf , dv , function +\cs_new_protected:Npn \__deriv_d_numerator_fun:Nnn #1 #2 #3 +{ + \__deriv_insert_inf:Nn #1 {#2} + \__deriv_insert_ord:Nnn \l__deriv_d_order_tl {#2} { inf_ord } + \__deriv_insert_fun:Nnn \l__deriv_d_order_tl {#2} {#3} +} +% inf , dv +\cs_new_protected:Npn \__deriv_d_numerator_nofun:Nn #1 #2 +{ + \__deriv_insert_inf:Nn #1 {#2} + \__deriv_insert_ord:Nnn \l__deriv_d_order_tl {#2} { inf_ord } +} +% inf , dv , variable +\cs_new_protected:Npn \__deriv_d_denominator:Nnn #1 #2 #3 +{ + \__deriv_insert_inf:Nn #1 {#2} + \__deriv_insert_var_ord:Nnn \l__deriv_d_order_tl {#2} {#3} +} + +%%%%% Partial derivative definition %%%%% +% inf , dv , order , mixed order , function , variable , sb-point , sp-point +\cs_new_protected:Npn \__deriv_pdv_both:Nnnnnnnn #1 #2 #3 #4 #5 #6 #7 #8 +{ + \__deriv_preparation:NNNnnnn \l__deriv_p_mo_tl \l__deriv_p_denom_tl #1 {#2} {#3} {#4} {#6} + \__deriv_evaluation_slash:nnnn {#2} {#7} {#8} + { + \__deriv_fraction_slash:nn {#2} + { + \use:c { __deriv_#2_style_frac_slash:n } + { \__deriv_p_numerator_nofun:Nn #1 {#2} } + { \__deriv_p_denominator:n {#2} } + } + \__deriv_function:nn {#2} {#5} + } +} +% inf , dv , order , mixed order , function , variable , sb-point , sp-point +\cs_new_protected:Npn \__deriv_pdv_star:Nnnnnnnn #1 #2 #3 #4 #5 #6 #7 #8 +{ + \__deriv_preparation:NNNnnnn \l__deriv_p_mo_tl \l__deriv_p_denom_tl #1 {#2} {#3} {#4} {#6} + \__deriv_evaluation:nnnn {#2} {#7} {#8} + { + \__deriv_fraction:nn {#2} + { + \use:c { __deriv_#2_style_frac:n } + { \__deriv_p_numerator_nofun:Nn #1 {#2} } + { \__deriv_p_denominator:n {#2} } + } + \__deriv_function:nn {#2} {#5} + } +} +% inf , dv , order , mixed order , function , variable , sb-point , sp-point +\cs_new_protected:Npn \__deriv_pdv_slash:Nnnnnnnn #1 #2 #3 #4 #5 #6 #7 #8 +{ + \__deriv_preparation:NNNnnnn \l__deriv_p_mo_tl \l__deriv_p_denom_tl #1 {#2} {#3} {#4} {#6} + \__deriv_evaluation_slash:nnnn {#2} {#7} {#8} + { + \__deriv_fraction_slash:nn {#2} + { + \use:c { __deriv_#2_style_frac_slash:n } + { \__deriv_p_numerator_fun:Nnn #1 {#2} {#5} } + { \__deriv_p_denominator:n {#2} } + } + } +} +% inf , dv , order , mixed order , function , variable , sb-point , sp-point +\cs_new_protected:Npn \__deriv_pdv_none:Nnnnnnnn #1 #2 #3 #4 #5 #6 #7 #8 +{ + \__deriv_preparation:NNNnnnn \l__deriv_p_mo_tl \l__deriv_p_denom_tl #1 {#2} {#3} {#4} {#6} + \__deriv_evaluation:nnnn {#2} {#7} {#8} + { + \__deriv_fraction:nn {#2} + { + \use:c { __deriv_#2_style_frac:n } + { \__deriv_p_numerator_fun:Nnn #1 {#2} {#5} } + { \__deriv_p_denominator:n {#2} } + } + } +}% inf , dv , function +\cs_new_protected:Npn \__deriv_p_numerator_fun:Nnn #1 #2 #3 +{ + \__deriv_insert_inf:Nn #1 {#2} + \__deriv_insert_ord:Nnn \l__deriv_p_mo_tl {#2} { inf_ord } + \__deriv_insert_fun:Nnn \l__deriv_p_mo_tl {#2} {#3} +} +% inf , dv +\cs_new_protected:Npn \__deriv_p_numerator_nofun:Nn #1 #2 +{ + \__deriv_insert_inf:Nn #1 {#2} + \__deriv_insert_ord:Nnn \l__deriv_p_mo_tl {#2} { inf_ord } +} +% dv +\cs_new_protected:Npn \__deriv_p_denominator:n #1 +{ + \tl_use:N \l__deriv_p_denom_tl %{ \__deriv_insert_mskip:nn {#1} { var_inf } } +} +% mixed-order-tl , denom-seq , inf , dv , order , mixed order , variable +\cs_new_protected:Npn \__deriv_preparation:NNNnnnn #1 #2 #3 #4 #5 #6 #7 +{ + \seq_clear:N #2 + \seq_set_from_clist:Nn \l__deriv_p_var_seq {#7} + \tl_if_novalue:nTF {#5} { \seq_clear:N \l__deriv_p_order_seq } { \seq_set_from_clist:Nn \l__deriv_p_order_seq {#5} } + + \tl_if_novalue:nTF {#6} + { + \seq_set_eq:NN \l__deriv_p_mo_seq \l__deriv_p_order_seq + \__deriv_adjust_mo_seq:NNN \l__deriv_p_mo_seq \l__deriv_p_var_seq \l__deriv_p_order_seq + \__deriv_mixed_order:NNn #1 \l__deriv_p_mo_seq {#4} + } + { \tl_set:Nn #1 {#6} } + + \__deriv_p_build_denom:NNNNn \l__deriv_p_var_seq \l__deriv_p_order_seq #2 #3 {#4} +} + +\cs_new_protected:Npn \__deriv_adjust_mo_seq:NNN #1 #2 #3 +{ + \int_set:Nn \l__deriv_vmo_int { \seq_count:N #2 - \seq_count:N #3 } + \__deriv_case:nF + { + { \int_compare_p:nNn { \l__deriv_vmo_int } > { 0 } } { \seq_put_left:NV #1 \l__deriv_vmo_int } + { \int_compare_p:nNn { \l__deriv_vmo_int } = { 0 } } { \prg_do_nothing: } + } + { + \int_step_inline:nn { -1 * \l__deriv_vmo_int } + { \seq_pop_right:NN #1 \l__deriv_p_tmpa_tl } + } +} +% \l__deriv_p_var_seq \l__deriv_p_order_seq, denom-tl , inf , dv +\cs_new_protected:Npn \__deriv_p_build_denom:NNNNn #1 #2 #3 #4 #5 +{ + \int_zero:N \l__deriv_tmpa_int + \seq_map_inline:Nn #1 + { + \int_incr:N \l__deriv_tmpa_int + \seq_pop_left:NN #2 \l__deriv_p_tmpa_tl + \tl_if_blank:nF {##1} + { + \tl_put_right:Nx #3 + { + \__deriv_insert_inf:Nn #4 {#5} + \int_compare:nNnTF { \l__deriv_tmpa_int } = { \seq_count:N #1 } + { \__deriv_insert_var_ord:Nnn \l__deriv_p_tmpa_tl {#5} {##1} } + { \__deriv_insert_var_ord_sep:Nnn \l__deriv_p_tmpa_tl {#5} {##1} } + } + } + } +} +%%%%% And the rest of the code %%%%% +% inf , dv +\cs_new:Npn \__deriv_insert_inf:Nn #1 #2 +{ + \exp_not:n + { + \use:c { __deriv_#2_style_inf:n } + { \tl_use:N #1 } + } +} +% dv , function +\cs_new:Npn \__deriv_insert_fun:Nnn #1 #2 #3 +{ + \tl_if_blank:nF {#3} + { + \str_if_eq:NNTF #1 1 + { \__deriv_insert_mskip:nn {#2} { inf_fun } } + { \__deriv_insert_mskip:nn {#2} { ord_fun } } + \__deriv_function:nn {#2} {#3} + } +} +% order, dv , variable +\cs_new:Npn \__deriv_insert_var_ord:Nnn #1 #2 #3 +{ + \tl_if_blank:nF {#3} + { + \__deriv_insert_mskip:nn {#2} { inf_var } + \exp_not:n { \__deriv_variable:nn {#2} {#3} } + \__deriv_insert_ord:Nnn #1 {#2} { var_ord } + } +} +\cs_new:Npn \__deriv_insert_var_ord_sep:Nnn #1 #2 #3 +{ + \tl_if_blank:nF {#3} + { + \__deriv_insert_mskip:nn {#2} { inf_var } + \exp_not:n { \__deriv_variable:nn {#2} {#3} } + \__deriv_insert_ord:Nn #1 {#2} + } +} +% dv , name +\cs_new:Npn \__deriv_insert_mskip:nn #1 #2 +{ + \str_if_eq:vnF { l__deriv_#1_sep_#2_muskip } { 0.0mu } + { \exp_args:Nc \mskip { l__deriv_#1_sep_#2_muskip } } +} +% order , dv , name +\cs_new:Npn \__deriv_insert_ord:Nnn #1 #2 #3 +{ + \__show_order:NT #1 + { + \sp + { + \__deriv_insert_mskip:nn {#2} {#3} + \tl_use:N #1 + } + } +} +% order , dv , name +\cs_new:Npn \__deriv_insert_ord:Nn #1 #2 +{ + \__show_order:NTF #1 + { + \sp + { + \__deriv_insert_mskip:nn {#2} { var_ord } + \tl_use:N #1 + } + \__deriv_insert_mskip:nn {#2} { ord_inf } + } + { \__deriv_insert_mskip:nn {#2} { var_inf } } +} +% order , order-list +\cs_new:Npn \__deriv_set_order:Nn #1 #2 +{ + \tl_if_novalue:nTF {#2} + { \tl_set:Nn #1 { 1 } } + { \tl_set:Nn #1 {#2} } +} +% muskip , length +\cs_new:Npn \__deriv_set_rubber_length:Nn #1 #2 +{ + \seq_set_split:Nnn \l__deriv_rubber_seq { , } { #2 } + \exp_args:NNf + \muskip_set:Nn #1 { \seq_use:Nnnn \l__deriv_rubber_seq { mu plus } { mu plus } { mu minus } mu } +} + +%%%%% Scale, delimiters, evaluation %%%%% +% dv , function +\cs_new:Npn \__deriv_function:nn #1 #2 +{ + \bool_set_false:c { l__deriv_#1_mics_var_bool } + \bool_if:cTF { l__deriv_#1_mics_fun_bool } + { + \bool_set_false:c { l__deriv_#1_mics_fun_bool } + \__deriv_add_delims:nnn {#1} { fun } {#2} + } + { #2 } +} +% dv , variable +\cs_new:Npn \__deriv_variable:nn #1 #2 +{ + \bool_if:cTF { l__deriv_#1_mics_var_bool } + { + \bool_set_false:c { l__deriv_#1_mics_var_bool } + \__deriv_add_delims:nnn {#1} { var } {#2} + } + { #2 } +} +% dv , code-for-fraction +\cs_new:Npn \__deriv_fraction:nn #1 #2 +{ + \bool_if:cTF { l__deriv_#1_mics_frac_bool } + { + \bool_set_false:c { l__deriv_#1_mics_frac_bool } + \__deriv_add_delims:nnn {#1} { frac } {#2} + } + { #2 } +} +% dv , code-for-fraction +\cs_new:Npn \__deriv_fraction_slash:nn #1 #2 +{ + \bool_if:cTF { l__deriv_#1_mics_frac_bool } + { + \bool_set_false:c { l__deriv_#1_mics_frac_bool } + \__deriv_add_delims:nnn {#1} { frac_slash } {#2} + } + { #2 } +} +% dv , sub , sup , code-for-fraction +\cs_new:Npn \__deriv_evaluation:nnnn #1 #2 #3 #4 +{ + \__if_novalue_blank_or:nnTF {#2} {#3} + { #4 } + { + \__deriv_add_delims:nnn {#1} { eval } {#4} + \__if_novalue_blank:nF {#2} { \sb{ \__deriv_insert_mskip:nn {#1} { eval_sb } #2 } } + \__if_novalue_blank:nF {#3} { \sp{ \__deriv_insert_mskip:nn {#1} { eval_sp } #3 } } + } +} +% dv , sub , sup , code-for-fraction +\cs_new:Npn \__deriv_evaluation_slash:nnnn #1 #2 #3 #4 +{ + \__if_novalue_blank_or:nnTF {#2} {#3} + { #4 } + { + \__deriv_add_delims:nnn {#1} { eval_slash } {#4} + \__if_novalue_blank:nF {#2} { \sb{ \__deriv_insert_mskip:nn {#1} { eval_sb } #2 } } + \__if_novalue_blank:nF {#3} { \sp{ \__deriv_insert_mskip:nn {#1} { eval_sp } #3 } } + } +} +% dv , name , value +\cs_new:Npn \__deriv_add_delims:nnn #1 #2 #3 +{ + \__deriv_scale_left:nn {#1} {#2} + {#3} + \__deriv_scale_right:nn {#1} {#2} +} +% dv , name +\cs_new:Npn \__deriv_scale_left:nn #1 #2 +{ + \exp_args:Nv \str_case:nnF { l__deriv_#1_scale_#2_tl } + { + { auto } { \__deriv_scale_auto:Nnnn \__deriv_auto_left:n {#1} {#2} { 1 } } + { none } { \__deriv_scale_none:nnn {#1} {#2} { 1 } } + } + { \__deriv_scale_big:nnnm {#1} {#2} { 1 } { l } } +} +% dv , name +\cs_new:Npn \__deriv_scale_right:nn #1 #2 +{ + \exp_args:Nv \str_case:nnF { l__deriv_#1_scale_#2_tl } + { + { auto } { \__deriv_scale_auto:Nnnn \__deriv_auto_right:n {#1} {#2} { 2 } } + { none } { \__deriv_scale_none:nnn {#1} {#2} { 2 } } + } + { \__deriv_scale_big:nnnm {#1} {#2} { 2 } { r } } +} +% left/right , dv , name, number +\cs_new:Npn \__deriv_scale_auto:Nnnn #1 #2 #3 #4 +{ + #1 \tl_item:cn { l__deriv_#2_delims_#3_tl } { #4 } +} +% dv , name , number +\cs_new:Npn \__deriv_scale_none:nnn #1 #2 #3 +{ + \str_if_eq:cNF { l__deriv_#1_delims_#2_tl } . { \tl_item:cn { l__deriv_#1_delims_#2_tl } { #3 } } +} +% dv , name , number , l/r +\cs_new:Npn \__deriv_scale_big:nnnn #1 #2 #3 #4 +{ + \tl_use:c { \tl_use:c { l__deriv_#1_scale_#2_tl } #4 } { \tl_item:cn { l__deriv_#1_delims_#2_tl } { #3 } } +} + +%%%%% Calculation of mixed order %%%%% +% mixed-order-tl , mixed-order-seq , dv +\cs_new:Npn \__deriv_mixed_order:NNn #1 #2 #3 +{ + \__deriv_replace:NN \l__deriv_input_seq #2 + \__deriv_seq_counting:N \l__deriv_input_seq + \__deriv_combine_seq:N \l__deriv_unsorted_seq + \__deriv_sort:NNn \l__deriv_sorted_seq \l__deriv_unsorted_seq {#3} + \__deriv_output:NNNn #1 \l__deriv_sorted_seq \l__deriv_numerical_int {#3} +} +% input-seq , mixed-order-seq +\cs_new_protected:Npn \__deriv_replace:NN #1 #2 +{ + \tl_set:Nf \l__deriv_input_tl { \seq_use:Nn #2 { , } } + \tl_remove_all:Nn \l__deriv_input_tl { ~ } + \tl_replace_all:Nnn \l__deriv_input_tl { -- } { , } + \tl_replace_all:Nnn \l__deriv_input_tl { - } { ,- } + \tl_replace_all:Nnn \l__deriv_input_tl { + } { , } + + \exp_args:NNV \seq_set_from_clist:Nn #1 \l__deriv_input_tl +} +% input-seq +\cs_new_protected:Npn \__deriv_seq_counting:N #1 +{ + \seq_clear:N \l__deriv_symbol_seq + \seq_clear:N \l__deriv_number_seq + + \seq_map_inline:Nn #1 + { + \__deriv_extract:NNn \l__deriv_sym_tmpa_tl \l__deriv_num_tmpa_tl {##1} + + \seq_if_in:NVTF \l__deriv_symbol_seq \l__deriv_sym_tmpa_tl + { \__deriv_update_seq:NN \l__deriv_sym_tmpa_tl \l__deriv_num_tmpa_tl } + { \__deriv_add_to_seq:NN \l__deriv_sym_tmpa_tl \l__deriv_num_tmpa_tl } + } +} +% sym-tl , num-tl , seq-item +\cs_new_protected:Npn \__deriv_extract:NNn #1 #2 #3 +{ + \regex_extract_once:NnN \c__deriv_pattern_regex {#3} \l__deriv_extract_seq + \seq_pop_right:NN \l__deriv_extract_seq #1 + \seq_pop_right:NN \l__deriv_extract_seq #2 + + \exp_args:NV \str_case:nn #2 + { + { } { \tl_set:Nn #2 { 1 } } + { - } { \tl_set:Nn #2 { -1 } } + } +} +% unsorted-seq +\cs_new:Npn \__deriv_combine_seq:N #1 +{ + \seq_clear:N #1 + \seq_map_inline:Nn \l__deriv_symbol_seq + { + \seq_pop_left:NN \l__deriv_number_seq \l__deriv_num_tmpa_tl + \__deriv_eval_term:NNn #1 \l__deriv_num_tmpa_tl {##1} + } +} +% unsorted-seq , num-tl, seq-item +\cs_new_protected:Npn \__deriv_eval_term:NNn #1 #2 #3 +{ + \__deriv_case:nF + { + { \tl_if_empty_p:n {#3} } { \int_set:Nn \l__deriv_numerical_int {#2} } + { \int_compare_p:nNn {#2} = { 1 } } { \seq_put_left:Nn #1 {#3} } + { \int_compare_p:nNn {#2} = { 0 } } { \prg_do_nothing: } + { \int_compare_p:nNn {#2} = { -1 } } { \seq_put_left:Nn #1 { -#3 } } + } + { \seq_put_left:No #1 { #2 #3 } } +} +% sym-tl , num-tl +\cs_new_protected:Npn \__deriv_add_to_seq:NN #1 #2 +{ + \seq_put_left:NV \l__deriv_symbol_seq #1 + \seq_put_left:NV \l__deriv_number_seq #2 +} +% sym-tl , num-tl +\cs_new_protected:Npn \__deriv_update_seq:NN #1 #2 +{ + \__deriv_get_position:NN \l__deriv_position_int #1 + \__deriv_rebuild_seq:NNN \l__deriv_number_seq \l__deriv_position_int #2 +} +% position-int , sym-tl +\cs_new:Npn \__deriv_get_position:NN #1 #2 +{ + \int_zero:N #1 + \seq_map_inline:Nn \l__deriv_symbol_seq + { + \int_incr:N #1 + \exp_args:NV \tl_if_eq:nnT #2 {##1} { \seq_map_break: } + } +} +% num-seq , position-int , num-tl +\cs_new_protected:Npn \__deriv_rebuild_seq:NNN #1 #2 #3 +{ + \int_zero:N \l__deriv_rebuild_int + \seq_clear:N \l__deriv_rebuild_seq + + \seq_map_inline:Nn #1 + { + \int_incr:N \l__deriv_rebuild_int + \int_compare:nNnTF \l__deriv_rebuild_int = #2 + { + \tl_set:Nf \l__deriv_num_tmpb_tl { \int_eval:n { ##1 + #3 } } + \seq_put_right:NV \l__deriv_rebuild_seq \l__deriv_num_tmpb_tl + } + { \seq_put_right:Nn \l__deriv_rebuild_seq {##1} } + } + \seq_set_eq:NN #1 \l__deriv_rebuild_seq +} +% sorted-seq , unsorted-seq , dv +\cs_new_protected:Npn \__deriv_sort:NNn #1 #2 #3 +{ + \int_set:Nn \l__deriv_sort_max_int { \clist_count:c { l__deriv_#3_sort_method_clist } } + + \seq_sort:Nn #2 + { + \__deriv_extract:NNn \l__deriv_sym_tmpa_tl \l__deriv_num_tmpa_tl {##1} + \__deriv_extract:NNn \l__deriv_sym_tmpb_tl \l__deriv_num_tmpb_tl {##2} + \int_zero:N \l__deriv_sort_counter_int + \__deriv_sort_method:n {#3} + } + \seq_set_eq:NN #1 #2 +} +% dv +\cs_new_protected:Npn \__deriv_sort_method:n #1 +{ + \int_incr:N \l__deriv_sort_counter_int + + \exp_args:Nf + \str_case:nn { \clist_item:cn { l__deriv_#1_sort_method_clist } { \l__deriv_sort_counter_int } } + { + { sign } { \__deriv_sort_sign:n {#1} } + { symbol } { \__deriv_sort_symbol:n {#1} } + { abs } { \__deriv_sort_abs:n {#1} } + } +} +% dv +\cs_new_protected:Npn \__deriv_sort_sign:n #1 +{ + \__deriv_case:nF + { + { \tl_if_head_eq_charcode_p:VN \l__deriv_num_tmpb_tl - && ! \tl_if_head_eq_charcode_p:VN \l__deriv_num_tmpa_tl - } { \__deriv_sort_reverse:nnn {#1} { sign } { same } } + { \tl_if_head_eq_charcode_p:VN \l__deriv_num_tmpa_tl - && ! \tl_if_head_eq_charcode_p:VN \l__deriv_num_tmpb_tl - } { \__deriv_sort_reverse:nnn {#1} { sign } { swapped } } + } + { + \int_compare:nNnTF { \l__deriv_sort_counter_int } = { \l__deriv_sort_max_int } + { \sort_return_same: } + { \__deriv_sort_method:n {#1} } + } +} +% dv +\cs_new_protected:Npn \__deriv_sort_symbol:n #1 +{ + \__deriv_case:nF + { + { \int_compare_p:nNn { \tl_count:N \l__deriv_sym_tmpa_tl } > { \tl_count:N \l__deriv_sym_tmpb_tl } } { \__deriv_sort_reverse:nnn {#1} { symbol } { same } } + { \int_compare_p:nNn { \tl_count:N \l__deriv_sym_tmpa_tl } < { \tl_count:N \l__deriv_sym_tmpb_tl } } { \__deriv_sort_reverse:nnn {#1} { symbol } { swapped } } + } + { + \int_compare:nNnTF { \l__deriv_sort_counter_int } = { \l__deriv_sort_max_int } + { \sort_return_same: } + { \__deriv_sort_method:n {#1} } + } +} +% dv +\cs_new_protected:Npn \__deriv_sort_abs:n #1 +{ + \__deriv_case:nF + { + { \int_compare_p:nNn { \int_abs:n \l__deriv_num_tmpa_tl } > { \int_abs:n \l__deriv_num_tmpb_tl } } { \__deriv_sort_reverse:nnn {#1} { abs } { same } } + { \int_compare_p:nNn { \int_abs:n \l__deriv_num_tmpa_tl } < { \int_abs:n \l__deriv_num_tmpb_tl } } { \__deriv_sort_reverse:nnn {#1} { abs } { swapped } } + } + { + \int_compare:nNnTF { \l__deriv_sort_counter_int } = { \l__deriv_sort_max_int } + { \sort_return_same: } + { \__deriv_sort_method:n {#1} } + } +} +% dv , sort-method , same/swapped +\cs_new_protected:Npn \__deriv_sort_reverse:nnn #1 #2 #3 +{ + \exp_args:Nc + \bool_xor:nnTF { l__deriv_#1_sort_#2_reverse_bool } { \str_if_eq_p:nn {#3} { same } } + { \sort_return_same: } + { \sort_return_swapped: } +} +% mixed-order-tl , sorted-seq , numerical-term, dv +\cs_new_protected:Npn \__deriv_output:NNNn #1 #2 #3 #4 +{ + \tl_set:Nf #1 { \seq_use:Nn #2 { + } } + + \int_compare:nNnF {#3} = { 0 } + { + \tl_if_empty:NTF #1 + { \tl_put_left:NV #1 #3 } + { + \exp_args:Nv \str_case:nnF { l__deriv_#4_sort_numerical_tl } + { + { last } { \tl_put_right:Nx #1 { + \int_use:N #3 } } + { first } { \tl_put_left:Nx #1 { \int_use:N #3 + } } + } + { + \bool_if:nTF { \tl_if_head_eq_charcode_p:VN #1 - } + { \tl_put_left:NV #1 #3 } + { \tl_put_right:Nx #1 { + \int_use:N #3 } } + } + } + } + \tl_replace_all:Nnn #1 { +- } { - } + \tl_if_empty:NT #1 { \tl_set:Nn #1 { 0 } } +} + +%%%%% Generate variants %%%%% + +\cs_generate_variant:Nn \tl_if_head_eq_charcode_p:nN { V } +\cs_generate_variant:Nn \__deriv_set_rubber_length:Nn { c } +\cs_generate_variant:Nn \__deriv_p_variables:n { V } +\cs_generate_variant:Nn \__deriv_d_variables:n { V } +\cs_generate_variant:Nn \deriv_p_define:nnnn { V } +\cs_generate_variant:Nn \deriv_d_define:nnnn { V } +\cs_generate_variant:Nn \__deriv_derivset:nn { V, VV } +\cs_generate_variant:Nn \__deriv_p_define_keys:n { V } +\cs_generate_variant:Nn \__deriv_d_define_keys:n { V } + +%%%%% Messages %%%%% + +\msg_new:nnnn { deriv } { command-already-defined } +{ Command~'#1'~already~defined! } +{ + You~have~used~#2~with~a~command~that~already~has~a~definition. \\ + The~existing~definition~of~'#1'~will~not~be~altered. +} + +\msg_new:nnnn { deriv } { derivative-not-defined } +{ Derivative~'#1'~is~not~defined! } +{ + You~have~used~#2~with~a~derivative~that~was~never~defined. +} +\msg_new:nnnn { deriv } { command-not-defined } +{ Command~'#1'~not~yet~defined! } +{ + You~have~used~#2~with~a~derivative~that~was~never~defined. +} + +%%%%% Declaring derivatives %%%%% + +\bool_lazy_or:nnT { \sys_if_engine_luatex_p: } { \sys_if_engine_xetex_p: } +{ + \DeclareOdvVariant{\odv}{d}[style-inf = \symup] + \DeclareOdvVariant{\mdv}{D}[style-inf = \symup] + \DeclareOdvVariant{\fdv}{\delta} + \DeclareOdvVariant{\adv}{\Delta} + \DeclareOdvVariant{\jdv}{\partial}[misc-add-delims = {fun, var}] + \DeclarePdvVariant{\pdv}{\partial}[sep-inf-ord=1, sep-ord-fun=-2] + +} +\sys_if_engine_pdftex:T +{ + \DeclareOdvVariant{\odv}{d}[style-inf = \mathrm] + \DeclareOdvVariant{\mdv}{D}[style-inf = \mathrm] + \DeclareOdvVariant{\fdv}{\delta} + \DeclareOdvVariant{\adv}{\Delta}[style-inf = \mathrm] + \DeclareOdvVariant{\jdv}{\partial}[misc-add-delims = {fun, var}] + \DeclarePdvVariant{\pdv}{\partial}[sep-inf-ord=1, sep-ord-fun=-2] +} +%\derivset{all} + +\endinput |