8

If I have a macro that works like this, inside the braces:

{\SomeMacro applies to this text}

I can easily do this:

\newcommand\MySomeMacro[1]{{\SomeMacro #1}}

Then the new command goes outside the braces:

\MySomeMacro{applies to this text}

I can also use \let to re-define the original macro, via an intermediary.

My question: Can it be done the other way around? That is, if I already have a macro that is used outside the braces, can I re-define it (or create a new macro) that does the same thing, but inside the braces?

I am using LuaTeX on TeXlive 2016, but surely this is a rather basic question, applicable to anything. Also, in my particular case, the argument of the macro is very simple, usually plain text.

Why I would like to do this: I am working with a document, in which most of the user commands go inside the braces. For consistency in writing, I would like to define my own commands so that they work the same way. Re-defining the original commands, so that they go outside the braces, might confuse someone who is editing my document.

1
  • while this is possible it seems very weird thing to do, commands like \bfseries do not pick up an argument from a surrounding group they are a state change just acting at the point of the command. To take a command that has an argument like \section{abc} and change its syntax so {zzzz \newsection abc} works (but \begin{figure} zzzz \newsection abc\end{figure} gives a parse error) obscures the underlying operation of the command. Commented Dec 6, 2016 at 17:27

2 Answers 2

7

If you want to input, for instance

{\macro argument or whatever}

and want TeX to convert that to

\command{argument or whatever}

to get all the flexibility of an easily defined command with one argument, you can do

\def\macro{\aftergroup\command\aftergroup{}}
\def\command#1{Whatever you whant to do with the argument [#1].}

What does this do?

Your code {\macro argument} will open a group { and then expand \macro, which expands to \aftergroup\command\aftergroup{}. In turn, \aftergroup makes sure the next token is inserted exactly after closing the group, so \aftergroup\command ensures that when you close the group \command is there, and \aftergroup{ ensures that \command{ is there when you close a group. Then, you close the group with the following } leaving your code with \command{argument}.

12
  • This is weird, since one would think the argument is processed and forgotten (since TeX found \macro and not \command), yet somehow it ends up as the argument to \command.
    – Werner
    Commented Dec 6, 2016 at 17:03
  • 1
    @Werner the trick is that the group started by { is finished by \macro not by the } at the end of the "argument" so the switch to \command happens before the argument is scanned. Commented Dec 6, 2016 at 18:41
  • 1
    @Werner Roughly, \macro “expands” to }\command{. So {\macro arg} is converted to {}\command{arg}.
    – Manuel
    Commented Dec 6, 2016 at 19:06
  • 1
    @RobtA It's not the argument that needs to be exotic but the context, not the fault of Manuel but \parbox{6cm}{abc \macro xyz} will fail as will \begin{center} abc\macro xyz\end{center} the number of places where you can use \macro and not result in an error or in lost text is strictly limited. Commented Dec 6, 2016 at 19:44
  • 1
    @UlrichDiez In any case you can (probably) make your suggestion work by just adding braces around the #1 inside each command of this type (for instance \def\command#1{Do something with [{#1}].}). Of course, as this whole idea, it's not ensured that it will work everytime.
    – Manuel
    Commented Dec 6, 2016 at 22:00
4

The real solution depends on how \commandwitharg is defined. A general solution allowing

 <open group>\noarg text<close group>

is really very difficult to find, if at all possible.

Here's an alternative solution to Manuel's, which is slicker:

\documentclass{article}

\newcommand\commandwitharg[1]{---#1---}

\newcommand{\noarg}{%
  % close the group
  \egroup                  
  % the first \expandafter removes \iftrue
  % the second \expandafter removes \else
  \expandafter\expandafter\expandafter
  \commandwitharg\iftrue\expandafter{\else}\fi 
}

\begin{document}

\commandwitharg{ABC}

{\noarg ABC}

\end{document}

Don't hope to be able to have \begingroup\noarg text\endgroup: only {\noarg text} will work.

It is much better to use a text editor and simply do the change

{\noarg<space>

to

\commandwitharg{

Finally, knowing the real definition of \commandwitharg and its use cases, can lead to a better solution.

7
  • 2
    but I want to do \begin{center} \noarg ABC \end{center} ..... Commented Dec 6, 2016 at 17:29
  • 1
    @DavidCarlisle Go away!
    – egreg
    Commented Dec 6, 2016 at 17:39
  • I will test all of the above, and report back. Perhaps my question is trickier than I thought it would be. Rather like asking, "If taking derivatives is so easy, then why are integrals so hard? Aren't they just the reverse of each other?"
    – user103221
    Commented Dec 6, 2016 at 18:29
  • 3
    @RobtA a better analogy might be like saying if making scrambled eggs is easy why can't I make an egg out of scrambled egg, aren't they just reverse of each other. Commented Dec 6, 2016 at 18:43
  • @DavidCarlisle Oh, I thought mathematicians were the main users here. Thought they'd understand math, but not eggs.
    – user103221
    Commented Dec 6, 2016 at 19:35

You must log in to answer this question.