I am relatively new to LaTeX and I want to know whether there is a way to create a command such that it takes whatever capital letter the command is and prints the blackboard font. Here's what I mean: If I want to write \mathbb{Z}
, then I want to simply write \Z
, and if I want to write \mathbb{C}
, I want to write \C
. One easy way is to just "brute force" \newcommand
for every letter. Is there a slicker way?
3 Answers
\documentclass{article}
\usepackage{amssymb}
\ExplSyntaxOn
\int_step_inline:nnn { 1 } { 26 }
{
\cs_if_exist:cTF { \int_to_Alph:n {#1} \int_to_Alph:n {#1} }
{
\iow_term:e { Not~redefining~\exp_not:c { \int_to_Alph:n {#1} \int_to_Alph:n {#1} } }
}
{
\cs_new_protected:cpe { \int_to_Alph:n {#1} \int_to_Alph:n {#1} }
{
\exp_not:N \mathbb { \int_to_Alph:n {#1} }
}
}
}
\ExplSyntaxOff
\begin{document}
$\BB+\CC+\ZZ$
\end{document}
You'll get
Not redefining \AA
Not redefining \SS
for which you can choose different names, if needed. The output is
I'd avoid \C
and \Z
or the like. The risk of hitting already defined commands is high. Moreover, I find \CC
and \ZZ
better from the semantic point of view.
For a more general approach. Here are the arguments to \batchdefine
in order
All
orall
for applying to the ehole alphabets (uppercase or lowercase respectively), but it can simply be a list of (distinct) letters;- the template for the command to be defined, where
#1
denotes the current letter in the loop; for instance#1#1
would define\BB
,\CC
and so on in the first call, but#1fr
generates\afr
,\bfr
and so on in the third call; - the wrapper command.
Already defined commands are skipped and an annotation appears in the log file and the console.
\documentclass{article}
\usepackage{amssymb}
\ExplSyntaxOn
\NewDocumentCommand{\batchdefine}{mmm}
{% #1 = lettesr, #2 = template, #3 = command
\ar_batchdefine:nnn {#1} {#2} {#3}
}
\cs_new_protected:Nn \ar_batchdefine:nnn
{
\str_case:nnF {#1}
{
{All}{ \__ar_batchdefine_list:nnn {ABCDEFGHIJKLMNOPQRSTUVWXYZ}{#2}{#3} }
{all}{ \__ar_batchdefine_list:nnn {abcdefghijklmnopqrstuvwxyz}{#2}{#3} }
}
{
\__ar_batchdefine_list:nnn {#1}{#2}{#3}
}
}
\cs_new_protected:Nn \__ar_batchdefine_list:nnn
{
\tl_map_inline:nn {#1}
{
\cs_if_exist:cTF { #2 }
{
\iow_term:e {Not~redefining~\exp_not:c {#2} }
}
{
\cs_new_protected:cpn { #2 } { #3{##1} }
}
}
}
\ExplSyntaxOff
\batchdefine{All}{#1#1}{\mathbb}
\batchdefine{All}{c#1}{\mathcal}
\batchdefine{all}{#1fr}{\mathfrak}
\batchdefine{uvwxyz}{vec#1}{\mathbf}
\begin{document}
$\BB+\CC+\ZZ$
$\cA+\cB+\cW$
$\afr+\yfr$
$\vecu+\vecv+\vecz$
\end{document}
(See edit history for a different implementation.)
An alternative which allows arbitrary lists of letters or ranges.
\documentclass{article}
\usepackage{pgffor}
\usepackage{amsfonts}
\def\batchdef#1#2#3{%
\def\processletter##1{\expandafter\gdef\csname #1\endcsname{#2{##1}}}%
\foreach\letter in {#3}{\expandafter\processletter\expandafter{\letter}}%
}
\batchdef{#1#1}{\mathbb}{N,Z,Q,R}
\batchdef{c#1}{\mathcal}{A,...,Z}
\batchdef{#1fr}{\mathfrak}{a,...,f,E}
\begin{document}
$\NN\subset\ZZ\subset\QQ\subset\RR$
$\cA+\efr+\Efr$
\end{document}
Arguments to \batchdef
are template, wrapper command, letters, where #1
in the template is replaced with the letter in each new command name.
Old LaTeX still kicking.
\documentclass{article}
\usepackage{amssymb}
\makeatletter
\@tfor\x:=ABCDEFGHIJKLMNOPQRSTUVWXYZ\do{%
\ifcsname \x\x\endcsname
\typeout{Not redefining \@backslashchar\x\x,
using \@backslashchar\x\x\x\space instead.}%
\ifcsname \x\x\x\endcsname
\typeout{Damned! \@backslashchar\x\x\x\space already defined! I
renounce.}
\else
\expandafter\edef\csname\x\x\x\endcsname
{\noexpand\mathbb{\x}}%
\fi
\else
\expandafter\edef\csname\x\x\endcsname
{\noexpand\mathbb{\x}}%
\fi
}
\makeatother
\begin{document}
\[\BB + \CC + \ZZ + \SSS + \AAA\]
\end{document}
Remark: as @egreg, I do not define single letter control sequence, which have too much risk of being defined already, although as shown above the code then can define with more letters.
Output:
Output on console and log:
Not redefining \AA, using \AAA instead.
Not redefining \SS, using \SSS instead.
-
The code overwrites current meaning of
\x
. I don't know any LaTeX package (or Babel language) defining\x
as something public. But in all rigor code could have either used\@tempa
or used a group and\xdef
in place of\edef
to avoid altering current meaning of\x
(a priori undefined). Commented Jun 25 at 16:57
\integers
or\complexplane
and rely on your editor's autocomplete.