3

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}}}}
}
}
2
  • 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
    Commented Apr 28, 2015 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
    Commented Apr 28, 2015 at 5:28

2 Answers 2

3

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}

Output from first code sample

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:

Output from second code sample

3
  • 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
    Commented May 29, 2015 at 22:19
  • @alfC: I have edited my answer to address all three points.
    – Alex Ball
    Commented May 31, 2015 at 12:21
  • Thanks, I added a star variant to the command in the edit to my answer.
    – alfC
    Commented Jun 1, 2015 at 0:58
3

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}
11
  • 1
    I am little bit in a hurry, so I can not test any code. It's a proposition, not a full solution yet
    – user31729
    Commented Apr 28, 2015 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
    Commented Apr 28, 2015 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
    Commented Apr 28, 2015 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
    Commented Apr 28, 2015 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
    Commented May 21, 2015 at 19:17

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .