An even more flexible derivative macro?

From the description, it seems like what you want is auto-detection of non-numerical input. That means you do not need \derivative* but can leave the decision to the code. Robustness could be an issue: in the following I've assume we have a single token for each index (that can be solved). As you've coded in 'traditional' LaTeX, I've stuck as far as possible to the same approach:

\documentclass[12pt]{article}
\makeatletter
\newcommand{\ifintegerTF}[1]{%
  \ifnum`#1<`0 %
    \expandafter\@secondoftwo
  \else
    \ifnum`#1>`9 %
      \expandafter\expandafter\expandafter\@secondoftwo
    \else
      \expandafter\expandafter\expandafter\@firstoftwo
    \fi  
  \fi
}
\newcommand{\derivative}[2]{%
  \begingroup
    \toks@{}%
    \@temptokena{}%
    \@tempcnta\z@
    \@tempswatrue
    \@for\@tempa:=#2\do{%
      \expandafter\derivative@aux@i\@tempa\stop
    }%
    \frac
      {%
        d%
        \if@tempswa
          \ifnum\@tempcnta>\@ne
            ^{\number\@tempcnta}%
          \fi
          #1%  
        \else
          #1%
          \ifnum\@tempcnta>\z@
            \toks@\expandafter\expandafter\expandafter
              {\expandafter\the\expandafter\toks@ \expandafter + \the\@tempcnta}%
          \fi
          ^{\expandafter\@gobble\the\toks@}%
        \fi
      }
      {\the\@temptokena}
  \endgroup
}
\newcommand{\derivative@aux}{}
\long\def\derivative@aux@i#1#2\stop{%
  \@temptokena\expandafter{\the\@temptokena \, d#1}%
  \ifx\\#2\\
    \advance\@tempcnta\@ne
  \else
    \def\@tempb{\@gobble}%
    \@for\@tempa:=#2\do{%
      \expandafter\derivative@aux@ii\@tempa{#1}%
    }%
   \@temptokena\expandafter\expandafter\expandafter
    {\expandafter\the\expandafter\@temptokena\expandafter^\expandafter{\@tempb}}% 
  \fi
}
\newcommand{\derivative@aux@ii}[2]{%
  \ifintegerTF{#1}
    {\advance\@tempcnta#1 }%
    {%
      \toks@\expandafter{\the\toks@ + #1}%
      \@tempswafalse
    }% 
  \protected@edef\@tempb{\@tempb + #1}%
}


\begin{document}

\[
    \derivative{x}{{y}{2},{z}{3}}
\]

\[
    \derivative{x}{{y}{m},{z}{n}}
\]

\[
    \derivative{x}{{v}{3},{w}{k,2},y,{z}{m}}
\]

\end{document}

The key idea is to set a flag to indicate that there are non-numerical index values, and use that flag to then determine how to construct the output.

(If there is interest, I think a LaTeX3 version of this will be somewhat more readable: we don't have an integer test there but the various expansion issues would be easier to solve.)


I think that LuaTeX is ideally suited for such tasks. Here is a proof of concept solution in ConTeXt (to translate to LuaLaTeX, you also need to port utilities.parsers.settings_to_array function; see util-prs.lua file in the ConTeXt tree for implementation details of this function)

\startluacode
  thirddata = thirddata or {}
  -- The pairs() iterator in lua does not guarantee the order in which 
  -- keys are accessed. So, instead of directly using settings_to_list
  -- I use a roundabout iterator.
  local settings_to_array = utilities.parsers.settings_to_array

  local format = string.format
  local split  = string.split

  function thirddata.partialD(settings)
      local list = settings_to_array(settings)

      local sum = 0
      local num = {}
      local den = {}

      for i = 1, #list do
         local s = split(list[i], "=")
         local key, value = s[1], s[2]

         local n = tonumber(value)

         if n ~= nil then
            sum = sum + n
         else
            num[#num + 1] = value
         end

         den[i] = format("\\partial %s^{%s}", key, value)
      end


      num[#num + 1] = sum
      num = table.concat(num, "+")
      den = table.concat(den)

      num  = format("\\partial^{%s}", num)


      context.dfrac( num, den)
  end
\stopluacode

\def\partialD%
  {\dosingleargument\dopartialD}

\unprotected\def\dopartialD[#1]{\ctxlua{thirddata.partialD(\!!bs#1\!!es)}}

\enablemode[lmmath]

\starttext
\startTEXpage[offset=3mm]
$\partialD[u=m, x=1, y=2, z=n]$
\stopTEXpage
\stoptext

which gives

enter image description here

Tags:

Macros