4

I am trying to make a macro for typesetting higher-categories, and would like to automatically enclose the optional argument in brackets if it is an expression containing + or -.

In particular I would like to have something like \cat[<optional_rank>]{<name>}, so that for example \cat{Bord}, \cat[n]{Fus}, and \cat[2]{Rep} typeset Bord, nFus, and 2Rep respectively, but \cat[n+1]{Fus} and \cat[n-k-2]{Rep} typeset (n+1)Fus and (n-k-2)Rep respectively.

How can I achieve the automatic bracketing? I am almost sure that the answer will involve xparse, but I don't know how to do it myself.

For convenience here is a MWE (that does not do exactly what I want yet)

\documentclass{article}

\newcommand{\cat}[2][]{{#1}\mathbf{#2}}

\begin{document}
    \(\cat{Bord}\), \(\cat[n]{Fus}\), \(\cat[2]{Rep}\), \(\cat[n+1]{Fus}\), \(\cat[n-k-2]{Rep}\)
\end{document}
  • You probably need something a bit more lower level than xparse, can we just look for + and -? Then some expl3 string match might be enough (see also the xstring package) – daleif Sep 24 at 12:45
  • I have xparse loaded anyway (since I always load the package physics which requires xparse). I don't know how what expl3 does, but I'll have a look, thanks. – ɪdɪət strəʊlə Sep 24 at 12:48
  • 1
    Note in general that the physics package is not well recommended due to many poor design choices. – daleif Sep 24 at 13:06
  • yep, I know. I have been following the related questions for alternatives here, but until something better comes up I'll stick with it. – ɪdɪət strəʊlə Sep 24 at 13:15
5

This checks if + or - is in the argument.

\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\cat}{om}
 {
  \IfValueT{#1}{ \is_cat_prefix:n { #1 } }
  \mathbf{#2}
 }

\cs_new_protected:Nn \is_cat_prefix:n
 {
  \str_if_in:nnTF { #1 } { + }
   { (#1) } % there is +
   {
    \str_if_in:nnTF { #1 } { - }
     { (#1) } % there is -
     { #1 }
   }
 }
\ExplSyntaxOff


\begin{document}

\(\cat{Bord}\), \(\cat[n]{Fus}\), \(\cat[2]{Rep}\), \(\cat[n+1]{Fus}\), \(\cat[n-k-2]{Rep}\)

\end{document}

enter image description here

| improve this answer | |
4

This does not expand the argument and simply checks whether #1 contains + or - with the macro \in@ defined by the LaTeX kernel; it will probably fail in many occasions.

\documentclass{article}

\makeatletter
\newcommand{\cat}[2][]{%
   \in@{+}{#1}% check if + occurs
   \ifin@\else\in@{-}{#1}\fi% if no +, check if - occurs
   \ifin@(#1)\else#1\fi
   \mathbf{#2}}
\makeatother

\begin{document}

\(\cat{Bord}\)

\(\cat[n]{Fus}\)

\(\cat[2]{Rep}\)

\(\cat[n+1]{Fus}\)

\(\cat[n-k-2]{Rep}\)

\end{document}

enter image description here

| improve this answer | |
  • Why do you say it will probably fail in many cases? Never heard of \in@ and \ifin@ before, but it looks a pretty useful combo. – Steven B. Segletes Sep 24 at 12:54
  • @StevenB.Segletes It's a pessimistic prediction :-) I'm not sure whether this works well when the whole construct is an argument to another macro. It might, but I haven't tested it yet and I have not used \in@ so thoroughly that I feel comfortable in giving the answer without a warning. – campa Sep 24 at 12:56
4

I use listofitems here to check for the literal presence of + or - in argument #1 (others can be added).

\documentclass{article}
\usepackage{listofitems}
\newcommand{\cat}[2][\relax]{%
  \setsepchar{+||-}%
  \readlist\checksgns{#1}%
  \ifnum\listlen\checksgns[]>1\relax(#1)\else#1\fi\mathbf{#2}}
\begin{document}
    \(\cat{Bord}\), \(\cat[n]{Fus}\), \(\cat[2]{Rep}\), \(\cat[n+1]{Fus}\), \(\cat[n-k-2]{Rep}\)
\end{document}

enter image description here

| improve this answer | |

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.