4

As stated elsewhere, it is usually quite recommended to use the starred \newcommand* instead of \newcommand since this helps finding missing }s by disallowing paragraphs in its argument. Every now and then, it is however desired to let such a command, e.g. \pdfmarkupcomment, act on (parts of) multiple paragraphs+. Is there any way to define an environment (say, pdfmarkedup, or can the environment share the command's name?) such that it automatically wraps each paragraph into the desired single-paragraph command? I.e.

\documentclass{article}
\usepackage{pdfcomment}
\newenvironment{pdfmarkedup}{%
    % insert magic here
}

\begin{document}
\begin{pdfmarkedup}[markup=Highlight]{no comment}
I'm a little paragraph short and stout.
Here is my last stop.

Here is my successor.
When I get all wrapped up,
Hear me shout!

Just write me down
and pour me out.

I'm a clever environment, yes it's true.
Here's an example of what I can do.
I can wrap my paragraphs each into a command.
Just put me around them and pour me out.
\end{pdfmarkedup}

\end{document}

should be equivalent to

\documentclass{article}
\usepackage{pdfcomment}
\begin{document}

\pdfmarkupcomment[markup=Highlight]{
I'm a little paragraph short and stout.
Here is my last stop.
}{No comment}

\pdfmarkupcomment[markup=Highlight]{
Here is my successor.
When I get all wrapped up,
Hear me shout!
}{No comment}

\pdfmarkupcomment[markup=Highlight]{
Just write me down
and pour me out.
}{No comment}

\pdfmarkupcomment[markup=Highlight]{
I'm a clever environment, yes it's true.
Here's an example of what I can do.
I can wrap my paragraphs each into a command.
Just put me around them and pour me out.
}{No comment}

\end{document}

+ In my example of \pdfmarkupcomment, it would be acceptable to have the same comment repeated over each paragraph.

  • yes sorry I just deleted that comment I misread the text, but still fixing the example so it loads all the right packages to run the example would be good – David Carlisle Dec 9 '15 at 7:51
  • @DavidCarlisle The second form shouldn't need more than a \documentclass{article}\usepackage{pdfcomment}\begin{document} and \end{document} wrapped around it, the first form obviously needs the sought environment's definition in addition. Probably some iteration over the paragraphs inside...But pdfmarkupcomment is really just an example, this might as well be any other star-defined macro, e.g. \newcommand*{\red}[#1]{{\color{red}#1}} – Tobias Kienzler Dec 9 '15 at 7:55
  • Strongly related, maybe even duplicate: tex.stackexchange.com/a/10526/430 – Tobias Kienzler Dec 9 '15 at 8:02
  • Don't add that to the comment add it to the example!! But as I said in my original comment, in general (as for the \color example) I can think of no cases where the complexity of doing this do not outweigh the benefits of the * form so simply using \newcommand would be preferable, But if you have and existing command that only works on text runs it could be done, probably although the details would depend on the command – David Carlisle Dec 9 '15 at 8:03
  • 1
    you could grab the whole environment with environ as in egreg's answer then what you do next depends on the command. In some cases it would be enough to define \par as \egroup\bgroup\foo so the command stops and starts at each blank line., Other commands really need explicit {} so there you would have to scan over the text splitting at \par and adding \foo{...} which is more general but more complicated, but as egreg's shown that I'll leave him to get the tick:-) – David Carlisle Dec 9 '15 at 9:00
5

Use the power of expl3 together with environ:

\documentclass{article}
\usepackage{environ,xparse}

\usepackage{pdfcomment}

\ExplSyntaxOn
\NewEnviron{pdfmarkedup}[2][]
 {
  \kienzler_pdfmarkedup:Vnn \BODY { #1 } { #2 }
 }

\seq_new:N \l_kienzler_pdfmarkedup_pars_seq
\cs_new_protected:Nn \kienzler_pdfmarkedup:nnn
 {
  \seq_set_split:Nnn \l_kienzler_pdfmarkedup_pars_seq { \par } { #1 }
  \seq_map_inline:Nn \l_kienzler_pdfmarkedup_pars_seq
   {
    \tl_if_blank:nF { ##1 }
     {
      \pdfmarkupcomment[#2]{##1}{#3} \par
     }
   }
 }
\cs_generate_variant:Nn \kienzler_pdfmarkedup:nnn { V }
\ExplSyntaxOff


\begin{document}
\begin{pdfmarkedup}[markup=Highlight]{no comment}
I'm a little paragraph short and stout.
Here is my last stop.

Here is my successor.
When I get all wrapped up,
Hear me shout!

Just write me down
and pour me out.

I'm a clever environment, yes it's true.
Here's an example of what I can do.
I can wrap my paragraphs each into a command.
Just put me around them and pour me out.
\end{pdfmarkedup}

\end{document}

We absorb the environment's content with environ, then split it in a sequence at \par tokens. Each item of the sequence is passed to \pdfmarkupcomment.

  • I frankly don't have the faintest clue how this works (yet), but it does, so here's the checkmark. I guess this can be generalized into a \createenvironmentfromcommand somehow... – Tobias Kienzler Dec 9 '15 at 13:36
  • @TobiasKienzler The main obstacle is the syntax of the original command. – egreg Dec 9 '15 at 15:39

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.