[Tex/LaTex] How to define a command that bolds the first letter of each word in the input argument

acronymsboldmacros

I want to define a command that takes a sentence, a word or several words as input and bolds the first letter of each word. I need this mostly for abbreviations and so far I have done it manually in this way:

\documentclass[a4paper]{article} 

\begin{document} 
GNU is a recursive acronym for ``\emph{\bf{G}\normalfont{nu's} \bf{N}\normalfont{ot} \bf{U}\normalfont{nix}}'', chosen because GNU's design is Unix-like, but differs from Unix by being free software and containing no Unix code.
\end{document}

enter image description here

What I want to do, is to define a command like \BoldAbbrv that does the job. In other words:

\documentclass[a4paper]{article} 
%\newcommand{\BoldAbbrv}...IMPLEMENTATION
\begin{document} 
GNU is a recursive acronym for ``\BoldAbbrv{Gnu's Not Unix}'', chosen because GNU's design is Unix-like, but differs from Unix by being free software and containing no Unix code.
\end{document}

How can I do that? Moreover, a related question that came to my mind while thinking about this problem, is there such concept as wildcard in latex (e.g. "*" as zero or more characters and "_" as a single one)?

Best Answer

Here's an idea using expl3:

\documentclass{article}
\usepackage[T1]{fontenc}

\usepackage{expl3,xparse}

% turn expl3 space on: `:' and `_' are letters now and spaces
% are ignored. To insert a space use `~'.
\ExplSyntaxOn
% declare a new sequence variable:
\seq_new:N \l_pouya_boldfirst_seq

% the internal command:
\cs_new:Npn \pouya_boldfirst:n #1
  {
    % split the input at every space and put the items in the sequence:
    \seq_set_split:Nnn \l_pouya_boldfirst_seq { ~ } { #1 }
    % map over every item of the sequence; each item is referred to with
    % `##1' as we're inside of a command definition:
    \seq_map_inline:Nn \l_pouya_boldfirst_seq
      {
        % use the head of the item in the argument of \textbf
        % and put in the tail of the item after it
        % followed by a space:
        \textbf { \tl_head:n { ##1 } } \tl_tail:n { ##1 } ~
      }
    % undo the last space:
    \unskip
  }

% the document command:
\NewDocumentCommand\BoldFirst{m}
  { \pouya_boldfirst:n { #1 } }

% turn expl3 space off again:
\ExplSyntaxOff

\begin{document}

GNU is a recursive acronym for ``\BoldFirst{Gnu's Not Unix}'', chosen because GNU's
design is Unix-like, but differs from Unix by being free software and containing
no Unix code.

\end{document}