0

Thanks for a great community and site! A lot of knowledge here and I am reaching out to with the hope that you can suggest a solution or point me in the right direction. I have tried to search for similar queries but I have not yet found something that took me all the way.

Here is the problem.

I am doing a book on quotes and as you can imagine, there are some people who reoccur with many quotes and I want to ensure that there is a consistent attribution for those who are cited multiple times throughout out the book. In the best of worlds I would like to have a shortcut to call that would contain a number of strings. Some attempts I have tried look as follows:

\def\ReplaceStr#1{VladimirNabokov}[0]{

    {Vladimir Nabokov}
    {1899-1977}
    {Novelist, poet, translator, and professor in entomology}
    {Russia, USA, and Switzerland}
}

\newcommand{\authorVladimirNabokov}[0]{

    {Vladimir Nabokov}
    {1899-1977}
    {Novelist, poet, translator, and professor in entomology}
    {Russia, USA, and Switzerland}
}

The above would be general information included in the attributions. In addition to a specific quote, I would also like to add specific information on where the quote was first given (in this case, not using bib items).

Optimally I would like to take take the shortcut and send it as parameter/set of strings to my command myattrib that takes care of font formatting etc for the different parameters

For example, below would be two types of attributions, one general without any specific reference, and the second one would be the general information + specific information where the quote occurred.

\myattrib{\authorVladimirNabokov}

\myattriblong{\authVladimirNabokov{In}{the book "The Eye}}

As you can see, my futile attempts with using ReplaceStr as one alternative and new command as a second alternative did not work out well… it displays all the information but both fail to treat the set of strings as a set of strings; instead everything becomes one singular string in the processing.

Thanks in advance for any help! Kindly, Jorgen


Here are some additional information in response to the requests: Here is a an example quote how I would like it in the text:

"I am looking forward very much to getting back to Cambridge, and being able to say what I think and not to mean what I say: two things which at home are impossible. Cambridge is one of the few places where one can talk unlimited nonsense and generalities without anyone pulling one up or confronting one with them when one says just the opposite the next day."
Bertrand Russell, (1872-1970)
Noble prize laureate, British philosopher and logician etc
In “Letter to Alys Pearsall Smith (1893); published in The Selected Letters of Bertrand Russell, Volume 1: The Private Years (1884–1914), edited by Nicholas Griffin”

The reason why I did not see bib items as viable is merely due to my understanding that it is used for generating a bibliography at the very end of a collection, while here I want to include all the data next to the quote. The other thing with bib items is that, for example, say that I have 20 quotes of author X, I want only one place where I give the generic information about the author and not in 20 different bib items - this in order to simplify any updates that are likely for author X (for example in the revisioning in the publishing process).

Indeed, maybe there is a feasible approach with bib items that I don’t know of. My primary use of latex throughout the years has been for writing scientific articles so my tinkering with Latex and knowledge thereof are around what is typical of scientific publishing, where you might cite an article numerous times. Here in the quote collection, you only cite a quote once but you have the same author numerous times.

Hope this clarifies what I am hoping to achieve.

Thanks again.

  • Welcome to TeX.SX! Could you please add a bit more about the wanted output? Your "set of strings" is a set of TeX groups and as TeX ignores multiple spaces and especially line breaks the substitution for your command will be a long line of tokens… – TeXnician Dec 30 '18 at 8:32
  • 1
    At least the second task (list the source of a quote) looks like a prime example for use of .bib files. Is there any reason why you don't want to use them? It would certainly not be impossible to implement a non-.bib-file-pseudo bibliography, especially if you don't need anything super fancy, but why do that if there already is a solution readily available? In fact the first task (a database of people) can also be done with .bib files, see tex.stackexchange.com/q/79342/35864. – moewe Dec 30 '18 at 9:33
  • Many thanks Moewe - have not seen that approach before. I am going to look into that approach right away. In the meantime I did also expand my initial question with a bit more detail. – Jorgen Dec 30 '18 at 11:50
1

I think this is a task where .bib file come in very handy. Certainly giving the sources of a quotation is what .bib files were made for.

As Create a register of persons with biblatex demonstrates it is possible to use biblatex for a index for people. Similarly Ulrike Fischer showed in her TUGboat article (https://tug.org/TUGboat/tb35-3/tb111fischer.pdf) that biblatex can be used as an address database. With biblatex's \fullcite command there is no need for a full bibliography in the end.

Here is a not very sophisticated proof of concept inspired by Guido's answer to Create a register of persons with biblatex.

\documentclass[british]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{babel}
\usepackage{csquotes}

\usepackage{filecontents}
\begin{filecontents}{person.dbx}
\DeclareDatamodelEntrytypes{person}
\DeclareDatamodelFields[type=list,datatype=name]{name}
\DeclareDatamodelFields[type=list,datatype=literal]{profession,country}
\DeclareDatamodelEntryfields[person]{name,date,profession,country}
\end{filecontents}

\begin{filecontents}{\jobname.bib}
@person{vladnab,
  name       = {Vladimir Nabokov},
  date       = {1899/1977},
  profession = {Novelist and poet and translator and professor in entomology},
  country    = {Russia and USA and Switzerland},
}
@person{russell,
  name       = {Bertrand Russell},
  date       = {1872/1970},
  profession = {Noble prize laureate and philosopher and logician},
  country    = {United Kingdom},
}
@inbook{alys,
  title     = {Letter to Alys Pearsall Smith (1893)},
  maintitle = {The Selected Letters of Bertrand Russell},
  volume    = {1},
  booktitle = {The Private Years (1884–1914)},
  editor    = {Nicholas Griffin},
}
\end{filecontents}

\usepackage[datamodel=person,backend=biber,style=authortitle,maxitems=999]{biblatex} 
\usepackage{hyperref}

\DeclareBibliographyDriver{person}{%
  \usebibmacro{bibindex}%
  \usebibmacro{begentry}%
  \printnames{name}%
  \newunit
  \printdate
  \newunit
  \printlist{profession}%
  \newunit
  \printlist{country}%
  \setunit{\bibpagerefpunct}\newblock
  \usebibmacro{pageref}%
  \newunit\newblock
  \iftoggle{bbx:related}
    {\usebibmacro{related:init}%
     \usebibmacro{related}}
    {}%
  \usebibmacro{finentry}}

\DeclareCiteCommand{\fullciteperson}
  {\usebibmacro{prenote}}
  {\usebibmacro{citeindex}%
   \usedriver{}{\thefield{entrytype}}}
  {\multicitedelim}
  {\usebibmacro{postnote}}

\addbibresource{\jobname.bib}

\makeatletter
\newenvironment{jorgenquote}[2]
{%
  \def\jorgenquote@temp@nameid{#1}%
  \def\jorgenquote@temp@citekey{#2}%
  \begingroup
  \quote
}
{%
  \endquote
  \endgroup
  \par
  \expandafter\fullciteperson\expandafter{\jorgenquote@temp@nameid}%
  \par
  \expandafter\fullcite\expandafter{\jorgenquote@temp@citekey}%
}
\makeatother

\begin{document}
\fullciteperson{vladnab}

\begin{jorgenquote}{russell}{alys}
I am looking forward very much to getting back to Cambridge, and being able to say what I think and not to mean what I say: two things which at home are impossible. Cambridge is one of the few places where one can talk unlimited nonsense and generalities without anyone pulling one up or confronting one with them when one says just the opposite the next day.
\end{jorgenquote}
\end{document}

Anyway, here is a simple and naive implementation of a database of people with etoolbox.

You can define a new person with \NewPerson{<id>}{<name>}{<date>}{<profession>}{<countries>}. The <id> is used as an internal label/identifier for the person, it should be unique and should only contain characters that are safe as command names (if you use only lowercase ASCII without the characters special for TeX, you should be fine). All properties for a person are saved in internal macros jorgpd@<id>@<property>, the contents of those macros can be retrieved with \csuse.

\documentclass[british]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{babel}
\usepackage{etoolbox}

\newcommand*{\NewPerson}[5]{%
  \csdef{jorgpd@#1@name}{#2}%
  \csdef{jorgpd@#1@date}{#3}%
  \csdef{jorgpd@#1@professsion}{#4}%
  \csdef{jorgpd@#1@countries}{#5}%
}

\newcommand*{\AttributePerson}[1]{%
  \csuse{jorgpd@#1@name}%
  \space
  (\csuse{jorgpd@#1@date})%
  \space was a\space
  \csuse{jorgpd@#1@professsion}%
  \space from\space
  \csuse{jorgpd@#1@countries}.
}

\begin{document}
\NewPerson{vladnab}
  {Vladimir Nabokov}
  {1899-1977}
  {Novelist, poet, translator, and professor in entomology}
  {Russia, USA, and Switzerland}

\AttributePerson{vladnab}
\end{document}

Some people may prefer a key-value interface for examples like this, so I copied egreg's answer to xparse and key value arguments that implements a key-value interface with xparse and LaTeX3.

This time \NewPerson has the syntax \NewPerson{<id>}{<prop_1>=<val_1>,...,<prop_n>=<val_n>}, where <prop_i> is one of name, date, profession or country. The data for one person are stored in a so-called property list.

\documentclass[british]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{babel}

\usepackage{expl3}
\usepackage{xparse}
\ExplSyntaxOn
% keys
\keys_define:nn { jorgen/person }
{
  name       .tl_set:N = \l_jorgen_person_name_tl,
  date       .tl_set:N = \l_jorgen_person_date_tl,
  profession .tl_set:N = \l_jorgen_person_profession_tl,
  countries  .tl_set:N = \l_jorgen_person_countries_tl,
}

% user level commands
\NewDocumentCommand{\NewPerson}{m m}
{
  \jorgen_newperson:nn { #1 } { #2 }
}

\NewDocumentCommand{\AttributePerson}{m}
{
  \jorgen_attributeperson:n { #1 }
}

% internal functions
\cs_new_protected:Npn \jorgen_newperson:nn #1 #2
{
  \group_begin:
  \prop_new:c { g_jorgen_person_#1_prop }
  \keys_set:nn { jorgen/person } { #2 }
  \prop_gput:cnV { g_jorgen_person_#1_prop } { name }       \l_jorgen_person_name_tl
  \prop_gput:cnV { g_jorgen_person_#1_prop } { date }       \l_jorgen_person_date_tl
  \prop_gput:cnV { g_jorgen_person_#1_prop } { profession } \l_jorgen_person_profession_tl
  \prop_gput:cnV { g_jorgen_person_#1_prop } { countries }  \l_jorgen_person_countries_tl
  \group_end:
}

\cs_new:Npn \jorgen_person_getvalue:nn #1 #2
{
  \prop_item:cn { g_jorgen_person_#1_prop } { #2 }
}
\cs_new_protected:Npn \jorgen_attributeperson:n #1
{
  \jorgen_person_getvalue:nn { #1 } { name }~
  (\jorgen_person_getvalue:nn { #1 } { date })~
  was~a~
  \jorgen_person_getvalue:nn { #1 } { profession }~
  from~
  \jorgen_person_getvalue:nn { #1 } { countries }.
}
\ExplSyntaxOff

\begin{document}
\NewPerson{vladnab}{
  name       = {Vladimir Nabokov},
  date       = {1899-1977},
  profession = {Novelist, poet, translator, and professor in entomology},
  countries  = {Russia, USA, and Switzerland},
}

\AttributePerson{vladnab}
\end{document}

The output from both examples is the same

Vladimir Nabokov (1899-1977) was a Novelist, poet, translator, and professor in entomology from Russia, USA, and Switzerland.

  • Wow, many thanks Moewe for your valuable input and showing me a way forward. This helps me a lot. I will give this a serious shot. I might come back with a question or two if there is something I do not fully understand. Again, many thanks for this. My best wishes, Jorgen – Jorgen Dec 30 '18 at 13:01

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.