1

I am thinking in creating a package to manage some metadata of books (like author, title, ...). This metadata will be defined in an external file and retrieved in the document. (This has nothing to do with the PDF metadata concept!). It would be easy if the metadata will consist only of values of a variable (a solution like What is the recommended way to assign a value to a variable and retrieve it for later use? using l3prop will work). But in my case I want to specify some behaviour, for example, when the value of the metadata is empty. I will like to assign a macro to be executed when the value is retrieved but empty.

The syntax of the metadata file will be something like this:

\setmetadata{author}{The name of the author}
\setmetadata[ifempty=\throwerror]{title}{The title}

And the values will be retrieved in the document

\getmetadata{author}

To implement this, I was wondering that the latex3 data table l3dt module was going to be useful. But it seems it has been removed from the code tree. My next approach will be to use a l3prop inside a l3prop. But before going deep on this, is it possible to nest property lists?

  • This is just one property list, as far as I can see. I'm not sure what “ifempty” refers to. What should \getmetadata do, precisely? – egreg Aug 19 '16 at 10:39
  • 1
    Why nesting? You could build a "content property list" and a "action property list". You should also look a biblatex. It already contains tons of tools to manage books. – Ulrike Fischer Aug 19 '16 at 10:43
  • Of each metadata key (author, title, ...) I would like to specify, for example, a what to do when it is empty (a choose between different macros), what to do if the key is already defined, what macro to use to format the value when retrieved, ... – TeXtnik Aug 19 '16 at 10:47
  • @UlrikeFischer Thanks for the idea of several property lists. The idea of the package is not for bibliographic information but I would have a look to see if I can reuse biblatex. – TeXtnik Aug 19 '16 at 11:00
  • What is l3dt? I have never heard of it. – Henri Menke Aug 19 '16 at 16:17
1

Does this provide an answer to your question? You actually don't need property lists within property lists.

\begin{filecontents*}{\jobname.input.tex}
\setmetadata{author}{The name of the author}
\setmetadata[ifempty=\throwerror]{title}{The title}
\end{filecontents*}
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn

\keys_define:nn { metadata }
  {
    ifempty .tl_set:N = \l_metadata_ifempty_tl
  }

\prop_new:N \g_metadata_prop

\cs_new_protected:Nn \metadata_gset:nn
  {
    \tl_if_empty:nTF { #2 }
      { 
        \tl_if_empty:NF \l_metadata_ifempty_tl
          { \tl_use:N \l_metadata_ifempty_tl }
      }
      { \prop_gput:Nnn \g_metadata_prop { #1 } { #2 } }
  }

\cs_new_protected:Nn \metadata_get:n
  {
    \prop_item:Nn \g_metadata_prop { #1 }
  }

\NewDocumentCommand \setmetadata { o m m }
  {
    \group_begin:
      \IfValueT { #1 }
        { \keys_set:nn { metadata } { #1 } }
      \metadata_gset:nn { #2 } { #3 }
    \group_end:
  }

\NewDocumentCommand \getmetadata { m }
  {
    \metadata_get:n { #1 }
  }

\ExplSyntaxOff
\begin{document}
\def\throwerror{***ERROR***}

\input{\jobname.input.tex}
\getmetadata{author}
\getmetadata{title}

\setmetadata[ifempty=\throwerror]{title}{}

\end{document}

Or maybe with LuaTeX? This provides a nice way to format your input file. Also you can process the database externally with Lua.

\begin{filecontents*}{\jobname.input.lua}
return {
  ["author"] = "The name of the author",
  ["title"] = "The title"
}
\end{filecontents*}
\documentclass{article}
\directlua{db = dofile"\jobname.input.lua"}
\def\getmetadata#1{\directlua{tex.sprint(db["\luaescapestring{#1}"]
    or "\noexpand\\throwerror")}}
\begin{document}
\def\throwerror{***ERROR***}

\getmetadata{author}

\getmetadata{journal}
\end{document}

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.