Background
Looking to convert XHTML metadata into document variables.
Code
The parts include:
- XHTML metadata — includes user-defined metadata
- XML setups — applies XML filters
- Metadata setups — converts setups to document variables
- Document variables — example variable usage
A short, self-contained, compilable example follows the parts explanation.
XHTML metadata
Users may provide arbitrary document metadata through a GUI:
Users may then export the document as XHTML, which produces the following example XHTML header:
<head>
<title>Heuristic View of Light</title>
<meta content="science, nature" name="keywords"/>
<meta content="Milena Marić Einstein" name="author"/>
<meta content="Albert Einstein" name="byline"/>
<meta content="4500" name="count"/>
<meta content="1905" name="copyright"/>
<meta content="Annalen der Physik" name="journal"/>
</head>
Note that the metadata names will be sanitized for TeX-compatibility.
XML setups
In the following XML setups, the first four have "special" behaviour, but the remainder are identical (save the name):
\startxmlsetups xml:html
% special setups
\xmlfilter{#1}{/head/title/command(xml:title)}
\xmlfilter{#1}{/head/meta[@name='author']/command(xml:author)}
\xmlfilter{#1}{/head/meta[@name='byline']/command(xml:byline)}
\xmlfilter{#1}{/head/meta[@name='keywords']/command(xml:keywords)}
% virtually identical setups
\xmlfilter{#1}{/head/meta[@name='address']/command(xml:address)}
\xmlfilter{#1}{/head/meta[@name='phone']/command(xml:phone)}
\xmlfilter{#1}{/head/meta[@name='email']/command(xml:email)}
\xmlfilter{#1}{/head/meta[@name='count']/command(xml:count)}
\xmlflush{#1}
\stopxmlsetups
Metadata setups
The setups for the virtually identical metadata values follow the same pattern:
% create email document variable
\startxmlsetups xml:email
\setupdocument[email={\xmlatt{#1}{content}}]
\stopxmlsetups
% create count document variable
\startxmlsetups xml:count
\setupdocument[count={\xmlatt{#1}{content}}]
\stopxmlsetups
Document variables
Here's an example usage of the document variables:
\startsetups document:start
\starttitlemakeup
\setupinterlinespace[line=14pt]
{%
\documentvariable{author}\hfill
\TextNumberFormat{\documentvariable{count}} words
}\break
\documentvariable{address}\break
\documentvariable{phone}\break
\documentvariable{email}\break
\vfill
\startalignment[middle]
\WORD{\documentvariable{title}}
\blank[big]
by
\blank[big]
\documentvariable{byline}
\stopalignment
\vfill
\stoptitlemakeup
\stopsetups
In this fashion, users may define variables in the GUI, then reference them using the \documentvariable{*}
macro.
SSCCE
Here's a self-contained example demonstrating the issue:
\startbuffer[xdoc]
<html>
<head>
<meta content="Milena Marić Einstein" name="author"/>
<meta content="Annalen der Physik" name="journal"/>
</head>
<body>
</body>
</html>
\stopbuffer
\startxmlsetups xml:xhtml
\xmlsetsetup{\xmldocument}{*}{-}
\xmlsetsetup{\xmldocument}{html|body}{xml:*}
\xmlsetsetup{\xmldocument}{head}{xml:meta}
\stopxmlsetups
\xmlregistersetup{xml:xhtml}
\startxmlsetups xml:html
\xmlfilter{#1}{/head/meta[@name='author']/command(xml:author)}
% What goes here?
%\xmlfilter{#1}{/head/meta[@name='journal']/command(xml:journal)}
\xmlflush{#1}
\stopxmlsetups
\startxmlsetups xml:author
\setupdocument[author={\xmlatt{#1}{content}}]
\setupdocument[metadata:author={\xmlatt{#1}{content}}]
\setupinteraction[author={\documentvariable{author}}]
\stopxmlsetups
% How can this be generalized?
%\startxmlsetups xml:journal
%\setupdocument[journal={\xmlatt{#1}{content}}]
%\stopxmlsetups
\startxmlsetups xml:body
\startdocument
Author: \documentvariable{author}
\par
Journal: \documentvariable{journal}
\stopdocument
\stopxmlsetups
\xmlprocessbuffer{main}{xdoc}{}
Problem
Adding new metadata values (subtitle, volume, license, software, etc.) requires updating the XML setups and metadata setups, which is a step I'd like to avoid.
Question
Given an XHTML document with arbitrary metadata name
and content
attributes, how would you automatically define document variables for each of the metadata names?
That is, given:
<meta content="Annalen der Physik" name="journal"/>
How would you ensure the usage of:
\documentvariable{journal}
When both journal and Annalen der Physik can be defined arbitrarily by the user?
Best Answer
From the mailing list, define dynamic variables based on XHTML metadata as follows:
Note that by calling the
xmlfilter
for thesetdocumentvariable
command first, it affords the opportunity to customize specific metadata variables.