I've been introduced recently to expl3 syntaxe using xparse package. This thing is wonderfull and helped me a lot. The thing is that my document class is now hybrid and I kindda need to use some of the new possibilities I have for one of my old fonction that is way too packed with too many \expandfter
that I never really succeed to understand right. (in oposition to the new syntax which is more readable for me). So in a learning perspective and in the goal of being able to make my class more fit for use in it's new context, I would like to convert this old function
\makeatletter
\newcommand{\WIT}[3]%
{
\ifcsname Total#1\endcsname
\relax
\else
\expandafter\def\csname#1Contents\endcsname{}%
\expandafter\def\csname#1ContentsWCost\endcsname{}%
\expandafter\pgfmathsetmacro\csname Total#1\endcsname{0}%
\pgfmathsetmacro\TotalContractH{0.0}%
\pgfmathsetmacro\TotalContractC{0.0}%
\expandafter\def\csname#1\endcsname##1##2
{
\pgfkeys{/pgf/fpu=true}%
\expandafter\pgfmathsetmacro\csname Total#1\endcsname{\csname Total#1\endcsname + ##2}%
\pgfmathsetmacro\TotalContractH{\TotalContractH + ##2}
\countCost{##2}{#3}
\pgfkeys{/pgf/fpu=false}
\pgfkeys{/pgf/fpu=true}
\pgfmathsetmacro\TotalContractC{\TotalContractC + \costRes}
\pgfkeys{/pgf/fpu=false}
\expandafter\g@addto@macro\csname#1ContentsWCost\endcsname{##1&\showTime{##2}&\countCost{##2}{#3}\showCost{\costRes}\\}%
\expandafter\g@addto@macro\csname#1Contents\endcsname{##1&\showTime{##2}\\}%
}%
\expandafter\def\csname#1TableNC\endcsname{\WITtableNC{#1}{#2}{\csname#1Contents\endcsname}{#3}}%
\g@addto@macro\SummaryTableNoCost{\csname#1Table\endcsname}%
\expandafter\def\csname#1TableWC\endcsname{\WITtableWC{#1}{#2}{\csname#1ContentsWCost\endcsname}{#3}}%
\g@addto@macro\SummaryTableWCost{\csname#1Table\endcsname}%
\expandafter\def\csname#1Table\endcsname{
\ifShowCost
\csname#1TableWC\endcsname
\else
\csname#1TableNC\endcsname
\fi
}%
}
\makeatother
\newcommand{\countCost}[2]{
\pgfkeys{/pgf/fpu=true}
\pgfmathsetmacro\costRes{#1 * #2}
\pgfkeys{/pgf/fpu=false}
}
\newcommand{\showCost}[1]{
\pgfkeys{/pgf/fpu=true}
\pgfmathprintnumber[cashnumber]{#1} \$%
\pgfkeys{/pgf/fpu=false}
}
\newcommand{\showTime}[1]{
\pgfkeys{/pgf/fpu=true}
\showTotalTime{#1}%
\pgfkeys{/pgf/fpu=false}
}
\newcommand{\showTotalTime}[1]{
\pgfmathprintnumber[hournumber]{#1} h%
}
into somehting more flexible.
This is what I got so far:
\ExplSyntaxOn
\fp_new:N \TotalContractH %Total Contract Hours
\fp_new:N \TotalContractC %Total Contract Cost
\tl_new:N \SummaryTableNoCost %Summary Table without the Cost
\tl_new:N \SummaryTableWCost %Summary Table with the Cost
\NewDocumentCommand{\WIT}{m m m}{ %type desc rate
\ifcsname Total#1\endcsname
\relax
\else
\fp_new:N \csname Total#1\endcsname
\tl_new:N \csname#1Contents\endcsname
\tl_new:N \csname#1ContentsWCost\endcsname
\NewDocumentCommand{\csname#1\endcsname}{o m m}{ %[groupe] desc time
\fp_add:Nn \csname Total#1\endcsname {##3}
\fp_add:Nn \TotalContractH {##3}
\fp_add:Nn \TotalContractC {(##3 * #3)}
\tl_put_right:Nx \csname#1ContentsWCost\endcsname {
##2&\pgfmathprintnumber[hournumber]{##3}&\pgfmathprintnumber[cashnumber]{\fp_eval:n {##3 * #3}}\\
}%
\tl_put_right:Nx \csname#1Contents\endcsname {
##2&\pgfmathprintnumber[hournumber]{##3}\\
}%
\cs_new:Npn \csname#1TableNC\endcsname{}{\WITtableNC{#1}{#2}{\csname#1Contents\endcsname}{#3}}%
\tl_put_right:Nx \SummaryTableNoCost{\csname#1TableNC\endcsname}%
\cs_new:Npn \csname#1TableWC\endcsname{}{\WITtableWC{#1}{#2}{\csname#1ContentsWCost\endcsname}{#3}}%
\tl_put_right:Nx \SummaryTableWCost{\csname#1TableWC\endcsname}%
\NewDocumentCommand{\csname#1Table\endcsname}{}{
\ifShowCost
\csname#1TableWC\endcsname
\else
\csname#1TableNC\endcsname
\fi
}%
}
\fi
}
\ExplSyntaxOff
of course, that thing doesn't work for 3 main reasons:
- I'm really bad with the
\expandafter
and I probably messed around trying to figure out what was happening here - I'm way too new to the expl3 syntax. I try my best, but I'm probably missing something.
- I'm not even sure that I can use the
csname
definition like this in the expl syntax.
Thanks in advance,
EDIT: Here a fully testable document
\documentclass[letterpaper, 12pt]{article}
\usepackage{xparse} %LaTeX3 enabled
\RequirePackage{lmodern}
\RequirePackage{graphicx}
\RequirePackage[french]{babel}%
\usepackage{relsize}
\usepackage[margin=12mm]{geometry}
\usepackage{ifluatex, ifxetex}
\newif\ifxetexorluatex
\ifxetex
\xetexorluatextrue
\else
\ifluatex
\xetexorluatextrue
\else
\xetexorluatexfalse
\fi\fi
\ifxetexorluatex
\usepackage{fontspec}
\setmainfont{Calibri}
\setsansfont{Arial}
\setmonofont{Liberation Mono}
\else
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\fi
\usepackage{tabularx}
\usepackage[table]{xcolor}
\usepackage{array}
\usepackage{enumitem}
\usepackage{float}
\usepackage{parskip}
\usepackage{pgfplots,tikz}
\usepackage{hyperref}
\hypersetup{%
pdfencoding=auto,
pdfauthor={yourself},
}
\RequirePackage{etoolbox}
\usepackage{framed}
\ifxetexorluatex
\usepackage{dtk-logos}
\hologoFontSetup {general=\fontspec{Times New Roman}}
\renewcommand{\TeX}{\hologo{TeX}}
\newcommand{\TeXStudio}{{\fontspec{Times New Roman}\hologo{TeX}Studio}}
\fi
%%%%%%%%%%%%%%%%%
% WorkItem Types
%%%%%%%%%%%%%%%%%
\newcommand{\countCost}[2]{
\pgfkeys{/pgf/fpu=true}
\pgfmathsetmacro\costRes{#1 * #2}
\pgfkeys{/pgf/fpu=false}
}
\newcommand{\showCost}[1]{
\pgfkeys{/pgf/fpu=true}
\pgfmathprintnumber[cashnumber]{#1} \$%
\pgfkeys{/pgf/fpu=false}
}
\newcommand{\showTime}[1]{
\pgfkeys{/pgf/fpu=true}
\showTotalTime{#1}%
\pgfkeys{/pgf/fpu=false}
}
\newcommand{\showTotalTime}[1]{
\pgfmathprintnumber[hournumber]{#1} h%
}
%http://tex.stackexchange.com/questions/360031/trying-to-create-dynamic-table-and-commands-alltogether
\newcommand\SummaryTableNoCost{}%
\newcommand\SummaryTableWCost{}%
\newif\ifShowCost
\ShowCosttrue
\newcommand\SummaryTable{
\ifShowCost
\SummaryTableWCost
\else
\SummaryTableNoCost
\fi
}%
\makeatletter
\newcommand{\WIT}[3]%
{
\ifcsname Total#1\endcsname
\relax
\else
\expandafter\def\csname#1Contents\endcsname{}%
\expandafter\def\csname#1ContentsWCost\endcsname{}%
\expandafter\pgfmathsetmacro\csname Total#1\endcsname{0}%
\pgfmathsetmacro\TotalContractH{0.0}%
\pgfmathsetmacro\TotalContractC{0.0}%
\expandafter\def\csname#1\endcsname##1##2
{
\pgfkeys{/pgf/fpu=true}%
\expandafter\pgfmathsetmacro\csname Total#1\endcsname{\csname Total#1\endcsname + ##2}%
\pgfmathsetmacro\TotalContractH{\TotalContractH + ##2}
\countCost{##2}{#3}
\pgfkeys{/pgf/fpu=false}
\pgfkeys{/pgf/fpu=true}
\pgfmathsetmacro\TotalContractC{\TotalContractC + \costRes}
\pgfkeys{/pgf/fpu=false}
\expandafter\g@addto@macro\csname#1ContentsWCost\endcsname{##1&\showTime{##2}&\countCost{##2}{#3}\showCost{\costRes}\\}%
\expandafter\g@addto@macro\csname#1Contents\endcsname{##1&\showTime{##2}\\}%
}%
\expandafter\def\csname#1TableNC\endcsname{\WITtableNC{#1}{#2}{\csname#1Contents\endcsname}{#3}}%
\g@addto@macro\SummaryTableNoCost{\csname#1Table\endcsname}%
\expandafter\def\csname#1TableWC\endcsname{\WITtableWC{#1}{#2}{\csname#1ContentsWCost\endcsname}{#3}}%
\g@addto@macro\SummaryTableWCost{\csname#1Table\endcsname}%
\expandafter\def\csname#1Table\endcsname{
\ifShowCost
\csname#1TableWC\endcsname
\else
\csname#1TableNC\endcsname
\fi
}%
}
\makeatother
\newcolumntype{L}[1]{>{\raggedright\let\newline\\\arraybackslash\hspace{0pt}}m{#1}}
\newcolumntype{C}[1]{>{\centering\let\newline\\\arraybackslash\hspace{0pt}}m{#1}}
\newcolumntype{R}[1]{>{\raggedleft\let\newline\\\arraybackslash\hspace{0pt}}m{#1}}
\newcommand\WITtableWC[4]%
{
\vbox{
\begin{flushleft}
\textbf{#2:} (#4 \$/h)
\end{flushleft}
\rowcolors{1}{white}{cyan!10}
\begin{tabularx}{\textwidth}{|X|r|R{3cm}|}
\hline\rowcolor{lightgray}
Description & \iflanguage{french}{Temps Estimé}{Estimated Hours} & \iflanguage{french}{Coût}{Cost}\hspace{5mm}\\
\hline
#3
\hline\rowcolor{lightgray}
Total #2 & \pgfmathprintnumber[hournumber]{\csname Total#1\endcsname} h & \countCost{\csname Total#1\endcsname}{#4}\showCost{\costRes}\\
\hline
\end{tabularx}\\
}
}
\newcommand\WITtableNC[4]%
{
\vbox{
\begin{flushleft}
\textbf{#2:}
\end{flushleft}
\rowcolors{1}{white}{cyan!10}
\begin{tabularx}{\textwidth}{|X|r|}
\hline\rowcolor{lightgray}
Description & \iflanguage{french}{Temps Estimé}{Estimated Hours}\\
\hline
#3
\hline\rowcolor{lightgray}
Total #2 & \pgfmathprintnumber[hournumber]{\csname Total#1\endcsname} h\\
\hline
\end{tabularx}\\
}
}
\iflanguage{french}{
\pgfkeys{
/pgf/number format/cashnumber/.style={
fixed,
use comma,
fixed zerofill,
precision=0,
1000 sep={\ },
},
/pgf/number format/hournumber/.style={
use comma,
fixed,
precision=2,
1000 sep={\ },
},
}
}{
\pgfkeys{
/pgf/number format/cashnumber/.style={
fixed,
fixed zerofill,
precision=0,
1000 sep={,},
},
/pgf/number format/hournumber/.style={
fixed,
precision=2,
1000 sep={,},
},
}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\WIT{dev}{Development}{30}
\WIT{other}{Other activities}{20}
\other{somehting}{8}
\other{other thing}{24}
\dev{GUI}{4}
\dev{BackEnd}{16}
\begin{document}
\SummaryTable
\end{document}
EDIT 2 (Final Version):
After the comments from egreg and some manipulation to be able to do what I wanted, here is my final resolved result
\documentclass[letterpaper, 12pt]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[english]{babel}
\usepackage[top=5mm,left=35mm,bottom=5mm,right=35mm]{geometry}
\usepackage{xparse} %LaTeX3 enabled
\usepackage{tabularx}
\usepackage[table]{xcolor}
\usepackage{array}
\usepackage{tikz}
%%%%%%%%%%%%%%%%%
% WorkItem Types
%%%%%%%%%%%%%%%%%
%https://tex.stackexchange.com/questions/370008/conversion-of-old-code-to-expl3-notation/
\ExplSyntaxOn
\NewDocumentCommand{\showCost}{m}{%
\pgfmathprintnumber[cashnumber]{#1}~\$%
}
\NewDocumentCommand{\showTime}{m}{%
\pgfmathprintnumber[hournumber]{#1}~h%
}
\NewDocumentCommand{\WITOptGrp}{mom}{
\cs_if_exist:cF { g_hikari_group_#1_contents_tl }{
\tl_new:c { g_hikari_group_#1_contents_tl }
\tl_new:c { g_hikari_group_#1_contents_with_cost_tl }
\fp_new:c { g_hikari_witgroup_#1_totaltime_fp }
\fp_new:c { g_hikari_witgroup_#1_totalcost_fp }
\cs_new:cpn { group #1 TableNC }
{
\WITGrouptableNC{#1}{#3}{\tl_use:c { g_hikari_group_#1_contents_tl }}{#2}
}
\cs_new:cpn { group #1 TableWC }
{
\WITGrouptableWC{#1}{#3}{\tl_use:c { g_hikari_group_#1_contents_with_cost_tl }}{#2}
}
\cs_new:cpn { group #1 Table }
{
\bool_if:NTF \g_hikari_wit_showcost_bool
{ \use:c { group #1 TableWC } }
{ \use:c { group #1 TableNC } }
}
\tl_gput_right:Nn \g_hikari_group_summary_table_no_cost_tl { \use:c { group #1 TableNC } }
\tl_gput_right:Nn \g_hikari_group_summary_table_with_cost_tl { \use:c { group #1 TableWC } }
}
}
\NewDocumentCommand\WITGrouptableWC{m m m m}
{
\par\addvspace{\medskipamount}\noindent
\begin{minipage}{\textwidth}
\raggedright
\textbf{\IfNoValueTF{#4}{#2}{#4}}\par\medskip
\rowcolors[\hline]{1}{cyan!10}{white}
\begin{tabularx}{\textwidth}{|X|r|r|R{3cm}|}
\hline\rowcolor{lightgray}
Description &
\iflanguage{french}{Temps~Estimé}{Estimated~Hours} &
\iflanguage{french}{Taux~Horraire}{Rate} &
\iflanguage{french}{Coût}{Cost}\hspace{5mm}\\
\hline
#3
\hline\rowcolor{lightgray}
Total~#2 &
\showTime{\fp_use:c { g_hikari_witgroup_#1_totaltime_fp } } &
~ &
\showCost{\fp_use:c { g_hikari_witgroup_#1_totalcost_fp } } \\
\hline
\end{tabularx}
\end{minipage}
}
\NewDocumentCommand\WITGrouptableNC{m m m m}
{
\par\addvspace{\medskipamount}\noindent
\begin{minipage}{\textwidth}
\raggedright
\textbf{\IfNoValueTF{#4}{#2}{#4}}\par\medskip
\rowcolors[\hline]{1}{cyan!10}{white}
\begin{tabularx}{\textwidth}{|X|r|}
\hline\rowcolor{lightgray}
Description & \iflanguage{french}{Temps Estimé}{Estimated Hours}\\
\hline
#3
\hline\rowcolor{lightgray}
Total~#2 & \showTime{\fp_use:c { g_hikari_witgroup_#1_totaltime_fp }} \\
\hline
\end{tabularx}
\end{minipage}
}
\NewDocumentCommand{\WIT}{mmm}
{
\cs_if_exist:cF { #1 }
{
\tl_new:c { g_hikari_wit_#1_contents_tl }
\tl_new:c { g_hikari_wit_#1_contents_with_cost_tl }
\fp_new:c { g_hikari_wit_#1_totaltime_fp }
\fp_new:c { g_hikari_wit_#1_totalcost_fp }
\exp_args:Nc \NewDocumentCommand { #1 } {mmD<>{default}o}
{
\WITOptGrp{##3}{##4}
\fp_gadd:cn { g_hikari_wit_#1_totaltime_fp } { ##2 }
\fp_gadd:cn { g_hikari_wit_#1_totalcost_fp } { ##2 * #3 }
\fp_gadd:cn { g_hikari_witgroup_##3_totaltime_fp } { ##2 }
\fp_gadd:cn { g_hikari_witgroup_##3_totalcost_fp } { ##2 * #3 }
\tl_gput_right:cn { g_hikari_wit_#1_contents_with_cost_tl }
{
##1 \IfNoValueF{##4}{~(##4)} & \showTime{##2} & \showCost{\fp_eval:n { ##2 * #3 }} \\
}
\tl_gput_right:cn { g_hikari_wit_#1_contents_tl } { ##1 \IfNoValueF{##4}{~(##4)} & \showTime{##2} \\ }
\tl_gput_right:cn { g_hikari_group_##3_contents_tl }{ ##1 ~ (#2) & \showTime{##2} \\ }
\tl_gput_right:cn { g_hikari_group_##3_contents_with_cost_tl }
{
##1 ~ (#2) & \showTime{##2} & #3 ~\$/h & \showCost{\fp_eval:n { ##2 * #3 }} \\
}
}
\cs_new:cpn { #1 TableNC }
{
\WITtableNC{#1}{#2}{\tl_use:c { g_hikari_wit_#1_contents_tl }}
}
\cs_new:cpn { #1 TableWC }
{
\WITtableWC{#1}{#2}{\tl_use:c { g_hikari_wit_#1_contents_with_cost_tl }}{#3}
}
\tl_gput_right:Nn \g_hikari_wit_summary_table_no_cost_tl { \use:c { #1 TableNC } }
\tl_gput_right:Nn \g_hikari_wit_summary_table_with_cost_tl { \use:c { #1 TableWC } }
\cs_new:cpn { #1 Table }
{
\bool_if:NTF \g_hikari_wit_showcost_bool
{ \use:c { #1 TableWC } }
{ \use:c { #1 TableNC } }
}
}
}
\NewDocumentCommand\SummaryTable{}
{
\bool_if:NTF \g_hikari_wit_showcost_bool
{ \tl_use:N \g_hikari_wit_summary_table_with_cost_tl }
{ \tl_use:N \g_hikari_wit_summary_table_no_cost_tl }
}
\NewDocumentCommand\SummaryTableByOpt{}
{
\bool_if:NTF \g_hikari_wit_showcost_bool
{ \tl_use:N \g_hikari_group_summary_table_with_cost_tl }
{ \tl_use:N \g_hikari_group_summary_table_no_cost_tl }
}
\NewDocumentCommand{\ShowCostTrue}{}
{
\bool_gset_true:N \g_hikari_wit_showcost_bool
}
\NewDocumentCommand{\ShowCostFalse}{}
{
\bool_gset_false:N \g_hikari_wit_showcost_bool
}
\bool_new:N \g_hikari_wit_showcost_bool
\tl_new:N \g_hikari_wit_summary_table_with_cost_tl
\tl_new:N \g_hikari_wit_summary_table_no_cost_tl
\tl_new:N \g_hikari_group_summary_table_with_cost_tl
\tl_new:N \g_hikari_group_summary_table_no_cost_tl
\NewDocumentCommand\WITtableWC{m m m m}
{
\par\addvspace{\medskipamount}\noindent
\begin{minipage}{\textwidth}
\raggedright
\textbf{#2:}~(#4 \$/h)\par\medskip
\rowcolors[\hline]{1}{cyan!10}{white}
\begin{tabularx}{\textwidth}{|X|r|R{3cm}|}
\hline\rowcolor{lightgray}
Description &
\iflanguage{french}{Temps~Estimé}{Estimated~Hours} &
\iflanguage{french}{Coût}{Cost}\hspace{5mm}\\
\hline
#3
\hline\rowcolor{lightgray}
Total~#2 &
\showTime{ \fp_use:c { g_hikari_wit_#1_totaltime_fp } } &
\showCost{ \fp_use:c { g_hikari_wit_#1_totalcost_fp } } \\
\hline
\end{tabularx}
\end{minipage}
}
\NewDocumentCommand\WITtableNC{m m m}
{
\par\addvspace{\medskipamount}\noindent
\begin{minipage}{\textwidth}
\raggedright
\textbf{#2:}\par\medskip
\rowcolors[\hline]{1}{cyan!10}{white}
\begin{tabularx}{\textwidth}{|X|r|}
\hline\rowcolor{lightgray}
Description & \iflanguage{french}{Temps Estimé}{Estimated Hours}\\
\hline
#3
\hline\rowcolor{lightgray}
Total~#2 & \showTime{ \fp_use:c { g_hikari_wit_#1_totaltime_fp }} \\
\hline
\end{tabularx}
\end{minipage}
}
\ExplSyntaxOff
\newcolumntype{L}[1]{>{\raggedright\let\newline\\\arraybackslash\hspace{0pt}}m{#1}}
\newcolumntype{C}[1]{>{\centering\let\newline\\\arraybackslash\hspace{0pt}}m{#1}}
\newcolumntype{R}[1]{>{\raggedleft\let\newline\\\arraybackslash\hspace{0pt}}m{#1}}
\iflanguage{french}{
\pgfkeys{
/pgf/number format/cashnumber/.style={
fixed,
use comma,
fixed zerofill,
precision=0,
1000 sep={\ },
},
/pgf/number format/hournumber/.style={
use comma,
fixed,
precision=2,
1000 sep={\ },
},
}
}{
\pgfkeys{
/pgf/number format/cashnumber/.style={
fixed,
fixed zerofill,
precision=0,
1000 sep={,},
},
/pgf/number format/hournumber/.style={
fixed,
precision=2,
1000 sep={,},
},
}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\WIT{dev}{Development}{30}
\WIT{other}{Other activities}{20}
\WITOptGrp{optB}[Forcing a long name for Option B]{Option B}
\other{something}{8}[Option A]
\other{other thing}{24}<optB>[Option B]
\other{wow}{2}<optC>[Option C]
\dev{GUI}{4}[Option A]
\dev{BackEnd}{16}<optB>[Option B]
\dev{Command Line}{8}<optC>[Option C]
\begin{document}
\ShowCostTrue
\SummaryTable
\vspace{1cm}
\SummaryTableByOpt
\vspace{2cm}
\ShowCostFalse
\SummaryTable
\vspace{1cm}
\SummaryTableByOpt
\end{document}
pgfmath
and useexpl3
alone.csname
, but with the readability ofexpl3
. When defining a new dynamic command, I want to be able to easily add a optional parameters, and more than anything, stop goofying around with theexpandafter
if possible