6

I find myself needing to define many different macros relating to variables, spaces, etc. to help define consistent font choices (\mathsf,\mathcal, normal, etc). These all essentially look like:

\newcommand{\P}{\ensuremath{\mathcal{P}}\xspace}

which lets \P be used in text/math mode, not eat spaces after it, etc. All essentially what I want out of notation definition.

I've abstracted this command system to the following constructor:

\newcommand{\makespace}[2]{\newcommand{#1}{\ensuremath{\mathcal{#2}}\xspace}}

With this macro, I'll have \makespace{\P}{P} produce the first macro I wrote, which makes all of my macro definitions more consistent/readible. I could just leave it at this, but I'll need to define multiple constructors - as an example, something like:

\newcommand{\makeconstant}[2]{\newcommand{#1}{\ensuremath{\mathsf{#2}}\xspace}}

(where \mathcal was replaced with \mathsf) would also need to be defined. So, it seems like making a constructor of constructors would be prudent, which I'd imagine would look like:

\newcommand{\makeconstructor}[2]{\newcommand{#1}[2]{\newcommand{#1'}{\ensuremath{#2{#2'}}\xspace}}}

Here's my issue - I want this two parameter macro to return a two parameter macro. How can I differentiate between #1 and #1' (which I'm sure is the incorrect notation)? What's the correct way to "keep the paramters separate" when defining a higher-order function such as this?

15
  • 5
    Where do I start? I mean, pardon my sincere tone, but you're actually doing three things that should not be done. (1) Use \xspace. (2) Use \ensuremath improperly. (3) Define or re-define one-letter macros for math symbols instead of using more descriptive names. Note that your code would not compile with the error ! LaTeX Error: Command \P already defined. Or name \end... illegal, see p.192 of the manual.
    – yo'
    Jun 21, 2017 at 17:15
  • 5
    If you want to reference an argument of an inner command, use ##1, if you want to reference an argument of a command inside a command inside a command, use ####1 if you want to ... use ########1 etc. Also, do not redefine one-letter commands, they are reserved. What you do here, is redifining the macro newcommand. This is at least strange. Jun 21, 2017 at 17:24
  • @yo' I appreciate the criticism. The \P example actually has name \player in usage, for whatever reason I decided against including that here. As for not using xspace, if I have issues with it eating spaces should I try throwing an {} on the end of whatever is causing issues, and then posting here if that doesn't work? It was introduced to me by one of my coauthors who's quite a bit more senior than me. Jun 21, 2017 at 17:27
  • @MichaelFraiman Am I redefining \newcommand, or defining an alternative usage/a template for it? I'm attempting to do the second, but if this would break \newcommand inadvertently that makes this all not worth it. Jun 21, 2017 at 17:28
  • 1
    @MichaelFraiman your comments here are incorrect sorry, the suggested definition does not redefine \newcommand (and single letter names are not in general reserved) Jun 21, 2017 at 18:19

3 Answers 3

11

Abstract also the formatting command

\newcommand{\newdescriptor}[3]{\newcommand{#1}{#2{#3}}}

Then

\newdescriptor{\sP}{\mathbf}{P}

will do

\newcommand{\sP}{\mathbf{P}}

Nowhere I see any improvement over the direct definition unless you do a further abstraction step:

\newcommand{\whatever}[1]{\mathbf{#1}}
\newcommand{\constant}[1]{\mathsf{#1}}

\newcommand{\newdescriptor}[3]{\newcommand{#1}{#2{#3}}}

\newdescriptor{\sP}{\whatever}{P}
\newdescriptor{\cs}{\constant}{S}

Add \ensuremath and \xspace if you really want. I will never be convinced that typing

The constant \cS is nice

is better than typing

The constant \(\cS\) is nice

To be honest, I find the second way the only good one (on par with $\cS$).

4
  • 1
    Are \(\cS\) and $\cS$ interpreted equivalently by Latex? Jun 21, 2017 at 17:29
  • 1
    @Mark Yes, but the former does a further check.
    – egreg
    Jun 21, 2017 at 17:30
  • @Mark Not completely equivalently, but to day, usage of $...$ is considered fine.
    – yo'
    Jun 21, 2017 at 17:31
  • 2
    For other people interested in the "further check" this might be a good starting point. Jun 21, 2017 at 17:33
9

In the replacement text of a definition #2 is replaced by the second argument, #1 is replaced by the first argument, and ## is replaced by # so

enter image description here

\documentclass{article}
\usepackage{xspace}
\newcommand{\makeconstructor}[2]{%
\newcommand{#1}[2]{\newcommand{##1}{\ensuremath{#2{##2}}\xspace}}}

\makeconstructor\makespace\mathcal
\makeconstructor\makewidget\mathsf

\makespace\SP{P}
\makespace\SQ{Q}
\makewidget\WP{P}
\makewidget\WQ{Q}


\begin{document}

$\SP<\SQ<\WP<\WQ$

\end{document}
2
  • 2
    Beautifully concise! Jun 21, 2017 at 18:26
  • 1
    @StevenB.Segletes it's the intended syntax of the OP, I just corrected #1' to ##1. Jun 21, 2017 at 18:27
1

Based on the comments, the main problem can be solved with defining new "style" of typesetting. To change everything with one click, we can now edit one line in preamble.

\documentclass{article}
    
\newcommand{\mystyle}[1]{\mathcal{#1}}
\newcommand{\player}{\mystyle{P}}

\begin{document}
    
    \noindent
    Here is calligrafic font.
    \[
    \player
    \]
    Oops, seems like now I want all letters to be Sans Serif.
    
    \renewcommand{\mystyle}[1]{\mathsf{#1}}
    \[
    \player
    \]
    
\end{document}

Here is the result. enter image description here

1
  • And of course you should not be using $$... $$ in latex
    – daleif
    Jun 21, 2017 at 22:30

You must log in to answer this question.

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