3

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:

document metadata user interface

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?

1

1 Answer 1

2

From the mailing list, define dynamic variables based on XHTML metadata as follows:

\startxmlsetups xml:setdocumentvariable
   \setupdocument[\xmlatt{#1}{name}={\xmlatt{#1}{content}}]
\stopxmlsetups

\startxmlsetups xml:author
   \setupdocument[author={\xmlatt{#1}{content}}]
   \setupdocument[metadata:author={\xmlatt{#1}{content}}]
   \setupinteraction[author={\documentvariable{author}}]
\stopxmlsetups

\startxmlsetups xml:html
   \xmlfilter{#1}{/head/meta/command(xml:setdocumentvariable)}
   \xmlfilter{#1}{/head/meta[@name='author']/command(xml:author)}

   \startdocument
     \xmlflush{#1}
   \stopdocument
\stopxmlsetups

Note that by calling the xmlfilter for the setdocumentvariable command first, it affords the opportunity to customize specific metadata variables.

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.