dn2osdbk: handle internal references

The internal references were not properly created. This patches make the
:ref: inline markup create a <xref> tag when the reference is internal.

This patch also reworks the sphinx extension to handle the URLs that
will be generated in the hot-reference with the new :ref: behavior.

Closes-Bug: #1378073
Change-Id: I84bf268dc1055dc6b39f23c4415734184ec57eec
This commit is contained in:
Gauvain Pocentek 2014-10-11 07:29:11 +02:00
parent 9e0b746c76
commit f24863cf4d
4 changed files with 42 additions and 45 deletions

View File

@ -5,6 +5,7 @@ Release notes
---- ----
* ``openstack-doc-test``: Check for a ``\n`` in the last line of a file. * ``openstack-doc-test``: Check for a ``\n`` in the last line of a file.
* ``openstack-dn2osdbk``: Properly handle internal references.
0.19 0.19
---- ----

View File

@ -15,6 +15,7 @@
import argparse import argparse
import glob import glob
import os import os
import re
import sys import sys
from lxml import etree from lxml import etree
@ -63,20 +64,21 @@ class XMLFileTransformer(object):
root.insert(0, comment) root.insert(0, comment)
for item in tree.iter(): for item in tree.iter():
# Find tags with an 'id' attribute, and prefix its value with the # Find tags with an 'id' attribute. In case there are multiple
# basename of the file being processed. This avoids id conflicts # space-separated IDs, we have to make a choice.
# when working with multiple source files.
id_attrib = '%sid' % XML_NS id_attrib = '%sid' % XML_NS
id = item.get(id_attrib) xml_id = item.get(id_attrib)
if id is not None: if xml_id is not None:
id = id.split(' ')[-1] id_list = xml_id.split(' ')
id = "%s_%s" % (self.basename, id) # If the title and an associated reference target match, sphinx
item.attrib[id_attrib] = id # generates a second id like 'id[0-9]' which is hardly usable.
# So we take the first id in that case, otherwise the last.
if len(id_list) > 1 and re.match(r'id\d+', id_list[-1]):
xml_id = id_list[0]
else:
xml_id = id_list[-1]
# Same for the linkend attribute. item.attrib[id_attrib] = xml_id
linkend = item.get('linkend')
if linkend is not None:
item.attrib['linkend'] = "%s_%s" % (self.basename, linkend)
return tree return tree

View File

@ -545,12 +545,25 @@ HYPERLINK & FOOTNOTES
<xsl:template match="reference"> <xsl:template match="reference">
<xsl:choose> <xsl:choose>
<xsl:when test="@refuri"> <xsl:when test="@refuri">
<xsl:choose>
<xsl:when test="@internal='True'">
<xref>
<xsl:attribute name="linkend">
<xsl:value-of select="substring-after(@refuri, '#')"/>
</xsl:attribute>
<!-- Don't apply-templates here or invalid docbook will
be generated (<emphasis> in <xref>). -->
</xref>
</xsl:when>
<xsl:otherwise>
<link> <link>
<xsl:attribute name="xlink:href"> <xsl:attribute name="xlink:href">
<xsl:value-of select="@refuri"/> <xsl:value-of select="@refuri"/>
</xsl:attribute> </xsl:attribute>
<xsl:apply-templates/> <xsl:apply-templates/>
</link> </link>
</xsl:otherwise>
</xsl:choose>
</xsl:when> </xsl:when>
<xsl:when test="@refid"> <xsl:when test="@refid">
<link> <link>

View File

@ -18,9 +18,6 @@
Usage examples: Usage examples:
The :hotref:`OS::Nova::Server` resource creates a new instance. The :hotref:`OS::Nova::Server` resource creates a new instance.
The :hotref:os:`OS::Nova:Server` resource also.
The :hotref:cfn:`AWS::CloudFormation::WaitCondition` is an AWS
resource.
To use this extension, add 'os_doc_tools.sphinx.hotref' in the `extensions` To use this extension, add 'os_doc_tools.sphinx.hotref' in the `extensions`
list of your conf.py file.""" list of your conf.py file."""
@ -29,37 +26,21 @@ from docutils import nodes
from docutils import utils from docutils import utils
def build_ref_node(prefix, rawtext, app, resource, options):
link = resource.replace(':', '_')
base = app.config.hotref_base_url
ref = "%(base)s/%(prefix)s_%(name)s.html" % {'base': base,
'prefix': prefix,
'name': link}
literal = nodes.literal('')
ref_node = nodes.reference(rawtext, utils.unescape(resource),
refuri=ref, **options)
literal.append(ref_node)
return literal
def hotref_os_role(name, rawtext, text, lineno, inliner, options={}, def hotref_os_role(name, rawtext, text, lineno, inliner, options={},
content=[]): content=[]):
app = inliner.document.settings.env.app app = inliner.document.settings.env.app
node = build_ref_node('openstack', rawtext, app, text, options) link = text.replace(':', '_')
return [node], [] base = app.config.hotref_base_url
ref = "%(base)s/%(name)s.html" % {'base': base, 'name': link}
literal = nodes.literal('')
def hotref_cfn_role(name, rawtext, text, lineno, inliner, options={}, ref_node = nodes.reference(rawtext, utils.unescape(text),
content=[]): refuri=ref, **options)
app = inliner.document.settings.env.app literal.append(ref_node)
node = build_ref_node('cfn', rawtext, app, text, options) return [literal], []
return [node], []
def setup(app): def setup(app):
app.add_role('hotref', hotref_os_role) app.add_role('hotref', hotref_os_role)
app.add_role('hotref:os', hotref_os_role)
app.add_role('hotref:cfn', hotref_cfn_role)
app.add_config_value('hotref_base_url', app.add_config_value('hotref_base_url',
'http://docs.openstack.org/hot-reference/content', 'http://docs.openstack.org/hot-reference/content',
'env') 'env')