pyRdfa.host

Host language sub-package for the pyRdfa package. It contains variables and possible modules necessary to manage various RDFa host languages.

This module may have to be modified if a new host language is added to the system. In many cases the rdfa_core as a host language is enough, because there is no need for a special processing. However, some host languages may require an initial context, or their value may control some transformations, in which case additional data have to be added to this module. This module header contains all tables and arrays to be adapted, and the module content may contain specific transformation methods.

@summary: RDFa Host package @requires: Python version 3.8 or higher @requires: U{requestshttps://pypi.org/project/requests/2.32.3/}; version 2.32.3 or higher. @requires: U{rdflibhttps://pypi.org/project/rdflib/7.0.0/}; version 7.0.0 or higher. @requires: U{html5libhttps://pypi.org/project/html5lib/1.1/}; version 1.1 or higher. @organization: U{World Wide Web Consortiumhttp://www.w3.org} @author: U{Ivan Herman} @license: This software is available for use under the U{W3C® SOFTWARE NOTICE AND LICENSE}

@var content_to_host_language: a dictionary mapping a media type to a host language @var preferred_suffixes: mapping from preferred suffixes for media types; used if the file is local, ie, there is not HTTP return value for the media type. It corresponds to the preferred suffix in the media type registration @var initial_contexts: mapping from host languages to list of initial contexts @var accept_xml_base: list of host languages that accept the xml:base attribute for base setting @var accept_xml_lang: list of host languages that accept the xml:lang attribute for language setting. Note that XHTML and HTML have some special rules, and those are hard coded... @var warn_xmlns_usage: list of host languages that should generate a warning for the usage of @xmlns (for RDFa 1.1) @var accept_embedded_rdf_xml: list of host languages that might also include RDF data using an embedded RDF/XML (e.g., SVG). That RDF data may be merged with the output @var accept_embedded_turtle: list of host languages that might also include RDF data using a C{script} element. That RDF data may be merged with the output @var require_embedded_rdf: list of languages that must accept embedded RDF, ie, the corresponding option is irrelevant @var host_dom_transforms: dictionary mapping a host language to an array of methods that are invoked at the beginning of the parsing process for a specific node. That function can do a last minute change on that DOM node, eg, adding or modifying an attribute. The method's signature is (node, state), where node is the DOM node, and state is the L{Execution context<pyRdfa.state.ExecutionContext>}. @var predefined_1_0_rel: terms that are hardcoded for HTML+RDF1.0 and replace the initial context for that version @var beautifying_prefixes: this is really just to make the output more attractive: for each media type a dictionary of prefix-URI pairs that can be used to make the terms look better... @var default_vocabulary: as its name suggests, default @vocab value for a specific host language

  1# -*- coding: utf-8 -*-
  2"""
  3Host language sub-package for the pyRdfa package. It contains variables and possible modules necessary to manage various RDFa
  4host languages.
  5
  6This module may have to be modified if a new host language is added to the system. In many cases the rdfa_core as a host language is enough, because there is no need for a special processing. However, some host languages may require an initial context, or their value may control some transformations, in which case additional data have to be added to this module. This module header contains all tables and arrays to be adapted, and the module content may contain specific transformation methods.
  7
  8
  9@summary: RDFa Host package
 10@requires: Python version 3.8 or higher
 11@requires: U{requests<https://pypi.org/project/requests/2.32.3/>}; version 2.32.3 or higher.
 12@requires: U{rdflib<https://pypi.org/project/rdflib/7.0.0/>}; version 7.0.0 or higher.
 13@requires: U{html5lib<https://pypi.org/project/html5lib/1.1/>}; version 1.1 or higher.
 14@organization: U{World Wide Web Consortium<http://www.w3.org>}
 15@author: U{Ivan Herman<a href="http://www.w3.org/People/Ivan/">}
 16@license: This software is available for use under the
 17U{W3C® SOFTWARE NOTICE AND LICENSE<href="http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231">}
 18
 19@var content_to_host_language: a dictionary mapping a media type to a host language
 20@var preferred_suffixes: mapping from preferred suffixes for media types; used if the file is local, ie, there is not HTTP return value for the media type. It corresponds to the preferred suffix in the media type registration
 21@var initial_contexts: mapping from host languages to list of initial contexts
 22@var accept_xml_base: list of host languages that accept the xml:base attribute for base setting
 23@var accept_xml_lang: list of host languages that accept the xml:lang attribute for language setting. Note that XHTML and HTML have some special rules, and those are hard coded...
 24@var warn_xmlns_usage: list of host languages that should generate a warning for the usage of @xmlns (for RDFa 1.1)
 25@var accept_embedded_rdf_xml: list of host languages that might also include RDF data using an embedded RDF/XML (e.g., SVG). That RDF data may be merged with the output
 26@var accept_embedded_turtle: list of host languages that might also include RDF data using a C{script} element. That RDF data may be merged with the output
 27@var require_embedded_rdf: list of languages that must accept embedded RDF, ie, the corresponding option is irrelevant
 28@var host_dom_transforms: dictionary mapping a host language to an array of methods that are invoked at the beginning of the parsing process for a specific node. That function can do a last minute change on that DOM node, eg, adding or modifying an attribute. The method's signature is (node, state), where node is the DOM node, and state is the L{Execution context<pyRdfa.state.ExecutionContext>}.
 29@var predefined_1_0_rel: terms that are hardcoded for HTML+RDF1.0 and replace the initial context for that version
 30@var beautifying_prefixes: this is really just to make the output more attractive: for each media type a dictionary of prefix-URI pairs that can be used to make the terms look better...
 31@var default_vocabulary: as its name suggests, default @vocab value for a specific host language
 32
 33"""
 34
 35__version__ = "3.0"
 36
 37from .atom  import atom_add_entry_type
 38from .html5 import html5_extra_attributes, remove_rel
 39
 40class HostLanguage:
 41    """An enumeration style class: recognized host language types for this processor of RDFa. Some processing details may depend on these host languages. "rdfa_core" is the default Host Language is nothing else is defined."""
 42    rdfa_core = "RDFa Core"
 43    xhtml =     "XHTML+RDFa"
 44    xhtml5 =    "XHTML5+RDFa"
 45    html5 =     "HTML5+RDFa"
 46    atom =      "Atom+RDFa"
 47    svg =       "SVG+RDFa"
 48
 49# initial contexts for host languages
 50initial_contexts = {
 51    HostLanguage.xhtml :     ["http://www.w3.org/2011/rdfa-context/rdfa-1.1",
 52                              "http://www.w3.org/2011/rdfa-context/xhtml-rdfa-1.1"],
 53    HostLanguage.xhtml5 :    ["http://www.w3.org/2011/rdfa-context/rdfa-1.1"],
 54    HostLanguage.html5 :     ["http://www.w3.org/2011/rdfa-context/rdfa-1.1"],
 55    HostLanguage.rdfa_core : ["http://www.w3.org/2011/rdfa-context/rdfa-1.1"],
 56    HostLanguage.atom :      ["http://www.w3.org/2011/rdfa-context/rdfa-1.1"],
 57    HostLanguage.svg :       ["http://www.w3.org/2011/rdfa-context/rdfa-1.1"]
 58}
 59
 60beautifying_prefixes = {
 61    HostLanguage.xhtml    : {
 62        "xhv": "http://www.w3.org/1999/xhtml/vocab#"
 63    },
 64    # HostLanguage.html5    : {
 65    #     "xhv" : "http://www.w3.org/1999/xhtml/vocab#"
 66    # },
 67    # HostLanguage.xhtml5    : {
 68    #     "xhv" : "http://www.w3.org/1999/xhtml/vocab#"
 69    # },
 70    HostLanguage.atom : {
 71        "atomrel": "http://www.iana.org/assignments/relation/"
 72    }
 73}
 74
 75
 76accept_xml_base =         [HostLanguage.rdfa_core, HostLanguage.atom, HostLanguage.svg,  HostLanguage.xhtml5]
 77accept_xml_lang =         [HostLanguage.rdfa_core, HostLanguage.atom, HostLanguage.svg]
 78
 79accept_embedded_rdf_xml = [HostLanguage.svg, HostLanguage.rdfa_core]
 80accept_embedded_turtle =  [HostLanguage.svg, HostLanguage.html5, HostLanguage.xhtml5, HostLanguage.xhtml]
 81
 82# some languages, eg, SVG, require that embedded content should be combined with the default graph,
 83# ie, it cannot be turned down by an option
 84require_embedded_rdf =    [HostLanguage.svg]
 85
 86warn_xmlns_usage =        [HostLanguage.html5, HostLanguage.xhtml5, HostLanguage.xhtml]
 87
 88host_dom_transforms = {
 89    HostLanguage.atom:   [atom_add_entry_type],
 90    HostLanguage.html5:  [html5_extra_attributes, remove_rel],
 91    HostLanguage.xhtml5: [html5_extra_attributes, remove_rel]
 92}
 93
 94default_vocabulary = {
 95    HostLanguage.atom: "http://www.iana.org/assignments/relation/"
 96}
 97
 98predefined_1_0_rel = ['alternate', 'appendix', 'cite', 'bookmark', 'chapter', 'contents',
 99'copyright', 'glossary', 'help', 'icon', 'index', 'meta', 'next', 'p3pv1', 'prev', 'previous', 
100'role', 'section', 'subsection', 'start', 'license', 'up', 'last', 'stylesheet', 'first', 'top']
101
102# ----------------------------------------------------------------------------------------------------------
103
104class MediaTypes:
105    """An enumeration style class: some common media types (better have them at one place to avoid misstyping...)"""
106    rdfxml = 'application/rdf+xml'
107    turtle = 'text/turtle'
108    html =   'text/html'
109    xhtml =  'application/xhtml+xml'
110    svg =    'application/svg+xml'
111    svgi =   'image/svg+xml'
112    smil =   'application/smil+xml'
113    atom =   'application/atom+xml'
114    xml =    'application/xml'
115    xmlt =   'text/xml'
116    nt =     'text/plain'
117
118# mapping from (some) content types to RDFa host languages. This may control the exact processing or at least the initial context (see below)...
119content_to_host_language = {
120    MediaTypes.html:  HostLanguage.html5,
121    MediaTypes.xhtml: HostLanguage.xhtml,
122    MediaTypes.xml:   HostLanguage.rdfa_core,
123    MediaTypes.xmlt:  HostLanguage.rdfa_core,
124    MediaTypes.smil:  HostLanguage.rdfa_core,
125    MediaTypes.svg:   HostLanguage.svg,
126    MediaTypes.svgi:  HostLanguage.svg,
127    MediaTypes.atom:  HostLanguage.atom
128}
129
130# mapping preferred suffixes to media types...
131preferred_suffixes = {
132    ".rdf":   MediaTypes.rdfxml,
133    ".ttl":   MediaTypes.turtle,
134    ".n3":    MediaTypes.turtle,
135    ".owl":   MediaTypes.rdfxml,
136    ".html":  MediaTypes.html,
137    ".shtml": MediaTypes.html,
138    ".xhtml": MediaTypes.xhtml,
139    ".svg":   MediaTypes.svg,
140    ".smil":  MediaTypes.smil,
141    ".xml":   MediaTypes.xml,
142    ".nt":    MediaTypes.nt,
143    ".atom":  MediaTypes.atom
144}
145
146# DTD combinations that may determine the host language and the rdfa version
147_XHTML_1_0 = [
148    ("-//W3C//DTD XHTML+RDFa 1.0//EN", "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd")
149]
150
151_XHTML_1_1 = [
152    ("-//W3C//DTD XHTML+RDFa 1.1//EN", "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-2.dtd"),
153    ("-//W3C//DTD HTML 4.01+RDFa 1.1//EN", "http://www.w3.org/MarkUp/DTD/html401-rdfa11-1.dtd")
154]
155
156_XHTML = [
157    ("-//W3C//DTD XHTML 1.0 Strict//EN",       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"),
158    ("-//W3C//DTD XHTML 1.0 Transitional//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"),
159    ("-//W3C//DTD XHTML 1.1//EN",              "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd")
160]
161
162def adjust_html_version(stream, rdfa_version):
163    """
164    Adjust the rdfa_version based on the (possible) DTD
165    @param stream: the data stream that has to be parsed by an xml parser
166    @param rdfa_version: the current rdfa_version; will be returned if nothing else is found
167    @return: the rdfa_version, either "1.0" or "1.1, if the DTD says so, otherwise the input rdfa_version value
168    """
169    import xml.dom.minidom
170    parse = xml.dom.minidom.parse
171    dom = parse(stream)
172
173    _hl, version = adjust_xhtml_and_version(dom, HostLanguage.xhtml, rdfa_version)
174    return version
175
176def adjust_xhtml_and_version(dom, incoming_language, rdfa_version):
177    """
178    Check if the xhtml+RDFa is really XHTML 0 or 1 or whether it should be considered as XHTML5. This is done
179    by looking at the DTD. Furthermore, checks whether whether the system id signals an rdfa 1.0, in which case the
180    version is also set.
181
182    @param dom: top level DOM node
183    @param incoming_language: host language to be checked; the whole check is relevant for xhtml only.
184    @param rdfa_version: rdfa_version as known by the caller
185    @return: a tuple of the possibly modified host language (ie, set to XHTML5) and the possibly modified rdfa version (ie, set to "1.0", "1.1", or the incoming rdfa_version if nothing is found)
186    """
187    if incoming_language == HostLanguage.xhtml:
188        try:
189            # There may not be any doctype set in the first place...
190            publicId = dom.doctype.publicId
191            systemId = dom.doctype.systemId
192
193            if (publicId, systemId) in _XHTML_1_0:
194                return (HostLanguage.xhtml,"1.0")
195            elif (publicId, systemId) in _XHTML_1_1:
196                return (HostLanguage.xhtml,"1.1")
197            elif (publicId, systemId) in _XHTML:
198                return (HostLanguage.xhtml, rdfa_version)
199            else:
200                return (HostLanguage.xhtml5, rdfa_version)
201        except:
202            # If any of those are missing, forget it...
203            return (HostLanguage.xhtml5, rdfa_version)
204    else:
205        return (incoming_language, rdfa_version)
class HostLanguage:
41class HostLanguage:
42    """An enumeration style class: recognized host language types for this processor of RDFa. Some processing details may depend on these host languages. "rdfa_core" is the default Host Language is nothing else is defined."""
43    rdfa_core = "RDFa Core"
44    xhtml =     "XHTML+RDFa"
45    xhtml5 =    "XHTML5+RDFa"
46    html5 =     "HTML5+RDFa"
47    atom =      "Atom+RDFa"
48    svg =       "SVG+RDFa"

An enumeration style class: recognized host language types for this processor of RDFa. Some processing details may depend on these host languages. "rdfa_core" is the default Host Language is nothing else is defined.

rdfa_core = 'RDFa Core'
xhtml = 'XHTML+RDFa'
xhtml5 = 'XHTML5+RDFa'
html5 = 'HTML5+RDFa'
atom = 'Atom+RDFa'
svg = 'SVG+RDFa'
initial_contexts = {'XHTML+RDFa': ['http://www.w3.org/2011/rdfa-context/rdfa-1.1', 'http://www.w3.org/2011/rdfa-context/xhtml-rdfa-1.1'], 'XHTML5+RDFa': ['http://www.w3.org/2011/rdfa-context/rdfa-1.1'], 'HTML5+RDFa': ['http://www.w3.org/2011/rdfa-context/rdfa-1.1'], 'RDFa Core': ['http://www.w3.org/2011/rdfa-context/rdfa-1.1'], 'Atom+RDFa': ['http://www.w3.org/2011/rdfa-context/rdfa-1.1'], 'SVG+RDFa': ['http://www.w3.org/2011/rdfa-context/rdfa-1.1']}
beautifying_prefixes = {'XHTML+RDFa': {'xhv': 'http://www.w3.org/1999/xhtml/vocab#'}, 'Atom+RDFa': {'atomrel': 'http://www.iana.org/assignments/relation/'}}
accept_xml_base = ['RDFa Core', 'Atom+RDFa', 'SVG+RDFa', 'XHTML5+RDFa']
accept_xml_lang = ['RDFa Core', 'Atom+RDFa', 'SVG+RDFa']
accept_embedded_rdf_xml = ['SVG+RDFa', 'RDFa Core']
accept_embedded_turtle = ['SVG+RDFa', 'HTML5+RDFa', 'XHTML5+RDFa', 'XHTML+RDFa']
require_embedded_rdf = ['SVG+RDFa']
warn_xmlns_usage = ['HTML5+RDFa', 'XHTML5+RDFa', 'XHTML+RDFa']
host_dom_transforms = {'Atom+RDFa': [<function atom_add_entry_type>], 'HTML5+RDFa': [<function html5_extra_attributes>, <function remove_rel>], 'XHTML5+RDFa': [<function html5_extra_attributes>, <function remove_rel>]}
default_vocabulary = {'Atom+RDFa': 'http://www.iana.org/assignments/relation/'}
predefined_1_0_rel = ['alternate', 'appendix', 'cite', 'bookmark', 'chapter', 'contents', 'copyright', 'glossary', 'help', 'icon', 'index', 'meta', 'next', 'p3pv1', 'prev', 'previous', 'role', 'section', 'subsection', 'start', 'license', 'up', 'last', 'stylesheet', 'first', 'top']
class MediaTypes:
105class MediaTypes:
106    """An enumeration style class: some common media types (better have them at one place to avoid misstyping...)"""
107    rdfxml = 'application/rdf+xml'
108    turtle = 'text/turtle'
109    html =   'text/html'
110    xhtml =  'application/xhtml+xml'
111    svg =    'application/svg+xml'
112    svgi =   'image/svg+xml'
113    smil =   'application/smil+xml'
114    atom =   'application/atom+xml'
115    xml =    'application/xml'
116    xmlt =   'text/xml'
117    nt =     'text/plain'

An enumeration style class: some common media types (better have them at one place to avoid misstyping...)

rdfxml = 'application/rdf+xml'
turtle = 'text/turtle'
html = 'text/html'
xhtml = 'application/xhtml+xml'
svg = 'application/svg+xml'
svgi = 'image/svg+xml'
smil = 'application/smil+xml'
atom = 'application/atom+xml'
xml = 'application/xml'
xmlt = 'text/xml'
nt = 'text/plain'
content_to_host_language = {'text/html': 'HTML5+RDFa', 'application/xhtml+xml': 'XHTML+RDFa', 'application/xml': 'RDFa Core', 'text/xml': 'RDFa Core', 'application/smil+xml': 'RDFa Core', 'application/svg+xml': 'SVG+RDFa', 'image/svg+xml': 'SVG+RDFa', 'application/atom+xml': 'Atom+RDFa'}
preferred_suffixes = {'.rdf': 'application/rdf+xml', '.ttl': 'text/turtle', '.n3': 'text/turtle', '.owl': 'application/rdf+xml', '.html': 'text/html', '.shtml': 'text/html', '.xhtml': 'application/xhtml+xml', '.svg': 'application/svg+xml', '.smil': 'application/smil+xml', '.xml': 'application/xml', '.nt': 'text/plain', 'pyRdfa.host.atom': 'application/atom+xml'}
def adjust_html_version(stream, rdfa_version):
163def adjust_html_version(stream, rdfa_version):
164    """
165    Adjust the rdfa_version based on the (possible) DTD
166    @param stream: the data stream that has to be parsed by an xml parser
167    @param rdfa_version: the current rdfa_version; will be returned if nothing else is found
168    @return: the rdfa_version, either "1.0" or "1.1, if the DTD says so, otherwise the input rdfa_version value
169    """
170    import xml.dom.minidom
171    parse = xml.dom.minidom.parse
172    dom = parse(stream)
173
174    _hl, version = adjust_xhtml_and_version(dom, HostLanguage.xhtml, rdfa_version)
175    return version

Adjust the rdfa_version based on the (possible) DTD @param stream: the data stream that has to be parsed by an xml parser @param rdfa_version: the current rdfa_version; will be returned if nothing else is found @return: the rdfa_version, either "1.0" or "1.1, if the DTD says so, otherwise the input rdfa_version value

def adjust_xhtml_and_version(dom, incoming_language, rdfa_version):
177def adjust_xhtml_and_version(dom, incoming_language, rdfa_version):
178    """
179    Check if the xhtml+RDFa is really XHTML 0 or 1 or whether it should be considered as XHTML5. This is done
180    by looking at the DTD. Furthermore, checks whether whether the system id signals an rdfa 1.0, in which case the
181    version is also set.
182
183    @param dom: top level DOM node
184    @param incoming_language: host language to be checked; the whole check is relevant for xhtml only.
185    @param rdfa_version: rdfa_version as known by the caller
186    @return: a tuple of the possibly modified host language (ie, set to XHTML5) and the possibly modified rdfa version (ie, set to "1.0", "1.1", or the incoming rdfa_version if nothing is found)
187    """
188    if incoming_language == HostLanguage.xhtml:
189        try:
190            # There may not be any doctype set in the first place...
191            publicId = dom.doctype.publicId
192            systemId = dom.doctype.systemId
193
194            if (publicId, systemId) in _XHTML_1_0:
195                return (HostLanguage.xhtml,"1.0")
196            elif (publicId, systemId) in _XHTML_1_1:
197                return (HostLanguage.xhtml,"1.1")
198            elif (publicId, systemId) in _XHTML:
199                return (HostLanguage.xhtml, rdfa_version)
200            else:
201                return (HostLanguage.xhtml5, rdfa_version)
202        except:
203            # If any of those are missing, forget it...
204            return (HostLanguage.xhtml5, rdfa_version)
205    else:
206        return (incoming_language, rdfa_version)

Check if the xhtml+RDFa is really XHTML 0 or 1 or whether it should be considered as XHTML5. This is done by looking at the DTD. Furthermore, checks whether whether the system id signals an rdfa 1.0, in which case the version is also set.

@param dom: top level DOM node @param incoming_language: host language to be checked; the whole check is relevant for xhtml only. @param rdfa_version: rdfa_version as known by the caller @return: a tuple of the possibly modified host language (ie, set to XHTML5) and the possibly modified rdfa version (ie, set to "1.0", "1.1", or the incoming rdfa_version if nothing is found)