# Make first word in macro bold

I have the following use-case:

\cmd{cp \opt{r} \marg{from} \marg{to}}

This should typeset a UNIX command for a manual. I’d like the actual command (here, cp) to be typeset in bold while the rest of the command line is typeset normally. Now, I could obviously just write something along the following lines:

\cmd{\textbf{cp} \opt{r} \marg{from} \marg{to}}

… but I’d prefer if this were possible automatically. I thought of two approaches but cannot get either to work:

1. Make everything bold, cancel bold for nested commands:

\newcommand*\cmd[1]{%
\texttt{\textbf{#1}}
}
\newcommand*\opt[1]{%
\undobf{-#1}
}

… problem: how would \undobf look like? \textrm isn’t appropriate here since I need to preserve the tt style.

2. Define a TeX command containing a space in its arguments:

\newcommand*\cmd[1]{%
\texttt{\setcmd#1}
}
\def\setcmd#1 #2{%
\textbf{#1} #2
}

But this doesn’t work at all, probably because I’m botching the syntax. But even once the syntax is fixed, this still won’t work for cases where I provide no arguments/options for a command (e.g. \cmd{pwd}).

-
Should it only take one argument? With e.g. two arguments you could do something like \newcommand{\cmd}[2]{\textbf{#1} #2} –  Tom Bombadil Oct 14 '12 at 11:44
@Tom Hmpf. I should have seen that solution myself. I’d still prefer if TeX could parse the argument itself (in fact I also dislike the \opt and \marg macros and if I had more time and my TeX weren’t so rusty then I’d fix it so that the usage would be as follows: \cmd{cp -r from to} … but that’s a story for another day. –  Konrad Rudolph Oct 14 '12 at 12:01

One could use the usual TeX/LaTeX programming to decide if the first word has something after it and then choose the right branch.

With LaTeX3 functions it's much easier:

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{tgcursor} % clone of Courier

\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\cmd}{ m }
{
\krudolph_split_cmd:n { #1 }
}
\cs_new_protected:Npn \krudolph_split_cmd:n #1
{
\seq_set_split:Nnn \l__krudolph_cmd_seq { ~ } { #1 }
\seq_pop_left:NN \l__krudolph_cmd_seq \l__krudolph_cmd_tl
\group_begin:
\normalfont\ttfamily
\textbf{ \l__krudolph_cmd_tl } ~
\seq_use:Nnnn \l__krudolph_cmd_seq { ~ } { ~ } { ~ }
\group_end:
}
\seq_new:N \l__krudolph_cmd_seq
\tl_new:N \l__krudolph_cmd_tl
\ExplSyntaxOff

% missing definitions
\newcommand{\opt}[1]{-#1}
\newcommand{\marg}[1]{<#1>}

\begin{document}
\cmd{cp \opt{r} \marg{from} \marg{to}}

\cmd{pwd}
\end{document}

The argument is split at spaces; then the first element is detached for being printed in boldface; the rest is printed in medium weight, separated by spaces.

-
Hmm, before I can start using this I need to use LaTeX3. Ah well, that day will surely come. –  Konrad Rudolph Oct 15 '12 at 11:03

You had the syntax correct for (2) but if you look in the log file it probably said

LaTeX Font Info:    Font shape T1/cmtt/bx/n' in size <10> not available
(Font)              Font shape T1/cmtt/m/n' tried instead on input line 18.

That is, the standard TeX fonts don't have bold typewriter so although you correctly asked for that you got normal weight instead.

If you don't want cp to be in monospace I think you the following where you just add the grouping in your user command and switch to tt after the bold:

\documentclass{article}

\usepackage[T1]{fontenc}

\def\opt#1{{[#1]}}
\def\marg#1{{\char\{#1\char\}}}

\newcommand*\cmd[1]{{\setcmd#1 }}

\def\setcmd#1 {%
\textbf{#1} \ttfamily
}

\begin{document}

\cmd{cp \opt{r} \marg{from} \marg{to}}

\cmd{pwd}

\end{document}
-
Actually, I’m loading courier so the bold font is available. Sorry, I should have been more explicit in the error message, which is along the lines of “use of \setcmd doesn’t match its definition”. It works after using extra braces around the invocation, as in your example. However, it predictably still fails for \cmd{pwd}. –  Konrad Rudolph Oct 14 '12 at 11:53
That's why the MWE should always be a complete docuement. If you got that error (which I didn't when I ran your example) it was called when there was no explicit space in the input stream, if you need to make sure there is a space, so \newcommand*\cmd[1]{{\setcmd#1 }} with a space after #1. –  David Carlisle Oct 14 '12 at 14:07
I totally agree. I omitted the MWE because I wasn’t actually fishing for a correction of an error, I just wanted to show my thoughts about an approach, i.e. I’d considered my code as pseudo code rather than almost-working TeX. –  Konrad Rudolph Oct 15 '12 at 10:37