Skip to content

Commit

Permalink
Merge branch 'xslt-extended'
Browse files Browse the repository at this point in the history
  • Loading branch information
jcarrano committed Apr 2, 2019
2 parents 0e2d8b8 + 0d749e0 commit 579ff24
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 44 deletions.
3 changes: 2 additions & 1 deletion antidox/directives.py
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,8 @@ def __init__(self, env):
self.stylesheet_filename = env.app.config.antidox_xml_stylesheet

self.stylesheet = get_stylesheet(self.stylesheet_filename,
locale_fn=_locale)
locale_fn=_locale,
doxy_db=env.antidox_db)

def merge_domaindata(self, docnames, otherdata):
"""Nothing to do here."""
Expand Down
18 changes: 16 additions & 2 deletions antidox/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,19 @@ class Shell(cmd.Cmd):
"help", "sty")

def __init__(self, doxydb=None, **kwargs):
self._stylesheet_fn = None
self.db = doxydb

super().__init__(**kwargs)

self.do_sty("")
@property
def db(self):
return self._db

@db.setter
def db(self, value):
self._db = value
self._reload_sty()

def precmd(self, line):
if line and self.db is None and line.strip().split()[0] not in self.NOINIT_CMDS:
Expand Down Expand Up @@ -328,9 +336,15 @@ def do_sty(self, filename):
sty [template.xsl]
Load a XML template file. Call with no argument to restore the default.
The database will be reloaded each time the database is loaded.
"""

self.stylesheet = get_stylesheet(filename)
self.stylesheet = get_stylesheet(filename, doxy_db=self.db)
self._stylesheet_fn = filename

def _reload_sty(self):
"""Reload the stylesheet (after a database load)"""
self.do_sty(self._stylesheet_fn)

@_catch_doxy
@_any_to_refid
Expand Down
32 changes: 4 additions & 28 deletions antidox/templates/compound.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -11,39 +11,15 @@
<xsl:param name="hidedef" select="false()"/>
<xsl:param name="hidedoc" select="false()"/>

<xsl:template match="/memberdef[@kind='function']">
<xsl:call-template name="memberdef-internal">
<xsl:with-param name="role">function</xsl:with-param>
</xsl:call-template>
</xsl:template>

<xsl:template match="/memberdef[@kind='typedef']">
<xsl:call-template name="memberdef-internal">
<xsl:with-param name="role">type</xsl:with-param>
</xsl:call-template>
</xsl:template>

<xsl:template match="/memberdef[@kind='define']">
<xsl:call-template name="memberdef-internal">
<xsl:with-param name="role">macro</xsl:with-param>
</xsl:call-template>
</xsl:template>

<xsl:template match="/memberdef[@kind='variable']">
<xsl:call-template name="memberdef-internal">
<xsl:with-param name="role">var</xsl:with-param>
</xsl:call-template>
</xsl:template>

<xsl:template name="memberdef-internal">
<xsl:param name = "role" />
<xsl:template match="/memberdef">
<xsl:param name="role" select="antidox:guess_desctype(@id)"/>
<desc domain="c">
<xsl:attribute name="noindex"><xsl:value-of select="$noindex"/></xsl:attribute>
<xsl:attribute name="desctype"><xsl:value-of select="$role"/></xsl:attribute>
<xsl:attribute name="objtype"><xsl:value-of select="$role"/></xsl:attribute>
<desc_signature first="false">
<xsl:attribute name="ids">c.<xsl:value-of select="@id"/></xsl:attribute>
<xsl:attribute name="names"><xsl:value-of select="@id"/></xsl:attribute>
<xsl:attribute name="names"><xsl:value-of select="antidox:refid_to_target(@id)"/></xsl:attribute>
<xsl:apply-templates select="type|name"/>
<xsl:if test="argsstring/text()|param">
<desc_parameterlist>
Expand Down Expand Up @@ -73,7 +49,7 @@
<xsl:attribute name="objtype">type</xsl:attribute>
<desc_signature first="False">
<xsl:attribute name="ids">c.<xsl:value-of select="@id"/></xsl:attribute>
<xsl:attribute name="names"><xsl:value-of select="@id"/></xsl:attribute>
<xsl:attribute name="names"><xsl:value-of select="antidox:refid_to_target(@id)"/></xsl:attribute>
<desc_type><xsl:text>enum</xsl:text></desc_type>
<xsl:apply-templates select="name"/>
<xsl:if test="not($noindex)"><antidox:index/></xsl:if>
Expand Down
46 changes: 33 additions & 13 deletions antidox/xtransform.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import os
import collections
import re
import functools
from pkgutil import get_data

from lxml import etree as ET
Expand Down Expand Up @@ -46,29 +47,48 @@ def resolve(self, url, id, context):
_NORMALIZE_SPACE = re.compile(" +")


def _to_text(nodes_or_text):
nodes_or_text = nodes_or_text or ""
return (nodes_or_text if isinstance(nodes_or_text, str)
else (nodes_or_text[0].xpath("string(.)")))
def _to_text(f):
"""Decorator to convert the arguments of an XPath extension function to
string."""
@functools.wraps(f)
def _f(self, ctx, nodes_or_text):
nodes_or_text = nodes_or_text or ""
element0 = (nodes_or_text[0] if isinstance(nodes_or_text, list)
else nodes_or_text)
return f(self, ctx, element0 if isinstance(element0, str)
else element0.xpath("string(.)"))

return _f

class _StaticExtensions:
def __init__(self, locale_fn=None):

class _XPathExtensions:
def __init__(self, locale_fn=None, doxy_db=None):
self._locale_fn = locale_fn or (lambda x: x)
self._doxy_db = doxy_db

def l(self, _, nodes_or_text):
@_to_text
def l(self, _, text):
"""Stub locale function. This is here so we can run the XSL transform
without having to import sphinx."""
return self._locale_fn(_to_text(nodes_or_text))
return self._locale_fn(text)

def string_to_ids(self, _, nodes_or_text):
@_to_text
def string_to_ids(self, _, text):
"""Convert a string into something that is safe to use as a docutils ids
field."""
return _NORMALIZE_SPACE.sub(
"-", _to_text(nodes_or_text)).strip().translate(_XLATE_TABLE)
"-", text.strip()).translate(_XLATE_TABLE)

@_to_text
def guess_desctype(self, _, text):
return "" if not self._doxy_db else self._doxy_db.guess_desctype(text)

@_to_text
def refid_to_target(self, _, text):
return "" if not self._doxy_db else str(self._doxy_db.refid_to_target(text))


def get_stylesheet(stylesheet_filename=None, locale_fn=None):
def get_stylesheet(stylesheet_filename=None, locale_fn=None, doxy_db=None):
"""Get a XSLT stylesheet.
If stylesheet_filename is not specified, the default sheet will be returned.
Expand All @@ -84,9 +104,9 @@ def get_stylesheet(stylesheet_filename=None, locale_fn=None):
the identity function will be used.
"""

statics = _StaticExtensions(locale_fn)
custom_extension = _XPathExtensions(locale_fn, doxy_db)

ext = ET.Extension(statics, ns="antidox")
ext = ET.Extension(custom_extension, ns="antidox")

if stylesheet_filename:
parser = ET.XMLParser()
Expand Down
2 changes: 2 additions & 0 deletions doc/source/guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ Not all kinds are currently supported.

Some important doxygen constructs may be missing.

.. _entity_references:

References
~~~~~~~~~~

Expand Down
21 changes: 21 additions & 0 deletions doc/source/templating.rst
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,27 @@ XPath extension functions
field. If a node is given, it is run through ``string(.)``. This is useful
for automatically generating anchors from section titles.


.. xpath-func:: antidox:guess_desctype(refid)

Try to guess the C domain role for the given refid (usually the given as
the "id" attribute of a node.) This is usually needed to set the ``desctype``
and ``objtype`` in ``desc`` nodes.

This function maps to :py:meth:`antidox.doxy.DoxyDB.guess_desctype`.


.. xpath-func:: antidox:refid_to_target(refid)

Generate a :ref:`target string <entity_references>` from a refid. This
function maps to :py:meth:`antidox.doxy.DoxyDB.refid_to_target`.

.. todo::

antidox-indexnode_ should recognize targets in "name" attributes and set
the "initial" letter correctly for the index.


antidox-specific (pseudo)elements
---------------------------------

Expand Down

0 comments on commit 579ff24

Please sign in to comment.