1

This is an extension of a previous question (link). I would like to include the following xparse key-value store holding a name value into the document below:

% Key-value store
\ExplSyntaxOn 

\prop_new:N \list_prop

\keys_define:nn {bio} {%
    name  .code:n={ \prop_put:Nnn \list_prop {name}  {#1} },
}

\NewDocumentCommand{\update}{+m}{%
    \keys_set:nn {bio} {#1}%
}

\cs_new:Npn \getvalue#1{%
    \prop_item:Nn \list_prop {#1}
}

\ExplSyntaxOff

% Default variable values
\update{%
    name={John Doe}
}

I would like to use the stored name to automatically update l_adam_name_full_tl defined in \adam_name_define:n below. In other words, l_adam_name_full_tl would be defined automatically based on values in the above key-value store. It would be ideal to retain the \definename function for flexibility, but to make its default value \getvalue{name} when an argument is not passed.

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\definename}{m}
 {
  \adam_name_define:n { #1 }
 }

\NewDocumentCommand{\makebold}{m}
 {
  \adam_name_makebold:n { #1 }
 }

\tl_new:N \l_adam_name_full_tl
\tl_new:N \l_adam_name_first_tl
\tl_new:N \l_adam_name_last_tl
\tl_new:N \l_adam_name_initials_tl
\tl_new:N \l__adam_name_input_tl

\cs_new_protected:Nn \adam_name_define:n
 {
  \tl_set:Nn \l_adam_name_full_tl { #1 }
  \tl_set_eq:NN \l_adam_name_first_tl \l_adam_name_full_tl
  \tl_set_eq:NN \l_adam_name_last_tl \l_adam_name_full_tl
  \regex_replace_once:nnN { (.*)\s[^\s]*\Z } { \1 } \l_adam_name_first_tl
  \regex_replace_once:nnN { .*\s([^\s]*)\Z } { \1 } \l_adam_name_last_tl
  \tl_set_eq:NN \l_adam_name_initials_tl \l_adam_name_first_tl
  \regex_replace_all:nnN { ([[:alpha:]])[[:alpha:]]+ } { \1. } \l_adam_name_initials_tl
 }

\cs_new_protected:Nn \adam_name_makebold:n
 {
  \tl_set:Nn \l__adam_name_input_tl { #1 }
  % full name
  \regex_replace_once:nnN
   {
    (
     \u{l_adam_name_full_tl}                                   % name surname
     |
     \u{l_adam_name_initials_tl} \s \u{l_adam_name_last_tl}    % initials surname
     |
     \u{l_adam_name_last_tl} , \s \u{l_adam_name_first_tl}     % surname, name
     |
     \u{l_adam_name_last_tl} , \s \u{l_adam_name_initials_tl}  % surname, initials
    )
   }
   { \c{textbf} \cB\{ \1 \cE\} }
   \l__adam_name_input_tl
  % print
  \tl_use:N \l__adam_name_input_tl
 }

\ExplSyntaxOff

\begin{document}

  \definename{John Doe}

  \makebold{His name was John Doe.}

  \makebold{His name was J. Doe.}

  \makebold{His name was Doe, J..}

  \definename{John T. Doe}

  \makebold{His name was John T. Doe.}

  \makebold{His name was J. T. Doe.}

  \makebold{His name was Doe, J. T..}

\end{document}

Expected output:

His name was John Doe.

His name was Doe, John.

His name was J. Doe.

His name was Doe, J..

His name was John T. Doe.

His name was J. T. Doe.

His name was Doe, J. T..

2

You can use \prop_set_from_keyval:Nn instead of defining keys, but that's not the main point.

Here I define \update to populate the property list and also to call \adam_name_define:x to extract the name property. Here you see one of the advantages of expl3: the function is just a variant of \adam_name_define:n which does full expansion of its argument before doing the work.

See the other answer for comments to the regex code.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\definename}{m}
 {
  \adam_name_define:n { #1 }
 }

\NewDocumentCommand{\makebold}{m}
 {
  \adam_name_makebold:n { #1 }
 }

\NewDocumentCommand{\makeboldlastname}{m}
 {
  \adam_name_makebold_lastname:n { #1 }
 }

\NewDocumentCommand{\update}{m}
 {
  \prop_clear:N \l_adam_name_bio_prop
  \prop_set_from_keyval:Nn \l_adam_name_bio_prop { #1 }
  \adam_name_define:x { \prop_item:Nn \l_adam_name_bio_prop { name } }
 }

\prop_new:N \l_adam_name_bio_prop
\tl_new:N \l_adam_name_full_tl
\tl_new:N \l_adam_name_first_tl
\tl_new:N \l_adam_name_last_tl
\tl_new:N \l_adam_name_initials_tl
\tl_new:N \l__adam_name_input_tl

\cs_new_protected:Nn \adam_name_define:n
 {
  \tl_set:Nn \l_adam_name_full_tl { #1 }
  \tl_set_eq:NN \l_adam_name_first_tl \l_adam_name_full_tl
  \tl_set_eq:NN \l_adam_name_last_tl \l_adam_name_full_tl
  \regex_replace_once:nnN { (.*)\s[^\s]*\Z } { \1 } \l_adam_name_first_tl
  \regex_replace_once:nnN { .*\s([^\s]*)\Z } { \1 } \l_adam_name_last_tl
  \tl_set_eq:NN \l_adam_name_initials_tl \l_adam_name_first_tl
  \regex_replace_all:nnN { ([[:alpha:]])[[:alpha:]]+ } { \1. } \l_adam_name_initials_tl
 }
\cs_generate_variant:Nn \adam_name_define:n { x }

\cs_new_protected:Nn \adam_name_makebold:n
 {
  \tl_set:Nn \l__adam_name_input_tl { #1 }
  % full name
  \regex_replace_once:nnN
   {
    (
     \u{l_adam_name_full_tl}                                   % name surname
     |
     \u{l_adam_name_initials_tl} \s \u{l_adam_name_last_tl}    % initials surname
     |
     \u{l_adam_name_last_tl} , \s \u{l_adam_name_first_tl}     % surname, name
     |
     \u{l_adam_name_last_tl} , \s \u{l_adam_name_initials_tl}  % surname, initials
    )
   }
   { \c{textbf} \cB\{ \1 \cE\} }
   \l__adam_name_input_tl
  % print
  \tl_use:N \l__adam_name_input_tl
 }

\cs_new_protected:Nn \adam_name_makebold_lastname:n
 {
  \tl_set:Nn \l__adam_name_input_tl { #1 }
  \regex_replace_once:nnN
   { (\u{l_adam_name_last_tl}) }
   { \c{textbf} \cB\{ \1 \cE\} }
   \l__adam_name_input_tl
  \tl_use:N \l__adam_name_input_tl
 }

\ExplSyntaxOff

\begin{document}

\update{
  name=John Doe,
  town=London,
  birth=1888-05-01,
}

\makebold{His name was John Doe.}

\makebold{His name was J. Doe.}

\makebold{His name was Doe, John.}

\makebold{His name was Doe, J. again.}

\makeboldlastname{Again, Doe was his last name.}

\makebold{Jackson, Bob and J. Doe.}

\update{
  name=John T. Doe,
  town=New York,
}

\makebold{His name was John T. Doe.}

\makebold{His name was J. T. Doe.}

\makebold{His name was Doe, John T. again.}

\makebold{His name was Doe, J. T. again.}

\makeboldlastname{Again, Doe was his last name.}

\definename{Brutus Cyclops Dull}

\makebold{His name was Brutus Cyclops Dull.}

\makebold{His name was B. C. Dull.}

\makebold{His name was Dull, Brutus Cyclops again.}

\makebold{His name was Dull, B. C. again.}

\makeboldlastname{Again, Dull was his last name.}

\end{document}

enter image description here

  • Thank you! The trouble with this is that \update needs to be called behind the scenes within a class file. In other words, before \begin{document}. Also, the current version doesn't work to boldface the author name when overriding bibitem and parsing the second argument as an input to \makebold. – Adam Erickson Jan 19 at 1:10
  • Nevermind! I have a version working now using the original key definitions. The only thing I'm having trouble with is that it is only applying boldfacing to the last bibliography entry for some reason...? – Adam Erickson Jan 19 at 1:41
  • Also, expl3 is quickly growing on me now that I'm starting to understand it. – Adam Erickson Jan 19 at 1:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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