4

I have a command (\people[⟨options⟩]{⟨name⟩}) for entering people. Its optional argument lets the user specify possible people's (possibly multiple) attribute(s) with a (l3keys) key–value system: attribute={⟨value A⟩},attribute={⟨value B⟩},... (these values are internally put to a sequence).

Now, some people may share the same attribute's ⟨value⟩s with people already entered and, in such a case, these ⟨value⟩s have to be treated differently. To this end, there is another key–value: duplicateattribute={⟨value⟩}.

I could manage with two parallel sequences ("attribute" and "duplicateattribute") as in the following MWE (involving datatool):

\documentclass{article}
\usepackage{xparse}
\usepackage{datatool}

\ExplSyntaxOn
\DTLnewdb{_mymodule_people}

\seq_new:N \l_mymodule_people_attributes_seq
\seq_new:N \l_mymodule_people_duplicateattributes_seq

\keys_define:nn { mymodule/people } {%
  attribute .code:n = \seq_put_right:Nn \l_mymodule_people_attributes_seq {#1},
  duplicateattribute .code:n =\seq_put_right:Nn \l_mymodule_people_duplicateattributes_seq {#1}
}

\cs_new_protected:Nn \_mymodule_enter_people:n
 {
  \DTLnewrow{_mymodule_people}
  \DTLnewdbentry{_mymodule_people}{name}{#1}
  \DTLnewdbentry{_mymodule_people}{attribute}{\tl_to_str:n{#1}}
  \DTLnewdbentry{_mymodule_people}{duplicateattribute}{\tl_to_str:n{#1}}
 }

\NewDocumentCommand \people { O{} m }
{
  \seq_clear:N \l_mymodule_people_attributes_seq
  \seq_clear:N \l_mymodule_attributes_seq
  \seq_clear:N \l_mymodule_people_duplicateattributes_seq

  \keys_set:nn { mymodule/people } { #1 }

  \_mymodule_enter_people:n {#2}

  \seq_new:c { g_mymodule_attributes_ \tl_to_str:n{#2} _seq }
  \seq_gset_eq:cN { g_mymodule_attributes_ \tl_to_str:n{#2} _seq } \l_mymodule_people_attributes_seq

  \seq_new:c { g_mymodule_duplicateattributes_ \tl_to_str:n{#2} _seq }
  \seq_gset_eq:cN { g_mymodule_duplicateattributes_ \tl_to_str:n{#2} _seq }
  \l_mymodule_people_duplicateattributes_seq

%  \seq_show:c { g_mymodule_attributes_ \tl_to_str:n{#2} _seq }
%  \seq_show:c { g_mymodule_duplicateattributes_ \tl_to_str:n{#2} _seq }
}
\ExplSyntaxOff
\begin{document}
\people                                {People 0}
\people[attribute          = {value A}]{People 1}
\people[attribute          = {value B},
        attribute          = {value C}]{People 2}
\people[attribute          = {value D},
        duplicateattribute = {value B},
        attribute          = {value E}]{People 3}
\end{document}

But this has the drawback that the duplicate attribute's ⟨value⟩s have to be duplicated (see value B in the example: in real life, the values may be much longer): that's boring and problematic from a maintenance point of view.

Hence, I'd like to be able to optionally label (tag) ⟨value⟩s in order to reuse them elsewhere just by duplicating their label and not themselves as a whole, e.g. in the following way:

[...]
\people[attribute          = [tagB]{value B},
        attribute          = {value C}]{People 2}
\people[attribute          = {value D},
        duplicateattribute = {tagB},
        attribute          = {value E}]{People 3}
[...]

where:

  • value B is tagged with tagB ([tagB]{value B}) and reused elsewhere (duplicateattribute = {tagB})
  • the other values are not tagged because not reused elsewhere.

Is it possible?

  • 1
    Wouldn't it be simpler to declare duplicate attributes outside a \people command? By the way, what you do with datatool seems an application for a property list. – egreg Nov 27 '15 at 21:23
  • @egreg Only the duplicate ones? And it is necessary to specify who share what attributes' values, e.g. the people whose attributes have also the value B value. About datatool, I suspect for a long time now that the intersection between this package's and expl3 property lists' features is not empty, but could you be more explicit? – Denis Bitouzé Nov 28 '15 at 6:23
  • I was thinking to something like \defineduplicateattribute{tag}{text}, so in a \people command you can say \people[attribute=foo,duplicateattribute=tag]{X Y}. Having all tags in a fixed place, say just before \begin{document} may help maintenance. – egreg Nov 28 '15 at 10:04
  • @egreg That is in direct conflict with my taste of symmetry: ordinary attributes treated differently from duplicate ones :) In fact, my problem is a many-to-many one (many people to many attributes) and I first considered defining people in one hand, attributes in the other hand and, finally, the many-to-many pairs. But this has the drawback all the people and all the attributes have to be tagged, even if unnecessary: if a people has non shared attributes, neither him/her nor his/her attributes should have to be tagged ideally. In conclusion, I guess I would follow your advice :) – Denis Bitouzé Nov 28 '15 at 16:26

Your Answer

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

Browse other questions tagged or ask your own question.