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}}}}
}
}
  • 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
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

  • 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
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}
  • 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 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.