Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I want to use the command \DTLstoreinitials from package \usepackage{datatool} in the following way :

\newcommand{\extractInitials}[1]{%
\DTLstoreinitials{#1}{\userInitials}%
\DTLsubstituteall{\userInitials}{.}{}%remove points between the initials
\DTLsubstituteall{\userInitials}{ }{}%remove spaces
\userInitials%
}

If I call the command directly, it works :

\extractInitials{My Name}

gives MN. But if I use an auxiliary command: \newcommand{\nom}{My Name} and try to call

\extractInitials{\nom}

then the compilation fails with error

! Paragraph ended before \@dtl@initials was complete.

How can I fix this?


Here is a minimal example 1 :

\documentclass[12pt]{article}
\usepackage{trackchanges}
\usepackage{datatool}

\newcommand{\extractInitials}[1]{%
%\expandafter\DTLstoreinitials\expandafter{#1}{\userInitials}%
\DTLstoreinitials{#1}{\userInitials}%
\DTLsubstituteall{\userInitials}{.}{}%remove points 
\DTLsubstituteall{\userInitials}{ }{}%remove spaces
}
\begin{document}
\extractInitials{AAA BBB}\addeditor{\userInitials}
\extractInitials{CCC DDD}\addeditor{\userInitials}
----------- \\% to see the result of the addeditor commands
\makeatletter
\TC@editorOne\\
\TC@editorTwo\\
\TC@editorThree\\
\makeatother
-----------
\end{document}

The output is CD n/n n/n To compare : example 2

\addeditor{AB}
\addeditor{CD}
----------- \\% to see the result of the addeditor commands
\makeatletter
\TC@editorOne\\
\TC@editorTwo\\
\TC@editorThree\\
\makeatother
-----------

The output is AB CD n/n

share|improve this question
    
You don't have to sign with your name since it automatically appears in the lower right corner of your post. I've edited your post accordingly. –  Werner Dec 21 '11 at 23:13
    
Welcome to TeX.sx! Note that you can edit your posts to add more information. Answer posts are for solutions to the question. –  Martin Scharrer Dec 22 '11 at 22:09
    
I've added note 3. –  egreg Dec 22 '11 at 22:34
    
thank you, it solved my problem. –  nicolas roy Dec 22 '11 at 23:42
add comment

1 Answer 1

up vote 5 down vote accepted

You have two choices.

First

\newcommand{\extractInitials}[1]{%
  \expandafter\DTLstoreinitials\expandafter{#1}{\userInitials}%
\DTLsubstituteall{\userInitials}{.}{}%remove points between the initials
\DTLsubstituteall{\userInitials}{ }{}%remove spaces
\userInitials
}

This can be used if \nom expands immediately to the name and no more processing is needed.

The trick is to access at #1 before processing by \DTLstoreinitials begins. The first \expandafter acts on the second, which in turn expands the first token after the brace: in your case it can be \nom; if you give directly a name nothing happens (but see the second note).

Second

\makeatletter
\newcommand{\extractInitials}[1]{%
  \begingroup\protected@edef\x{%
    \endgroup\noexpand\DTLstoreinitials{#1}{\noexpand\userInitials}}\x%
\DTLsubstituteall{\userInitials}{.}{}%remove points between the initials
\DTLsubstituteall{\userInitials}{ }{}%remove spaces
\userInitials
}
\makeatother

This is to be preferred if the contents of \nom is more complicated (say \nom becomes \Prenom\space\Nom. Here we expand until the bottom, but "robusted" macros such as those for accented letters remain untouched.

Note 1

Using \edef in this context directly is bound to break if the argument of \extractInitials contains accented characters (even when a control sequence is used).

Note 2

In both cases, results are unpredictable if the first initial is an accented letter. Put it as {É}lie Cartan to get a correct result. However, none of the method works reliably in this case if the input encoding is UTF-8 (for limitations of datatool). Write always a first accented initial in braces.

Note 3

In case this macro must be fed to another command, the result will depend on what this macro does. For example it will work with \textbf{\extractInitials{My Name}}, since \textbf wants only to print its argument. In other cases a different approach must be taken; for example, in your test document one has to take an indirect path:

\newcommand{\extractInitials}[1]{%
  \expandafter\DTLstoreinitials\expandafter{#1}{\userInitials}%
\DTLsubstituteall{\userInitials}{.}{}%remove points between the initials
\DTLsubstituteall{\userInitials}{ }{}%remove spaces
}
\newcommand{\myaddeditor}[1]{%
  \extractInitials{#1}\expandafter\addeditor\expandafter{\userInitials}}

and then say \myaddeditor{AAA BBB}

share|improve this answer
    
Thank you very much. I will use the first one, since \nom expands immediately to the name in my case, and i have accented letter. It works, but i don't quite understand the trick :). Could you explain it to me ? I understand the first \expandafter, it insure that the argumen #1 will be first expanded. But why to "expand" \userItinials ? I thought this is a temporary command where DTLstoreinitials stores the result of the string operation... –  nicolas roy Dec 22 '11 at 9:38
    
Another problem i'm facing : i'm using the result of \extractInitials in some other command \somecommand{\extractInitials{My Name}} but it fails. This command is one from a package, and i don't know exactly how it is defined. But is there a way to make \extractInitials completely expand, before we give it as an argument to \somecommand, so that the compilation doesnt fails, even if we don't know how \somecommand is build ? –  nicolas roy Dec 22 '11 at 10:22
    
@nicolasroy Please add to the question a minimal example; you should register on the site (the moderators can then merge other questions you submitted as an unregistered user). –  egreg Dec 22 '11 at 11:45
    
Well, my question was precisely, how can i make the command \extractInitials sufficiently robust, so that i can use it inside any command in the future... But ok, for the moment, i want to be able to use: \addeditor{\extractInitials{My Name}} where \addeditor is a command from the package trackchanges. –  nicolas roy Dec 22 '11 at 18:11
    
@nicolasroy If you cut the last \userInitials from the main macro and say \extractInitials{My Name}\addeditor{\userInitials} it might work (maybe with a couple of \expandafters). –  egreg Dec 22 '11 at 18:14
show 2 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.