3

Is there a way to define a command or macro that outputs only the first letter of its argument?

Example: my name is Joaquim Brasil. I could define a macro \def\WhatIsYourName#1{\@WhatIsYourName{#1}} that stores my name and another one \def\MyNameIs{\@WhatIsYourName} that prints Joaquim Brasil whenever I do \MyNameIs in the body of my tex file. However, I sometimes need to print B., Joaquim since this is my signature.

So, my question is: Is there a way to define a command, say \MySignatureIs that reads the value stored in \MyNameIs and outputs the signature in the way required above?

2 Answers 2

3

One way to achieve this is by specifying the "shape" of the input using \def. For example, if you define

\def\@setinitials#1#2@{\def\@initials{#1}}

and then use \@setinitials Joaquim@ then when \@setinitials is expanded #1 is set to J and #2 to oaquim so that \@initials is defined to be J. The key point is that the @ at the end of the parameter specifications for \@setinitials tell TeX to set #2 to be whatever follows #1 up to the the next @ character in the input stream. Of course, you do not want to use the command \@setintials "by hand", since you would always have to put the @ character at the end, but by chaining a series of commands like this you can set it up so that the code

  \SetMyName{Joaquim Brasil}
  My name is \MyName.
  My abbreviated name is \myName.
  My abbreviated surname is \Myname.

produces

enter image description here

Here is the full code:

\documentclass{article}

\makeatletter
\def\@firstname{} % initialise all name variants
\def\@firstnameInitial{}
\def\@surnameInitial{}
\def\@surname{}
\def\@setsurnameinitial#1#2@{\def\@surnameInitial{#1}}
\def\@setinitial#1#2@{\def\@firstnameInitial{#1}}
\def\@setmyname#1 #2@{% space separates #1 and #2 up to @
  \def\@firstname{#1}% set first name
  \def\@surname{#2}%   set surname
  \@setinitial#1@%     set firstname initial
  \@setsurnameinitial#2@% set surname initial
}
\newcommand\SetMyName[1]{\@setmyname #1@}
\newcommand\MyName{\@firstname\space\@surname}
\newcommand\myName{\@firstnameInitial.~\@surname}
\newcommand\Myname{\@surnameInitial.,~\@firstname}
\makeatother

\begin{document}

  \SetMyName{Joaquim Brasil}

  My name is \MyName.

  My abbreviated name is \myName.

  My abbreviated surname is \Myname.

\end{document}

A final caveat, this \SetMyName command will break if the name that it is given does not contain a space, such as \SetMyName{Brasil}. With a little more effort you could cope with this case too. It will also break if the name contains an @ character. If you want something really robust then I would probably switch to using LaTeX3.

3
  • Hi @Andrew thank you for the response. I tested the code and simply commented out the first four \defs. After compilation, no error occurred, so that I believe that these defs are not necessary. Do you agree?
    – Brasil
    Commented Jun 29, 2020 at 2:43
  • @Brasil The first four \def's initialise the macros that are used by the various my name macros. If you delete these and then use \MyName, \Myname or \myName without first using \SetMyName then you will get an error. These commands are not necessary if \SetMyName is always used. They are there only to stop a compilation problem in case of "user error".
    – user30471
    Commented Jun 29, 2020 at 2:53
  • Great! Thank you again!
    – Brasil
    Commented Jun 29, 2020 at 3:28
4

Here's an expandable expl3 implementation that copes with middle names, single names, and no forbidden characters :-)

enter image description here

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\seq_new:N \g_brasil_name_seq
\NewDocumentCommand \WhatIsYourName { m }
  { \seq_gset_split:Nnn \g_brasil_name_seq { ~ } {#1} }
\NewExpandableDocumentCommand \MyNameIs { }
  { \seq_use:Nn \g_brasil_name_seq { ~ } }
\NewExpandableDocumentCommand \MySignatureIs { }
  {
    \__brasil_signature:ee
      { \seq_item:Nn \g_brasil_name_seq { 1 } }
      {
        \seq_use:Nn \g_brasil_name_seq { \s_stop } \s_stop
        \exp_not:N \q_nil \s_stop
      }
  }
\cs_new:Npn \__brasil_signature:nn #1 #2
  {
    \exp_last_unbraced:No \__brasil_signature_aux:w
      { \use_none_delimit_by_s_stop:w #2 } #1
  }
\cs_generate_variant:Nn \__brasil_signature:nn { ee }
\cs_new:Npn \__brasil_signature_aux:w #1 \s_stop
  {
    \quark_if_nil:nF {#1}
      { \tl_head:n {#1}.,~ \__brasil_signature_aux:w }
  }
\ExplSyntaxOff
\pagestyle{empty}

\begin{document}

\WhatIsYourName{Joaquim Brasil}

My name is \MyNameIs{} and my signature is \MySignatureIs.

\WhatIsYourName{Brasil}

My name is \MyNameIs{} and my signature is \MySignatureIs.

\WhatIsYourName{Joaquim Middle Name Brasil}

My name is \MyNameIs{} and my signature is \MySignatureIs.

\end{document}
6
  • Sorry @PhelypeOleinik but I mistakenly upvoted your answer before testing it. I tried to compile, but I got a lot of errors and no output.
    – Brasil
    Commented Jun 29, 2020 at 2:02
  • @Brasil I wouldn't post an answer that doesn't work (for me, at least :-). What errors (usually the first one is enough)? What TeX distribution do you have? Commented Jun 29, 2020 at 2:10
  • I am trying to compile in Overleaf, so that I cannot Ctrl+C. But I will try to type it here (sorry if I make any mistake): \MySignatureIs code ->\exp_args:Nee \_brasil_signature:nn{\seq_item:Nn\g_... l.35 ...ameIs{} and my signature is \MySignatureIs The control sequence at the end of the top line of your error message was never \def'ed. Something like this...
    – Brasil
    Commented Jun 29, 2020 at 2:21
  • @Brasil I changed so it works with TL'18. With TL'17 or older you can do it expandably as well, but the code would need to change quite a lot. Anyways, in Overleaf you can change the version of TeXLive by going to the Menu and then selecting a newer version. Commented Jun 29, 2020 at 2:33
  • 1
    Thank you for the tip about the TL version. I didn't know it. I am quite new to LaTeX. :-)
    – Brasil
    Commented Jun 29, 2020 at 2:37

You must log in to answer this question.

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