%%
%% 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 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/cgi-bin/cvsweb.cgi/
%%
%% 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 573 2006-08-21 20:59:37Z morten $
       {L3 Experimental calc module}
\RequirePackage{l3int}
\RequirePackage{l3skip}
\RequirePackage{l3box}
\tlp_new:Nn\l_calc_expression_tlp{}
\def_new:Npn \g_calc_A_register{}
\def_new: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
\def_long_new:Npn \calc_assign_generic:NNNNNn#1#2#3#4#5#6{
  \let:NN\g_calc_A_register#2\let:NN\l_calc_B_register#3
  \int_set:Nn \l_calc_current_type_int {#1}
  \tlp_set:Nx\l_calc_expression_tlp{#6}
  \exp_after:NN\calc_open:w\exp_after:NN(\l_calc_expression_tlp!
  \pref_global:D\g_calc_A_register\l_calc_B_register
  \group_end:
  #4#5\l_calc_B_register
}
\def_new:Npn\calc_int_set:Nn{
  \calc_assign_generic:NNNNNn\c_zero\g_calc_A_int\l_calc_B_int\int_set:Nn
}
\def_new:Npn\calc_int_gset:Nn{
  \calc_assign_generic:NNNNNn\c_zero\g_calc_A_int\l_calc_B_int\int_gset:Nn
}
\def_new:Npn\calc_int_add:Nn{
  \calc_assign_generic:NNNNNn\c_zero\g_calc_A_int\l_calc_B_int\int_add:Nn
}
\def_new:Npn\calc_int_gadd:Nn{
  \calc_assign_generic:NNNNNn\c_zero\g_calc_A_int\l_calc_B_int\int_gadd:Nn
}
\def_new:Npn\calc_int_sub:Nn{
  \calc_assign_generic:NNNNNn\c_zero\g_calc_A_int\l_calc_B_int\int_sub:Nn
}
\def_new:Npn\calc_int_gsub:Nn{
  \calc_assign_generic:NNNNNn\c_zero\g_calc_A_int\l_calc_B_int\int_gsub:Nn
}
\def_new:Npn\calc_dim_set:Nn{
  \calc_assign_generic:NNNNNn\c_one\g_calc_A_dim\l_calc_B_dim\dim_set:Nn
}
\def_new:Npn\calc_dim_gset:Nn{
  \calc_assign_generic:NNNNNn\c_one\g_calc_A_dim\l_calc_B_dim\dim_gset:Nn
}
\def_new:Npn\calc_dim_add:Nn{
  \calc_assign_generic:NNNNNn\c_one\g_calc_A_dim\l_calc_B_dim\dim_add:Nn
}
\def_new:Npn\calc_dim_gadd:Nn{
  \calc_assign_generic:NNNNNn\c_one\g_calc_A_dim\l_calc_B_dim\dim_gadd:Nn
}
\def_new:Npn\calc_dim_sub:Nn{
  \calc_assign_generic:NNNNNn\c_one\g_calc_A_int\l_calc_B_int\dim_sub:Nn
}
\def_new:Npn\calc_dim_gsub:Nn{
  \calc_assign_generic:NNNNNn\c_one\g_calc_A_int\l_calc_B_int\dim_gsub:Nn
}
\def_new:Npn\calc_skip_set:Nn{
  \calc_assign_generic:NNNNNn\c_two\g_calc_A_dim\l_calc_B_dim\skip_set:Nn
}
\def_new:Npn\calc_skip_gset:Nn{
  \calc_assign_generic:NNNNNn\c_two\g_calc_A_dim\l_calc_B_dim\skip_gset:Nn
}
\def_new:Npn\calc_skip_add:Nn{
  \calc_assign_generic:NNNNNn\c_two\g_calc_A_dim\l_calc_B_dim\skip_add:Nn
}
\def_new:Npn\calc_skip_gadd:Nn{
  \calc_assign_generic:NNNNNn\c_two\g_calc_A_dim\l_calc_B_dim\skip_gadd:Nn
}
\def_new:Npn\calc_skip_sub:Nn{
  \calc_assign_generic:NNNNNn\c_two\g_calc_A_dim\l_calc_B_dim\skip_sub:Nn
}
\def_new:Npn\calc_skip_gsub:Nn{
  \calc_assign_generic:NNNNNn\c_two\g_calc_A_dim\l_calc_B_dim\skip_gsub:Nn
}
\def_new:Npn\calc_muskip_set:Nn{
  \calc_assign_generic:NNNNNn\c_three\g_calc_A_dim\l_calc_B_dim\muskip_set:Nn
}
\def_new:Npn\calc_muskip_gset:Nn{
  \calc_assign_generic:NNNNNn\c_three\g_calc_A_dim\l_calc_B_dim\muskip_gset:Nn
}
\def_new:Npn\calc_muskip_add:Nn{
  \calc_assign_generic:NNNNNn\c_three\g_calc_A_dim\l_calc_B_dim\muskip_add:Nn
}
\def_new:Npn\calc_muskip_gadd:Nn{
  \calc_assign_generic:NNNNNn\c_three\g_calc_A_dim\l_calc_B_dim\muskip_gadd:Nn
}
\def_new:Npn\calc_muskip_sub:Nn{
  \calc_assign_generic:NNNNNn\c_three\g_calc_A_dim\l_calc_B_dim\muskip_add:Nn
}
\def_new:Npn\calc_muskip_gsub:Nn{
  \calc_assign_generic:NNNNNn\c_three\g_calc_A_dim\l_calc_B_dim\muskip_gadd:Nn
}
\def_new:Npn \calc_pre_scan:N #1{
  \if_meaning:NN(#1
    \exp_after:NN\calc_open:w
  \else:
    \if_meaning:NN \calc_textsize:Nn #1
    \else:
      \if_meaning:NN \calc_maxmin_operation:Nnn #1
      \else:
        \calc_numeric:
      \fi:
    \fi:
  \fi:
  #1}
\def_new: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
}
\def_new:Npn\calc_init_B:{\l_calc_B_register\g_calc_A_register}
\def_new:Npn\calc_numeric:{
  \tex_afterassignment:D\calc_post_scan:N
  \pref_global:D\g_calc_A_register
}
\def_new: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}
\def_new:Npn\calc_post_scan:N#1{
  \if_meaning:NN#1!\let:NN\calc_next:w\group_end: \else:
    \if_meaning:NN#1+\let:NN\calc_next:w\calc_add: \else:
      \if_meaning:NN#1-\let:NN\calc_next:w\calc_subtract: \else:
        \if_meaning:NN#1*\let:NN\calc_next:w\calc_multiply:N \else:
          \if_meaning:NN#1/\let:NN\calc_next:w\calc_divide:N \else:
            \if_meaning:NN#1)\let:NN\calc_next:w\calc_close: \else:
              \let:NN \calc_next:w \scan_stop:
              \calc_error:N#1
            \fi:
          \fi:
        \fi:
      \fi:
    \fi:
  \fi:
  \calc_next:w}
\def_new:Npn \calc_multiply:N #1{
  \if_meaning:NN \calc_maxmin_operation:Nnn #1
    \let:NN \calc_next:w \calc_maxmin_multiply:
  \else:
    \if_meaning:NN \calc_ratio_multiply:nn #1
      \let:NN \calc_next:w \calc_ratio_multiply:nn
    \else:
      \if_meaning:NN \calc_real_evaluate:nn #1
        \let:NN \calc_next:w \calc_real_multiply:n
      \else:
        \def:Npn \calc_next:w{\calc_multiply: #1}
      \fi:
    \fi:
  \fi:
  \calc_next:w
}
\def_new:Npn \calc_divide:N #1{
  \if_meaning:NN \calc_maxmin_operation:Nnn #1
    \let:NN \calc_next:w \calc_maxmin_divide:
  \else:
    \if_meaning:NN \calc_ratio_multiply:nn #1
      \let:NN \calc_next:w \calc_ratio_divide:nn
    \else:
      \if_meaning:NN \calc_real_evaluate:nn #1
        \let:NN \calc_next:w \calc_real_divide:n
      \else:
        \def:Npn \calc_next:w{\calc_divide: #1}
      \fi:
    \fi:
  \fi:
  \calc_next:w
}
\def_new: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}
\def_new:Npn\calc_add:{\calc_generic_add_or_subtract:N\calc_add_A_to_B:}
\def_new:Npn\calc_subtract:{
  \calc_generic_add_or_subtract:N\calc_subtract_A_from_B:}
\def_new: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:
}
\def_new: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:
}
\def_new:Npn\calc_generic_multiply_or_divide:N#1{
  \group_end:
  \group_begin:
  \let:NN\g_calc_A_register\g_calc_A_int
  \let:NN\l_calc_B_register\l_calc_B_int
  \group_execute_after:N#1\calc_pre_scan:N
}
\def_new: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:
}
\def_new: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:
}
\def_new:Npn\calc_multiply:{
  \calc_generic_multiply_or_divide:N\calc_multiply_B_by_A:}
\def_new:Npn\calc_divide:{
  \calc_generic_multiply_or_divide:N\calc_divide_B_by_A:}
\def_long_new:Npn \calc_calculate_box_size:nnn #1#2#3{
  \hbox_set:Nn \l_tmpa_box {{#3}}
  #2{\c_zero_dim \tlist_map_function:nN{#1}\calc_calculate_box_size_aux:n}
}
\def:Npn \calc_calculate_box_size_aux:n#1{ + #1\l_tmpa_box}
\def_protected_long:Npn \calc_textsize:Nn#1#2{
  \group_begin:
  \let:NN\widthof\box_wd:N
  \let:NN\heightof\box_ht:N
  \let:NN\depthof\box_dp:N
  \def:Npn\totalheightof{\box_ht:N\box_dp:N}
  \exp_args:No\calc_calculate_box_size:nnn{#1}
  {\dim_gset:Nn\g_calc_A_register}
  {
    \let:NN \depthof\calc_depthof:n
    \let:NN \widthof\calc_widthof:n
    \let:NN \heightof\calc_heightof:n
    \let:NN \totalheightof\calc_totalheightof:n
    #2
  }
  \group_end:
  \calc_post_scan:N
}
\def_protected_long: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:
  \gdef: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}
\def_long_new:Npn \calc_ratio_divide:nn#1#2{\calc_ratio_multiply:nn{#2}{#1}}
\def_protected_new: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}
\def_new:Npn \calc_real_multiply:n #1{\calc_real_evaluate:nn{#1}{1}}
\def_new:Npn \calc_real_divide:n {\calc_real_evaluate:nn{1}}
\def_protected_long:Npn\calc_maxmin_operation:Nnn#1#2#3{
  \group_begin:
  \calc_maxmin_generic:Nnn#1{#2}{#3}
  \group_end:
  \calc_post_scan:N
}
\def_protected_long_new: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:
}
\def_long_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
}
\def_new:Npn\calc_maxmin_multiply:{
  \calc_maxmin_div_or_mul:NNnn\calc_multiply_B_by_A:}
\def_new:Npn\calc_maxmin_divide:  {
  \calc_maxmin_div_or_mul:NNnn\calc_divide_B_by_A:}
\def_new:Npn\calc_error:N#1{
  \PackageError{calc}
  {`\token_to_string:N#1'~ invalid~ at~ this~ point}
  {I~ expected~ to~ see~ one~ of:~ +~ -~ *~ /~ )}
}
\def_long_new:Npn \calc_maxof:nn#1#2{
  \calc_maxmin_operation:Nnn > \exp_not:n{{#1}{#2}}
}
\def_long_new:Npn \calc_minof:nn#1#2{
  \calc_maxmin_operation:Nnn < \exp_not:n{{#1}{#2}}
}
\let_new:NN \maxof \calc_maxof:nn
\let_new:NN \minof \calc_minof:nn
\def_long_new:Npn \calc_widthof:n#1{
  \calc_textsize:Nn \exp_not:N\widthof\exp_not:n{{#1}}
}
\def_long_new:Npn \calc_heightof:n#1{
  \calc_textsize:Nn \exp_not:N\heightof\exp_not:n{{#1}}
}
\def_long_new:Npn \calc_depthof:n#1{
  \calc_textsize:Nn \exp_not:N\depthof\exp_not:n{{#1}}
}
\def_long_new:Npn \calc_totalheightof:n#1{
  \calc_textsize:Nn \exp_not:N\totalheightof\exp_not:n{{#1}}
}
\let:NN \depthof\calc_depthof:n
\let:NN \widthof\calc_widthof:n
\let:NN \heightof\calc_heightof:n
\let:NN \totalheightof\calc_totalheightof:n
\def_long_new:Npn \calc_ratio:nn#1#2{
  \calc_ratio_multiply:nn\exp_not:n{{#1}{#2}}}
\let_new:NN \calc_real:n \calc_real_evaluate:nn
\let_new:NN \ratio\calc_ratio:nn
\let_new:NN \real\calc_real:n
%% 
%%
%% End of file `l3calc.sty'.
