In an earlier post I asked a question about writing a flexible derivative macro, and someone suggested that a LaTeX3 version might be easier to understand, so I decided to try my hand at writing one. Unfortunately, I ran into some problems. First, I had trouble getting started with implementing the functionality to sum the numerical derivative orders. In particular, I got an error when I tried adding the command \@tempcnta\z@
to the clean-up portion of my macro. Since my LaTeX knowledge is extremely limited, I don't now another way to add up the numerical derivative orders. I also tried wrapping the command in \ExplSyntaxOff
and \ExplSyntaxOn
, but this didn't help. Second, the command sometimes requires more braces than I would like. I think the commented example below is a reasonable usage. However, the implementation does not support this, and requires an extra set of braces (as shown immediately below the commented example). I think the basic functionality is there (I'll mostly use the command as shown in the first example), but it'd be nice to get the extra features (summing the numerical derivative orders and eliminating the need for extra braces).
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
% allocate variables to typeset the derivative
\tl_new:N \l_myderivative_num_exp_tl
\tl_new:N \l_myderivative_den_tl
\tl_new:N \l_myderivative_den_factor_var_flag_tl
\tl_new:N \l_myderivative_den_factor_exp_tl
% function to write the derivative
\NewDocumentCommand{\derivative}{m>{\SplitList,}m}
{
% clear any old values
\tl_clear:N \l_myderivative_num_exp_tl
\tl_clear:N \l_myderivative_num_exp_flag_tl
\tl_clear:N \l_myderivative_den_tl
\tl_clear:N \l_myderivative_den_factor_var_flag_tl
\tl_clear:N \l_myderivative_den_factor_exp_flag_tl
% format the denominator
\tl_map_inline:nn { #2 }
{
\myderivative_add_den_factor:n { ##1 }
}
% write the derivative
\frac
{
\partial
\tl_if_empty:NF \l_myderivative_num_exp_flag_tl
{
^{\l_myderivative_num_exp_tl}
}
#1
}
{
\l_myderivative_den_tl
}
}
% helper function to process a factor in the denominator
\cs_new_protected:Npn \myderivative_add_den_factor:n #1
{
% clear the variables
\tl_clear:N \l_myderivative_den_factor_var_flag_tl
\tl_clear:N \l_myderivative_den_factor_exp_tl
\tl_if_empty:NF \l_myderivative_den_tl
{
% add a thin space if we've already processed at least one factor
\tl_put_right:Nn \l_myderivative_den_tl { \, }
}
% format the factor
\tl_map_inline:nn { #1 }
{
\myderivative_fmt_den_factor:n { ##1 }
}
% check for an implicit exponent
\tl_if_empty:NT \l_myderivative_den_factor_exp_flag_tl
{
\tl_if_empty:NF \l_myderivative_num_exp_tl
{
\tl_put_right:Nn \l_myderivative_num_exp_flag_tl { 1 }
\tl_put_right:Nn \l_myderivative_num_exp_tl { + }
}
\tl_put_right:Nn \l_myderivative_num_exp_tl { 1 }
}
}
% helper function to format a factor in the denominator
\cs_new_protected:Npn \myderivative_fmt_den_factor:n #1
{
\tl_if_empty:NTF \l_myderivative_den_factor_var_flag_tl
{
% if the flag is not set, then we are processing the variable
\tl_put_right:Nn \l_myderivative_den_tl { \partial #1 }
% set the flag
\tl_put_right:Nn \l_myderivative_den_factor_var_flag_tl { 1 }
}
{
% if the flag is set, then we are processing the exponent
\tl_put_right:Nn \l_myderivative_den_tl { ^{#1} }
% update the numerator exponent
\tl_if_empty:NF \l_myderivative_num_exp_tl
{
\tl_put_right:Nn \l_myderivative_num_exp_tl { + }
}
\tl_put_right:Nn \l_myderivative_num_exp_tl { #1 }
% set the flag
\tl_put_right:Nn \l_myderivative_den_factor_exp_flag_tl { 1 }
\tl_put_right:Nn \l_myderivative_num_exp_flag_tl { 1 }
}
}
\ExplSyntaxOff
\begin{document}
\[
\derivative{f}{xp,yq,zr}
\]
\[
\derivative{f}{x2,y3,z4}
\]
\[
\derivative{f}{x}
\]
\[
\derivative{f}{{\hat{x}}{2},{\tilde{y}}{3}}
\]
%\[
% \derivative{f}{{\hat{x}}}
%\]
\[
\derivative{f}{{{\hat{x}}}}
\]
\end{document}