# Passing complicated argument patterns to a new command

I am using the nice changes package. Which basically provides three commands \added, \deleted and \replaced. Because of the structure and the fact that the optional arguments it takes, I think it is possible to simplify its use. I followed the xparse package documentation to see if I could create a command that simplifies the call.

Below is a MWE. I was able to create two version of the command, one that delete and one that replace depending on the number of argument. But I ran quickly out of steam.

In summary here are the mappings I would like to achieve by defining a new command \ME:

• \ME{deleted} maps to \deleted[id=Me]{deleted}
• \ME[added] maps to \added[id=Me]{added} (or at least equivalent to \ME[added]{})
• \ME[replacing]{replaced} maps to \replaced[id=Me]{replacing}{replaced}
• \ME[comment]{deleted} maps to \deleted[id=Me, remark={comment}]{deleted}
• \ME[comment][added] maps to \added[id=Me,remark={comment}]{added} (or equivalent to \ME[comment][added]{})
• \ME[comment][replacing]{replaced} maps to \replaced[id=Me, remark={comment}]{replacing}{replaced}.

MWE:

\documentclass{article}
\usepackage{changes}
\usepackage{xparse}

\definechangesauthor[name={MyName},color=blue]{ME}

\DeclareDocumentCommand \ME { o m }{%
\IfNoValueTF{#1}{
\deleted[id=ME]{#2}}{
\replaced[id=ME]{#1}{#2}
}
}

%\newcommand{\ME}[1]{\deleted[id=ME]{#1}} %ok

%\newcommand{\ME}[1][]{\added[id=ME]{#1}} % not working

\begin{document}

\added[id=ME,remark={added}]{added}

\deleted[id=ME,remark={deleted}]{deleted}

\replaced[id=ME,remark={replaced}]{replacing}{replaced}

\ME{aaa}       % ok
\ME[aaa]{bbb}  % ok
\ME[aaa]{}     % ok

\ME{remark}[aaa]{}

\end{document}


EDIT: Summary, so far. Thanks to @AxelBall and @ChristianHupfer I get this syntax, which is almost ideal (except for pure comments) with the implementation below:

\ME{addonly}

\ME{add}<deleted>

\ME<deleteonly>

\ME[addonlycommet]{addonly}

\ME[adddeletecomment]{add}<delete>

\ME[deleteonlycomment]<deleteonly>

text\ME[commentonly]


And finally the star variants, that add the id on the revision:

\ME*[deleteonlycomment]<deleteonly>


code:

\NewDocumentCommand{\ME}{sogd<>}{
\IfBooleanTF#1{
\IfNoValueTF{#2}{\IfNoValueTF{#3}{\IfNoValueF{#4}{\deleted[id=ME]{#4}}}{\IfNoValueTF{#4}{\added[id=ME]{#3}}{\replaced[id=ME]{#3}{#4}}}}{\IfNoValueTF{#3}{\IfNoValueTF{#4}{\added[id=ME,remark={#2}]{}}{\deleted[id=ME, remark={#2}]{#4}}}{\IfNoValueTF{#4}{\added[id=ME,remark={#2}]{#3}}{\replaced[id=ME, remark={#2}]{#3}{#4}}}}
}{
\IfNoValueTF{#2}{\IfNoValueTF{#3}{\IfNoValueF{#4}{\deleted{#4}}}{\IfNoValueTF{#4}{\added{#3}}{\replaced{#3}{#4}}}}{\IfNoValueTF{#3}{\IfNoValueTF{#4}{\added[remark={#2}]{}}{\deleted[remark={#2}]{#4}}}{\IfNoValueTF{#4}{\added[remark={#2}]{#3}}{\replaced[remark={#2}]{#3}{#4}}}}
}
}

• How should the command decide in the case \Me[something]{real arg} if something is the designed for the 2nd opt or as the 1st opt. You need another syntax, in my point of view. In addition, the omittance of {} as mandatory argument is very difficult to achieve. – user31729 Apr 28 '15 at 5:24
• @ChristianHupfer, good point. I think adding an empty argument would be a work around \Me[comment]{added}{} or \Me[][replacing]{replaced}. – alfC Apr 28 '15 at 5:28

## 2 Answers

Here we define a command \ME that takes three optional arguments:

\ME[optional comment]<deleted content>(added content)


Either or both of <deleted> and (added) must be given or the command does nothing (but no error/warning is raised).

(EDITED to correct replacing behaviour.)

\documentclass{standalone}
\usepackage{changes}
\usepackage{xparse}

\definechangesauthor[name={MyName},color=blue]{ME}

\NewDocumentCommand{\ME}{od<>d()}{%
\IfNoValueTF{#1}{%
\IfNoValueTF{#2}{%
\IfNoValueF{#3}{%
% (#3)
\added[id=ME]{#3}%
}%
}{%
\IfNoValueTF{#3}{%
% <#2>
\deleted[id=ME]{#2}%
}{% <#2>(#3)
\replaced[id=ME]{#3}{#2}%
}%
}%
}{%
\IfNoValueTF{#2}{%
\IfNoValueF{#3}{%
% [#1](#3)
\added[id=ME,remark={#1}]{#3}%
}%
}{%
\IfNoValueTF{#3}{%
% [#1]<#2>
\deleted[id=ME, remark={#1}]{#2}%
}{% [#1]<#2>(#3)
\replaced[id=ME, remark={#1}]{#3}{#2}%
}%
}%
}%
}

\begin{document}

\begin{tabular}{ll}
\deleted[id=ME]{deleted}
& \ME<deleted> \\
\added[id=ME]{added}
& \ME(added) \\
\replaced[id=ME]{replacing}{replaced}
& \ME<replaced>(replacing)\\
\deleted[id=ME, remark={comment}]{deleted}
& \ME[comment]<deleted> \\
\added[id=ME,remark={comment}]{added}
& \ME[comment](added)\\
\replaced[id=ME, remark={comment}]{replacing}{replaced}
& \ME[comment]<replaced>(replacing)\\
\end{tabular}
\end{document}


In case you are concerned about using parentheses, don't be. xparse copes perfectly well if you use balanced parentheses inside the third argument; if you want an unbalanced one, wrap it in braces: \ME(like {(} this).

If you really want to use braces for the last argument, you can can use the g specifier:

\NewDocumentCommand{\ME}{od<>g}{...}


EDIT

Okay, this should do what you want:

\documentclass[border=12pt]{standalone}
\usepackage{changes}
\usepackage{xparse}

\definechangesauthor[name={MyName},color=blue]{ME}

\NewDocumentCommand{\ME}{ogd<>}{%
\IfNoValueTF{#1}{%
\IfNoValueTF{#2}{%
\IfNoValueF{#3}{%
% <#3>
\deleted[id=ME]{#3}%
}%
}{%
\IfNoValueTF{#3}{%
% {#2}
\added[id=ME]{#2}%
}{% {#2}<#3>
\replaced[id=ME]{#2}{#3}%
}%
}%
}{%
\IfNoValueTF{#2}{%
\IfNoValueTF{#3}{%
% [1]
\added[id=ME,remark={#1}]{}%
}{% [#1]<#3>
\deleted[id=ME, remark={#1}]{#3}%
}%
}{%
\IfNoValueTF{#3}{%
% [#1]{#2}
\added[id=ME,remark={#1}]{#2}%
}{% [#1]{#2}<#3>
\replaced[id=ME, remark={#1}]{#2}{#3}%
}%
}%
}%
}

\begin{document}

\begin{tabular}{ll}
\verb|\ME<deleted>|
& \ME<deleted> \\
\verb|\ME{added}|
& \ME{added} \\
\verb|\ME{added}<deleted>|
& \ME{added}<deleted>\\
\verb|\ME[comment]|
& \ME[comment]\\
\verb|\ME[comment]<deleted>|
& \ME[comment]<deleted> \\
\verb|\ME[comment]{added}|
& \ME[comment]{added}\\
\verb|\ME[comment]{added}<deleted>|
& \ME[comment]{added}<deleted>\\
\end{tabular}

\end{document}


Output:

• Great thanks something like this should be optional in changes, it simplifies writing changes a lot. Three things 1) I would like to have braces {...} for the second (added text) argument (currently <...>) not the third 2) is it possible to add \ME[comment] for a pure comment (translated to \added[remark={comment}]{} (or \ME[comment]{} if that is impossible) 3) in your code there is an inconsistency where the added and deleted are reversed when they are alone relative to the combined case (It took me a while to get it right) – alfC May 29 '15 at 22:19
• @alfC: I have edited my answer to address all three points. – Alex Ball May 31 '15 at 12:21
• Thanks, I added a star variant to the command in the edit to my answer. – alfC Jun 1 '15 at 0:58

This is uses in fact three optional arguments:

\ME[operation driver]<operation argument>[operation comment]


Any of them can be omitted, in this case nothing would happen.

\documentclass{article}
\usepackage{changes}
\usepackage{xstring}
\usepackage{xparse}

\definechangesauthor[name={MyName},color=blue]{ME}

\DeclareDocumentCommand \MEOrig{ o m }{%
\IfNoValueTF{#1}{
\deleted[id=ME]{#2}}{
\replaced[id=ME]{#1}{#2}
}
}

\DeclareDocumentCommand{\ME}{oD<>{}o}{%
\IfNoValueTF{#1}{%
\IfValueTF{#3}{%
\deleted[id=ME,remark={#3}]{#2}%
}{%
\deleted[id=ME]{#2}%
}%
}{%
\IfStrEq{#1}{added}{%
\IfValueTF{#2}{%
\IfValueTF{#3}{%
\added[id=ME,remark={#3}]{#2}%
}{%
\added[id=ME]{#2}%
}%
}{%
\IfValueTF{#3}{%
\added[id=ME,remark={#3}]{}%
}{%
\added[id=ME]{}%
}%
}%
}{%
\IfStrEq{#1}{replacing}{%
\IfValueTF{#3}{%
\replaced[id=ME,remark={#3}]{replacing}{#2}%
}{%
\replaced[id=ME]{replacing}{#2}%
}%
}{%
% Do nothing in here
}%
}% End of IfStrEq{#1}{added}
}% End of IfNoValueTF{#1}
}

\begin{document}

\added[id=ME,remark={added}]{added}

\deleted[id=ME,remark={deleted}]{deleted}

\replaced[id=ME,remark={replaced}]{replacing}{replaced}

\ME<aaa>       % ok
\ME[aaa]<bbb>  % ok
\ME[aaa]     % ok

\ME<remark>[aaa]

\end{document}

• I am little bit in a hurry, so I can not test any code. It's a proposition, not a full solution yet – user31729 Apr 28 '15 at 5:51
• Awesome, I didn't know that <> can also be used, perhaps in the light of it remarks can always go in <>, added/replacing in [] and deleted in {}. – alfC Apr 28 '15 at 5:56
• D is the delimited argument version (there is also d) which allows for basically any token (but not [] or {}, as far as I know). I am still thinking, if a key-value approach would not be even better, as wrapper around the different commands – user31729 Apr 28 '15 at 5:59
• A key/value approach is something that I also wanted to avoid to make changes as short as possible, and in particular not including any word that would make reading more difficult. That is why I wanted something that avoided the remark= keyword. – alfC Apr 28 '15 at 6:02
• I can't manage to use some of the combinations, For example \ME<deleted> \ME[remark deleted]<deleted> \ME[remark] \ME<deleted>[remark deleted]`. Out of the four commands, only 2 produce output. – alfC May 21 '15 at 19:17