%% %% This is file `l3calc.sty', %% generated with the docstrip utility. %% %% The original source files were: %% %% l3calc.dtx (with options: `package') %% %% %% EXPERIMENTAL CODE %% %% Do not distribute this file without also distributing the %% source files specified above. %% %% Do not distribute a modified version of this file. %% %% %% File: l3calc.dtx Copyright (C) 2006,2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this %% license or (at your option) any later version. The latest version %% of this license is in the file %% %% http://www.latex-project.org/lppl.txt %% %% This file is part of the ``expl3 bundle'' (The Work in LPPL) %% and all files in that bundle must be distributed together. %% %% The released version of this bundle is available from CTAN. %% %% ----------------------------------------------------------------------- %% %% The development version of the bundle can be found at %% %% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% %%%%%%%%%%% %% NOTE: %% %%%%%%%%%%% %% %% Snapshots taken from the repository represent work in progress and may %% not work or may contain conflicting material! We therefore ask %% people _not_ to put them into distributions, archives, etc. without %% prior consultation with the LaTeX Project Team. %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} \GetIdInfo$Id: l3calc.dtx 1776 2010-02-07 21:51:23Z joseph $ {L3 Experimental calc module} \ProvidesExplPackage {\filename}{\filedate}{\fileversion}{\filedescription} \package_check_loaded_expl: \tl_new:N \l_calc_expression_tl \cs_new_nopar:Npn \g_calc_A_register{} \cs_new_nopar:Npn \l_calc_B_register{} \int_new:N \l_calc_current_type_int \int_new:N \g_calc_A_int \int_new:N \l_calc_B_int \int_new:N \l_calc_C_int \dim_new:N \g_calc_A_dim \dim_new:N \l_calc_B_dim \dim_new:N \l_calc_C_dim \skip_new:N \g_calc_A_skip \skip_new:N \l_calc_B_skip \skip_new:N \l_calc_C_skip \muskip_new:N \g_calc_A_muskip \muskip_new:N \l_calc_B_muskip \muskip_new:N \l_calc_C_muskip \cs_new:Npn \calc_assign_generic:NNNNnn#1#2#3#4#5#6{ \cs_set_eq:NN\g_calc_A_register#2 \cs_set_eq:NN\l_calc_B_register#3 \int_set:Nn \l_calc_current_type_int {#1} \group_begin: \cs_set_eq:NN \real \calc_real:n \cs_set_eq:NN \ratio\calc_ratio:nn \tl_set:Nx\l_calc_expression_tl{#6} \exp_after:wN \group_end: \exp_after:wN\calc_open:w\exp_after:wN(\l_calc_expression_tl ! \pref_global:D\g_calc_A_register\l_calc_B_register \group_end: #4{#5}\l_calc_B_register } \cs_new_nopar:Npn\calc_int_set:Nn{ \calc_assign_generic:NNNNnn\c_zero\g_calc_A_int\l_calc_B_int\int_set:Nn } \cs_new_nopar:Npn\calc_int_gset:Nn{ \calc_assign_generic:NNNNnn\c_zero\g_calc_A_int\l_calc_B_int\int_gset:Nn } \cs_new_nopar:Npn\calc_int_add:Nn{ \calc_assign_generic:NNNNnn\c_zero\g_calc_A_int\l_calc_B_int\int_add:Nn } \cs_new_nopar:Npn\calc_int_gadd:Nn{ \calc_assign_generic:NNNNnn\c_zero\g_calc_A_int\l_calc_B_int\int_gadd:Nn } \cs_new_nopar:Npn\calc_int_sub:Nn{ \calc_assign_generic:NNNNnn\c_zero\g_calc_A_int\l_calc_B_int\int_sub:Nn } \cs_new_nopar:Npn\calc_int_gsub:Nn{ \calc_assign_generic:NNNNnn\c_zero\g_calc_A_int\l_calc_B_int\int_gsub:Nn } \cs_new_nopar:Npn\calc_dim_set:Nn{ \calc_assign_generic:NNNNnn\c_one\g_calc_A_dim\l_calc_B_dim\dim_set:Nn } \cs_new_nopar:Npn\calc_dim_gset:Nn{ \calc_assign_generic:NNNNnn\c_one\g_calc_A_dim\l_calc_B_dim\dim_gset:Nn } \cs_new_nopar:Npn\calc_dim_add:Nn{ \calc_assign_generic:NNNNnn\c_one\g_calc_A_dim\l_calc_B_dim\dim_add:Nn } \cs_new_nopar:Npn\calc_dim_gadd:Nn{ \calc_assign_generic:NNNNnn\c_one\g_calc_A_dim\l_calc_B_dim\dim_gadd:Nn } \cs_new_nopar:Npn\calc_dim_sub:Nn{ \calc_assign_generic:NNNNnn\c_one\g_calc_A_int\l_calc_B_int\dim_sub:Nn } \cs_new_nopar:Npn\calc_dim_gsub:Nn{ \calc_assign_generic:NNNNnn\c_one\g_calc_A_int\l_calc_B_int\dim_gsub:Nn } \cs_new_nopar:Npn\calc_skip_set:Nn{ \calc_assign_generic:NNNNnn\c_two\g_calc_A_skip\l_calc_B_skip\skip_set:Nn } \cs_new_nopar:Npn\calc_skip_gset:Nn{ \calc_assign_generic:NNNNnn\c_two\g_calc_A_skip\l_calc_B_skip\skip_gset:Nn } \cs_new_nopar:Npn\calc_skip_add:Nn{ \calc_assign_generic:NNNNnn\c_two\g_calc_A_skip\l_calc_B_skip\skip_add:Nn } \cs_new_nopar:Npn\calc_skip_gadd:Nn{ \calc_assign_generic:NNNNnn\c_two\g_calc_A_skip\l_calc_B_skip\skip_gadd:Nn } \cs_new_nopar:Npn\calc_skip_sub:Nn{ \calc_assign_generic:NNNNnn\c_two\g_calc_A_skip\l_calc_B_skip\skip_sub:Nn } \cs_new_nopar:Npn\calc_skip_gsub:Nn{ \calc_assign_generic:NNNNnn\c_two\g_calc_A_skip\l_calc_B_skip\skip_gsub:Nn } \cs_new_nopar:Npn\calc_muskip_set:Nn{ \calc_assign_generic:NNNNnn\c_three\g_calc_A_muskip\l_calc_B_muskip \muskip_set:Nn } \cs_new_nopar:Npn\calc_muskip_gset:Nn{ \calc_assign_generic:NNNNnn\c_three\g_calc_A_muskip\l_calc_B_muskip \muskip_gset:Nn } \cs_new_nopar:Npn\calc_muskip_add:Nn{ \calc_assign_generic:NNNNnn\c_three\g_calc_A_muskip\l_calc_B_muskip \muskip_add:Nn } \cs_new_nopar:Npn\calc_muskip_gadd:Nn{ \calc_assign_generic:NNNNnn\c_three\g_calc_A_muskip\l_calc_B_muskip \muskip_gadd:Nn } \cs_new_nopar:Npn\calc_muskip_sub:Nn{ \calc_assign_generic:NNNNnn\c_three\g_calc_A_muskip\l_calc_B_muskip \muskip_add:Nn } \cs_new_nopar:Npn\calc_muskip_gsub:Nn{ \calc_assign_generic:NNNNnn\c_three\g_calc_A_muskip\l_calc_B_muskip \muskip_gadd:Nn } \cs_new_nopar:Npn \calc_pre_scan:N #1{ \if_meaning:w(#1 \exp_after:wN\calc_open:w \else: \if_meaning:w \calc_textsize:Nn #1 \else: \if_meaning:w \calc_maxmin_operation:Nnn #1 \else: \calc_numeric: \fi: \fi: \fi: #1} \cs_new_nopar:Npn \calc_open:w({ \group_begin:\group_execute_after:N\calc_init_B: \group_begin:\group_execute_after:N\calc_init_B: \calc_pre_scan:N } \cs_new_nopar:Npn\calc_init_B:{\l_calc_B_register\g_calc_A_register} \cs_new_nopar:Npn\calc_numeric:{ \tex_afterassignment:D\calc_post_scan:N \pref_global:D\g_calc_A_register } \cs_new_nopar:Npn\calc_close:{ \group_end:\pref_global:D\g_calc_A_register\l_calc_B_register \group_end:\pref_global:D\g_calc_A_register\l_calc_B_register \calc_post_scan:N} \cs_new_nopar:Npn\calc_post_scan:N#1{ \if_meaning:w#1!\cs_set_eq:NN\calc_next:w\group_end: \else: \if_meaning:w#1+\cs_set_eq:NN\calc_next:w\calc_add: \else: \if_meaning:w#1-\cs_set_eq:NN\calc_next:w\calc_subtract: \else: \if_meaning:w#1*\cs_set_eq:NN\calc_next:w\calc_multiply:N \else: \if_meaning:w#1/\cs_set_eq:NN\calc_next:w\calc_divide:N \else: \if_meaning:w#1)\cs_set_eq:NN\calc_next:w\calc_close: \else: \if_meaning:w#1\scan_stop:\cs_set_eq:NN\calc_next:w\calc_post_scan:N \else: \cs_set_eq:NN \calc_next:w \prg_do_nothing: \calc_error:N#1 \fi: \fi: \fi: \fi: \fi: \fi: \fi: \calc_next:w} \cs_new_nopar:Npn \calc_multiply:N #1{ \if_meaning:w \calc_maxmin_operation:Nnn #1 \cs_set_eq:NN \calc_next:w \calc_maxmin_multiply: \else: \if_meaning:w \calc_ratio_multiply:nn #1 \cs_set_eq:NN \calc_next:w \calc_ratio_multiply:nn \else: \if_meaning:w \calc_real_evaluate:nn #1 \cs_set_eq:NN \calc_next:w \calc_real_multiply:n \else: \cs_set_nopar:Npn \calc_next:w{\calc_multiply: #1} \fi: \fi: \fi: \calc_next:w } \cs_new_nopar:Npn \calc_divide:N #1{ \if_meaning:w \calc_maxmin_operation:Nnn #1 \cs_set_eq:NN \calc_next:w \calc_maxmin_divide: \else: \if_meaning:w \calc_ratio_multiply:nn #1 \cs_set_eq:NN \calc_next:w \calc_ratio_divide:nn \else: \if_meaning:w \calc_real_evaluate:nn #1 \cs_set_eq:NN \calc_next:w \calc_real_divide:n \else: \cs_set_nopar:Npn \calc_next:w{\calc_divide: #1} \fi: \fi: \fi: \calc_next:w } \cs_new_nopar:Npn\calc_generic_add_or_subtract:N#1{ \group_end: \pref_global:D\g_calc_A_register\l_calc_B_register\group_end: \group_begin:\group_execute_after:N#1\group_begin: \group_execute_after:N\calc_init_B: \calc_pre_scan:N} \cs_new_nopar:Npn\calc_add:{\calc_generic_add_or_subtract:N\calc_add_A_to_B:} \cs_new_nopar:Npn\calc_subtract:{ \calc_generic_add_or_subtract:N\calc_subtract_A_from_B:} \cs_new_nopar:Npn\calc_add_A_to_B:{ \l_calc_B_register \if_case:w\l_calc_current_type_int \etex_numexpr:D\or: \etex_dimexpr:D\or: \etex_glueexpr:D\or: \etex_muexpr:D\fi: \l_calc_B_register + \g_calc_A_register\scan_stop: } \cs_new_nopar:Npn\calc_subtract_A_from_B:{ \l_calc_B_register \if_case:w\l_calc_current_type_int \etex_numexpr:D\or: \etex_dimexpr:D\or: \etex_glueexpr:D\or: \etex_muexpr:D\fi: \l_calc_B_register - \g_calc_A_register\scan_stop: } \cs_new_nopar:Npn\calc_generic_multiply_or_divide:N#1{ \group_end: \group_begin: \cs_set_eq:NN\g_calc_A_register\g_calc_A_int \cs_set_eq:NN\l_calc_B_register\l_calc_B_int \int_zero:N \l_calc_current_type_int \group_execute_after:N#1\calc_pre_scan:N } \cs_new_nopar:Npn\calc_multiply_B_by_A:{ \l_calc_B_register \if_case:w\l_calc_current_type_int \etex_numexpr:D\or: \etex_dimexpr:D\or: \etex_glueexpr:D\or: \etex_muexpr:D\fi: \l_calc_B_register*\g_calc_A_int\scan_stop: } \cs_new_nopar:Npn\calc_divide_B_by_A:{ \l_calc_B_register \if_case:w\l_calc_current_type_int \etex_numexpr:D\or: \etex_dimexpr:D\or: \etex_glueexpr:D\or: \etex_muexpr:D\fi: \l_calc_B_register/\g_calc_A_int\scan_stop: } \cs_new_nopar:Npn\calc_multiply:{ \calc_generic_multiply_or_divide:N\calc_multiply_B_by_A:} \cs_new_nopar:Npn\calc_divide:{ \calc_generic_multiply_or_divide:N\calc_divide_B_by_A:} \cs_new:Npn \calc_calculate_box_size:nnn #1#2#3{ \hbox_set:Nn \l_tmpa_box {{#3}} #2{\c_zero_dim \tl_map_function:nN{#1}\calc_calculate_box_size_aux:n} } \cs_set_nopar:Npn \calc_calculate_box_size_aux:n#1{ + #1\l_tmpa_box} \cs_set_protected:Npn \calc_textsize:Nn#1#2{ \group_begin: \cs_set_eq:NN\calc_widthof_aux:n\box_wd:N \cs_set_eq:NN\calc_heightof_aux:n\box_ht:N \cs_set_eq:NN\calc_depthof_aux:n\box_dp:N \cs_set_nopar:Npn\calc_totalheightof_aux:n{\box_ht:N\box_dp:N} \exp_args:No\calc_calculate_box_size:nnn{#1} {\dim_gset:Nn\g_calc_A_register} { \cs_set_eq:NN \calc_depthof_aux:n \calc_depthof_auxi:n \cs_set_eq:NN \calc_widthof_aux:n \calc_widthof_auxi:n \cs_set_eq:NN \calc_heightof_aux:n \calc_heightof_auxi:n \cs_set_eq:NN \calc_totalheightof_aux:n \calc_totalheightof_auxi:n #2 } \group_end: \calc_post_scan:N } \cs_set_protected:Npn\calc_ratio_multiply:nn#1#2{ \group_end:\group_begin: \if_num:w\l_calc_current_type_int < \c_three \calc_dim_set:Nn\l_calc_B_int{#1} \calc_dim_set:Nn\l_calc_C_int{#2} \else: \calc_dim_muskip:Nn{\l_calc_B_int\etex_mutoglue:D}{#1} \calc_dim_muskip:Nn{\l_calc_C_int\etex_mutoglue:D}{#2} \fi: \cs_gset_nopar:Npx\calc_calculated_ratio:{ \int_use:N\l_calc_B_int/\int_use:N\l_calc_C_int } \group_end: \l_calc_B_register \if_case:w\l_calc_current_type_int \etex_numexpr:D\or: \etex_dimexpr:D\or: \etex_glueexpr:D\or: \etex_muexpr:D\fi: \l_calc_B_register*\calc_calculated_ratio:\scan_stop: \group_begin: \calc_post_scan:N} \cs_new:Npn \calc_ratio_divide:nn#1#2{\calc_ratio_multiply:nn{#2}{#1}} \cs_new_protected_nopar:Npn\calc_real_evaluate:nn #1#2{ \group_end: \l_calc_B_register \if_case:w\l_calc_current_type_int \etex_numexpr:D\or: \etex_dimexpr:D\or: \etex_glueexpr:D\or: \etex_muexpr:D\fi: \l_calc_B_register * \tex_number:D \dim_eval:n{#1pt}/ \tex_number:D\dim_eval:n{#2pt} \scan_stop: \group_begin: \calc_post_scan:N} \cs_new_nopar:Npn \calc_real_multiply:n #1{\calc_real_evaluate:nn{#1}{1}} \cs_new_nopar:Npn \calc_real_divide:n {\calc_real_evaluate:nn{1}} \cs_set_protected:Npn\calc_maxmin_operation:Nnn#1#2#3{ \group_begin: \calc_maxmin_generic:Nnn#1{#2}{#3} \group_end: \calc_post_scan:N } \cs_new_protected:Npn \calc_maxmin_generic:Nnn#1#2#3{ \group_begin: \if_case:w\l_calc_current_type_int \calc_int_set:Nn\l_calc_C_int{#2}% \calc_int_set:Nn\l_calc_B_int{#3}% \pref_global:D\g_calc_A_register \if_num:w\l_calc_C_int#1\l_calc_B_int \l_calc_C_int\else:\l_calc_B_int\fi: \or: \calc_dim_set:Nn\l_calc_C_dim{#2}% \calc_dim_set:Nn\l_calc_B_dim{#3}% \pref_global:D\g_calc_A_register \if_dim:w\l_calc_C_dim#1\l_calc_B_dim \l_calc_C_dim\else:\l_calc_B_dim\fi: \or: \calc_skip_set:Nn\l_calc_C_skip{#2}% \calc_skip_set:Nn\l_calc_B_skip{#3}% \pref_global:D\g_calc_A_register \if_dim:w\l_calc_C_skip#1\l_calc_B_skip \l_calc_C_skip\else:\l_calc_B_skip\fi: \else: \calc_muskip_set:Nn\l_calc_C_muskip{#2}% \calc_muskip_set:Nn\l_calc_B_muskip{#3}% \pref_global:D\g_calc_A_register \if_dim:w\l_calc_C_muskip#1\l_calc_B_muskip \l_calc_C_muskip\else:\l_calc_B_muskip\fi: \fi: \group_end: } \cs_new:Npn\calc_maxmin_div_or_mul:NNnn#1#2#3#4{ \group_end: \group_begin: \int_zero:N\l_calc_current_type_int \group_execute_after:N#1 \calc_maxmin_generic:Nnn#2{#3}{#4} \group_end: \group_begin: \calc_post_scan:N } \cs_new_nopar:Npn\calc_maxmin_multiply:{ \calc_maxmin_div_or_mul:NNnn\calc_multiply_B_by_A:} \cs_new_nopar:Npn\calc_maxmin_divide: { \calc_maxmin_div_or_mul:NNnn\calc_divide_B_by_A:} \cs_new_nopar:Npn\calc_error:N#1{ \PackageError{calc} {`\token_to_str:N#1'~ invalid~ at~ this~ point} {I~ expected~ to~ see~ one~ of:~ +~ -~ *~ /~ )} } \cs_new:Npn \calc_maxof:nn#1#2{ \calc_maxmin_operation:Nnn > \exp_not:n{{#1}{#2}} } \cs_new:Npn \calc_minof:nn#1#2{ \calc_maxmin_operation:Nnn < \exp_not:n{{#1}{#2}} } \cs_set_eq:NN \maxof \calc_maxof:nn \cs_set_eq:NN \minof \calc_minof:nn \cs_new:Npn \calc_widthof:n#1{ \calc_textsize:Nn \exp_not:N\calc_widthof_aux:n\exp_not:n{{#1}} } \cs_new:Npn \calc_heightof:n#1{ \calc_textsize:Nn \exp_not:N\calc_heightof_aux:n\exp_not:n{{#1}} } \cs_new:Npn \calc_depthof:n#1{ \calc_textsize:Nn \exp_not:N\calc_depthof_aux:n\exp_not:n{{#1}} } \cs_new:Npn \calc_totalheightof:n#1{ \calc_textsize:Nn \exp_not:N\calc_totalheightof_aux:n \exp_not:n{{#1}} } \cs_new:Npn \calc_widthof_aux:n #1{ \exp_not:N\calc_widthof_aux:n\exp_not:n{{#1}} } \cs_new_eq:NN \calc_widthof_auxi:n \calc_widthof_aux:n \cs_new:Npn \calc_depthof_aux:n #1{ \exp_not:N\calc_depthof_aux:n\exp_not:n{{#1}} } \cs_new_eq:NN \calc_depthof_auxi:n \calc_depthof_aux:n \cs_new:Npn \calc_heightof_aux:n #1{ \exp_not:N\calc_heightof_aux:n\exp_not:n{{#1}} } \cs_new_eq:NN \calc_heightof_auxi:n \calc_heightof_aux:n \cs_new:Npn \calc_totalheightof_aux:n #1{ \exp_not:N\calc_totalheightof_aux:n\exp_not:n{{#1}} } \cs_new_eq:NN \calc_totalheightof_auxi:n \calc_totalheightof_aux:n \cs_new:Npn \calc_ratio:nn#1#2{ \calc_ratio_multiply:nn\exp_not:n{{#1}{#2}}} \cs_new_nopar:Npn \calc_real:n {\calc_real_evaluate:nn} \cs_set_eq:NN \depthof\calc_depthof:n \cs_set_eq:NN \widthof\calc_widthof:n \cs_set_eq:NN \heightof\calc_heightof:n \cs_set_eq:NN \totalheightof\calc_totalheightof:n %%\cs_set_eq:NN \ratio\calc_ratio:nn %%\cs_set_eq:NN \real\calc_real:n \cs_set_protected_nopar:Npn \setlength{\calc_skip_set:Nn} \cs_set_protected_nopar:Npn \gsetlength{\calc_skip_gset:Nn} \cs_set_protected_nopar:Npn \addtolength{\calc_skip_add:Nn} \cs_set_protected_nopar:Npn \gaddtolength{\calc_skip_gadd:Nn} \newif\iffirstchoice@ \firstchoice@true \cs_set_protected_nopar:Npn \calc_setcounter:nn#1#2{ \calc_chk_document_counter:nn{#1}{ \exp_args:Nc\calc_int_gset:Nn {c@#1}{#2} } } \cs_set_protected_nopar:Npn \calc_addtocounter:nn#1#2{ \iffirstchoice@ \calc_chk_document_counter:nn{#1}{ \exp_args:Nc\calc_int_gadd:Nn {c@#1}{#2} } \fi: } \cs_set_protected_nopar:Npn \calc_stepcounter:n#1{ \iffirstchoice@ \calc_chk_document_counter:nn{#1}{ \int_gincr:c {c@#1} \group_begin: \cs_set_eq:NN \@elt\@stpelt \use:c{cl@#1} \group_end: } \fi: } \cs_new_nopar:Npn \calc_chk_document_counter:nn#1{ \cs_if_free:cTF{c@#1}{\@nocounterr {#1}} } \cs_set_eq:NN \setcounter \calc_setcounter:nn \cs_set_eq:NN \addtocounter \calc_addtocounter:nn \cs_set_eq:NN \stepcounter \calc_stepcounter:n \AtBeginDocument{ \cs_set_eq:NN \setcounter \calc_setcounter:nn \cs_set_eq:NN \addtocounter \calc_addtocounter:nn \cs_set_eq:NN \stepcounter \calc_stepcounter:n } \cs_set_nopar:cpn{ver@calc.sty}{2005/08/06} %% %% %% End of file `l3calc.sty'.