/usr/share/perl5/LaTeXML/Package/lxRDFa.sty.ltxml is in latexml 0.8.1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 | # -*- mode: Perl -*-
# /=====================================================================\ #
# | lxRDFa | #
# | LaTeXML support for RDFa | #
# |=====================================================================| #
# | Part of LaTeXML: | #
# | Public domain software, produced as part of work done by the | #
# | United States Government & not subject to copyright in the US. | #
# |---------------------------------------------------------------------| #
# | Bruce Miller <bruce.miller@nist.gov> #_# | #
# | http://dlmf.nist.gov/LaTeXML/ (o o) | #
# \=========================================================ooo==U==ooo=/ #
package LaTeXML::Package::Pool;
use strict;
use warnings;
use LaTeXML::Package;
#======================================================================
# Context
# \lxRDFaPrefix{prefix}{initialurl}
# Associates a prefix with the given (partial) URI
# for use in RDFa Compact URI's.
# These associations are global, not attached to the current node.
# If prefix is empty, this defines the vocabulary(?)
DefPrimitive('\lxRDFaPrefix{}{}', sub {
my ($stomach, $prefix, $url) = @_;
$prefix = ToString(Expand($prefix));
$url = CleanURL(ToString(Expand($url)));
if ($prefix) {
AssignMapping('RDFa_prefixes', $prefix => $url); }
else {
AssignValue('RDFa_vocabulary' => $url, 'global'); }
return; });
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Keywords for RDF Attributes
#======================================================================
# about: Establishes the subject for predicates appearing on the current element or descendants.
# about can be SafeCURIE, CURIE or IRI;
# Or, if the keyword is of the form \ref{label} or #id,
# it actually sets the aboutlabelref or aboutidref attribute (resp).
# These will be resolved back to a IRI for about during postprocessing.
# Note, however, that otherwise, the about need not be an explicit reference
# to a part of the document; it can be 'vitual'.
DefKeyVal('RDFa', about => 'Semiverbatim');
#======================================================================
# resource: Specifies the object of the a @property on the same element,
# AND specifies the subject for any predicates on descendant elements (chaining)
# resource can be SafeCURIE, CURIE or IRI;
# Or, if \ref{label} or #id, specifies resourcelabelref or resourceidref attribute.
DefKeyVal('RDFa', resource => 'Semiverbatim');
#======================================================================
# typeof : if @resource is on the same element, it forms a new triple indicating the type
# Otherwise, it creates an anonymous resource (blank node or bnode) with that type
# typeof can be a space separated list of: Term, CURIE or Abs. IRI
DefKeyVal('RDFa', typeof => 'Semiverbatim'); # space sep list of: Term, CURIE or Abs. IRI
#======================================================================
# property: specifies predicate(s) and asserts that the current subject is related to object
# * subject is @about on same element, or @resource/@typeof on ancestor, or document root;
# * object is @resource, @href, @content, @typeof on same element, or the text content
# resource can be a space separated list of: Term, CURIE or Abs. IRI.
DefKeyVal('RDFa', property => 'Semiverbatim');
#======================================================================
# rel : Exactly the same as @property, except that
# * can form multiple triples,
# * the objects being nearest @resource,@href on same or descendent
# rel can be a space separated list of: Term, CURIE or Abs. IRI.
DefKeyVal('RDFa', rel => 'Semiverbatim');
#======================================================================
# rev : Exactly the same as @rel, except that subject & object are reversed.
# rev can be a space separated list of: Term, CURIE or Abs. IRI
DefKeyVal('RDFa', rev => 'Semiverbatim');
#======================================================================
# content: specifies the object as a plain string in place of the element's content().
DefKeyVal('RDFa', content => 'Semiverbatim'); # CDATA
#======================================================================
# datatype: specifies the datatype of the content/content()
DefKeyVal('RDFa', datatype => 'Semiverbatim'); # Term, CURIE or Abs. IRI
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# href : specifies the object of a predicate.
# It is similar to @resource but does not chain to indicate subject
# @labelref, @idref and @href, and thus <ltx:ref>, can thus participate
# in RDFa by indicating the object of a predicate.
#======================================================================
# src : also indicates the object of a predicate
# @src doesn't appear directly in LaTeXML's schema,
# but <ltx:graphics @source> does, and is mapped to <img src..> in html.
# Should @source then act as an object?
#======================================================================
# Decipher the RDF Keywords into a hash of RDF attributes,
# accounting for \ref{label} or #id in the about and resource keywords
sub RDFAttributes {
my ($keyvals) = @_;
$keyvals = $keyvals->beDigested($STATE->getStomach);
my $hash = GetKeyVals($keyvals);
my $x;
foreach my $key (qw(about resource)) {
if (my $value = $$hash{$key}) {
if ((ref $value eq 'LaTeXML::Core::Whatsit')
&& ($value->getDefinition->getCSName eq '\ref')) {
$$hash{ $key . 'labelref' } = CleanLabel($value->getArg(2));
delete $$hash{$key}; }
elsif (($x = ToString($value)) && ($x =~ /^#(.+)$/)) {
$$hash{ $key . 'idref' } = CleanID($1);
delete $$hash{$key}; }
else {
$$hash{$key} = CleanURL($value); } } } # at least clean it.
return $hash; }
# It ought to be wrong to put resource (or resourceXXref) attributes on an ltx:ref...
# Given the RDF Keywords, and content (if any) check/complete the RDF triple
# Presumably an anonymous subject or object isn't sufficient?
sub RDFTriple {
my ($keyvals, $content) = @_;
my $attr = RDFAttributes($keyvals);
if (!($$attr{about} || $$attr{aboutlabelref} || $$attr{aboutidref})) {
$$attr{about} = ''; } # Silently make the triple about the entire document
if (!($$attr{property} || $$attr{rel} || $$attr{rev})) {
Warn('expected', 'property', $keyvals,
"Expected 'property' or 'rel' or 'rev' in RDF attributes"); }
if (!($$attr{content} || $$attr{resource} || $$attr{resourcelabelref} || $$attr{resourceidref}
|| ($content && scalar($content->unlist)))) {
Warn('expected', 'resource', $keyvals,
"Expected 'resource' or 'content' in RDF attributes"); }
return $attr; }
#======================================================================
# Adding RDF Attributes to arbitrary LaTeXML Markup.
# \lxRDFa{keywordpairs} "RDF attributes"
# Add any RDF attributes to the _current_ node.
# You are responsible for how the attributes relate to those
# in both parent and children nodes, such as establishing
# of default subject or objects, chaining and so forth.
DefConstructor('\lxRDFa [Semiverbatim] RequiredKeyVals:RDFa', sub {
my ($document, $xpath, $kv) = @_;
my ($save, $node);
if ($xpath) {
$save = $document->getNode;
$node = $document->findnode(ToString($xpath), $save); }
else {
$save = $document->floatToAttribute('property'); # pic arbitrary rdf attribute
$node = $document->getElement; }
my $attr = RDFAttributes($kv);
foreach my $k (sort keys %$attr) {
# use direct method ($doc method doesn't skips about="", which we need!)
$node->setAttribute($k => ToString($$attr{$k})); }
$document->setNode($save); });
#======================================================================
# \lxRDF{keyvals}[content] "Add RDF triple"
# Add an RDF triple to the document.
# Create an (invisible) metadata container, with the given RDF attributes.
# This can appear anywhere in the document, including in the preamble.
# This version of \lxRDF is for use in the preamble.
# It is complicated because \@add@frontmatter provides us no way to
# do the extra processing of the RDF Keywords.
DefPrimitive('\lxRDF@preamble[]RequiredKeyVals:RDFa', sub {
my ($stomach, $content, $kv) = @_;
# Since this gets digested in the preamble...
my $inpreamble = LookupValue('inPreamble');
AssignValue(inPreamble => 0);
my $attr = RDFTriple($kv); # require complete triple, here.
push(@{ LookupValue('frontmatter')->{'ltx:rdf'} },
['ltx:rdf', { map { ($_ => ToString($$attr{$_})) } keys %$attr },
($content ? (Digest(Tokens(T_BEGIN, $content, T_END))) : ())]);
AssignValue(inPreamble => $inpreamble);
return; });
# This version of \lxRDF is for use in the document body.
DefConstructor('\lxRDF@body[] RequiredKeyVals:RDFa', sub {
# "^<ltx:rdf %&RDFTriple(#2,#1)>#1</ltx:rdf>",
my ($document, $content, $kv) = @_;
if (my $savenode = $document->floatToElement('ltx:rdf')) {
my $rdf = $document->openElement('ltx:rdf');
# a bit of trouble to add empty elements!
my $attr = RDFTriple($kv, $content);
foreach my $k (keys %$attr) {
# use direct method ($doc method doesn't skips about="", which we need!)
$rdf->setAttribute($k => ToString($$attr{$k})); }
$document->absorb($content) if $content;
$document->closeElement('ltx:rdf');
$document->setNode($savenode); } },
alias => '\lxRDF');
# Start with \lxRDF bound to the preamble form, which saves the rdf as frontmatter
Let('\lxRDF', '\lxRDF@preamble');
# When the document's begun, switch to the inline version.
PushValue('@at@begin@document', (T_CS('\let'), T_CS('\lxRDF'), T_CS('\lxRDF@body')));
#======================================================================
# \lxRDFAnnotate{keyvals}{text} "Add RDF Annotated text"
# Create a visible text node, with the given RDF attributes.
# This node inherits whatever RDF context exists at that point,
# such as the current subject, chaining or whatever.
# Thus, you may want to give an explicit about.
DefConstructor('\lxRDFAnnotate RequiredKeyVals:RDFa {}',
"<ltx:text %&RDFAttributes(#1,#2)>#2</ltx:text>");
#======================================================================
# Other shorthands might be useful, like
# DefMacro('\lxRDFResource[]{}{}','\@lxRDF{about={#1},predicate={#2},resource={#3}}');
# DefMacro('\lxRDFProperty[]{}{}','\@lxRDF{about={#1},predicate={#2},content={#3}}');
# or maybe leave to other applications, till I get some feedback ?
# Another useful thing might be the ability to attribute
# the current node, the previous node, the parent node...?
#======================================================================
1;
|