3

I'd like to create a macro that behaves differently depending on whether or not it is called from within an \item, such as

\def\mymacro{\if<INSIDE_ITEM> do this \else do that\fi}

Here is an example where this could be used:

This is how my macro performs outside an item: {\mymacro}

\item{1}. And this is how it performs inside an item: {\mymacro}

For comparison, a similar situation regards macros that perform differently depending on whether or not they are called from within math mode, such as:

\def\anothermacro{\ifmmode do this \else do that\fi}

The trouble is that there does not seem to be any big difference between the environment of an item as compared to a normal paragraph. Any ideas?

PS: I am really interested in plain TeX (as opposed to LaTeX)! Also, a straightforward solution that does not require any extra packages would be highly appreciated!

1
  • 5
    \item in plainTeX is just \par\hang\textindent, with \hang is \hangindent\parindent. Such an \item AFAIK always ends with the next paragraph. So you could do \ifdim\hangindent=\parindent … \else …\fi as a heuristic. If you don't want a heuristic, you have to redefine \item (and maybe use \everypar to recognize the end of the item).
    – cabohah
    Mar 17, 2023 at 14:51

2 Answers 2

4

Similar to what cabohah suggested in a comment, but with a small safety check: I redefine \item to use a new length \itemindent instead of \parindent, and set the former to be \parindent plus 1sp. This is optically indistinguishable (just a couple of nanometers), but the chances of the test \ifdim\hangindent=\itemindent leading to a false positive are relatively small, I'd say.

\newdimen\itemindent
\itemindent\parindent
\advance\itemindent1sp
% the plain TeX definition is basically:
% \def\item{\par\hangindent\parindent\textindent}
\def\item{\par\hangindent\itemindent\textindent}
\def\mymacro{\ifdim\hangindent=\itemindent(INSIDE)\else(OUTSIDE)\fi}

Text text text text text text text text text \mymacro
\item{x} bla bla bla bla \mymacro
\item{x} bla bla bla bla \mymacro

Text text text text text text text text text \mymacro
\bye

enter image description here

1
  • Both answers are great. I'm accepting this one due to its greatest simplicity.
    – Ruy
    Mar 17, 2023 at 21:48
4

Following the suggestion of cabohah in the comments:

\newif\ifinitem
\initemfalse
\def\mymacro{\ifinitem hi!\else bye\fi}
\def\item{\par\initemtrue\hang\textindent}
\let\oldpar\par
\def\par{\initemfalse\oldpar}
This is how my macro performs outside an item: {\mymacro}  

\item{1}. And this is how it performs inside an item: {\mymacro}

Now we are no longer inside the item: {\mymacro}
\bye

enter image description here

6
  • Also, the etoolbox macros \pretocmd and \apptocmd can manipulate booleans that way.
    – rallg
    Mar 17, 2023 at 15:22
  • 1
    @rallg the OP asked for a solution with no packages, that's why I did it like this. Otherwise I might have opted for tex.stackexchange.com/a/79625 which is an environment and therefore a bit easier to manipulate in terms of actions at the start and end.
    – Marijn
    Mar 17, 2023 at 15:45
  • +1 You could use the built-in \endgraf instead of making another copy of \par.
    – campa
    Mar 17, 2023 at 16:26
  • @Marijn OK, no packages. But the OP did not provide a MWE stating which packages were already used, and etoolbox is quite often used by a variety of standard packages. The environment approach is also very good.
    – rallg
    Mar 17, 2023 at 19:14
  • @rallg The question states explicitly plain TeX.
    – campa
    Mar 17, 2023 at 20:32

You must log in to answer this question.

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