mirror of
https://github.com/wxWidgets/Phoenix.git
synced 2025-09-06 09:50:12 +02:00
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxPython/Phoenix/trunk@70205 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
199 lines
7.4 KiB
Python
199 lines
7.4 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
Allow "availability" admonitions to be inserted into your documentation.
|
|
Inclusion of availabilities can be switched of by a configuration variable.
|
|
The availabilitylist directive collects all availabilities of your project
|
|
and lists them along with a backlink to the original location.
|
|
"""
|
|
|
|
from docutils import nodes
|
|
|
|
from sphinx.locale import _
|
|
from sphinx.environment import NoUri
|
|
from sphinx.util.nodes import set_source_info
|
|
from sphinx.util.compat import Directive, make_admonition
|
|
|
|
# ----------------------------------------------------------------------- #
|
|
class availability_node(nodes.Admonition, nodes.Element): pass
|
|
|
|
# ----------------------------------------------------------------------- #
|
|
class availabilitylist(nodes.General, nodes.Element): pass
|
|
|
|
# ----------------------------------------------------------------------- #
|
|
|
|
|
|
class Availability(Directive):
|
|
"""
|
|
An "availability" entry, displayed (if configured) in the form of an admonition.
|
|
"""
|
|
|
|
has_content = True
|
|
required_arguments = 0
|
|
optional_arguments = 0
|
|
final_argument_whitespace = False
|
|
option_spec = {}
|
|
|
|
|
|
# ----------------------------------------------------------------------- #
|
|
|
|
def run(self):
|
|
env = self.state.document.settings.env
|
|
targetid = 'index-%s' % env.new_serialno('index')
|
|
targetnode = nodes.target('', '', ids=[targetid])
|
|
|
|
ad = make_admonition(availability_node, self.name, [_('Availability')], self.options,
|
|
self.content, self.lineno, self.content_offset,
|
|
self.block_text, self.state, self.state_machine)
|
|
set_source_info(self, ad[0])
|
|
return [targetnode] + ad
|
|
|
|
|
|
|
|
# ----------------------------------------------------------------------- #
|
|
|
|
def process_availabilities(app, doctree):
|
|
# collect all availabilities in the environment
|
|
# this is not done in the directive itself because it some transformations
|
|
# must have already been run, e.g. substitutions
|
|
env = app.builder.env
|
|
if not hasattr(env, 'availability_all_availabilities'):
|
|
env.availability_all_availabilities = []
|
|
for node in doctree.traverse(availability_node):
|
|
try:
|
|
targetnode = node.parent[node.parent.index(node) - 1]
|
|
if not isinstance(targetnode, nodes.target):
|
|
raise IndexError
|
|
except IndexError:
|
|
targetnode = None
|
|
env.availability_all_availabilities.append({
|
|
'docname': env.docname,
|
|
'source': node.source or env.doc2path(env.docname),
|
|
'lineno': node.line,
|
|
'availability': node.deepcopy(),
|
|
'target': targetnode,
|
|
})
|
|
|
|
|
|
# ----------------------------------------------------------------------- #
|
|
|
|
class AvailabilityList(Directive):
|
|
"""
|
|
A list of all availability entries.
|
|
"""
|
|
|
|
has_content = False
|
|
required_arguments = 0
|
|
optional_arguments = 0
|
|
final_argument_whitespace = False
|
|
option_spec = {}
|
|
|
|
|
|
# ----------------------------------------------------------------------- #
|
|
|
|
def run(self):
|
|
# Simply insert an empty availabilitylist node which will be replaced later
|
|
# when process_availability_nodes is called
|
|
return [availabilitylist('')]
|
|
|
|
|
|
# ----------------------------------------------------------------------- #
|
|
|
|
def process_availability_nodes(app, doctree, fromdocname):
|
|
if not app.config['availability_include_availabilities']:
|
|
for node in doctree.traverse(availability_node):
|
|
node.parent.remove(node)
|
|
|
|
# Replace all availabilitylist nodes with a list of the collected availabilities.
|
|
# Augment each availability with a backlink to the original location.
|
|
env = app.builder.env
|
|
|
|
if not hasattr(env, 'availability_all_availabilities'):
|
|
env.availability_all_availabilities = []
|
|
|
|
for node in doctree.traverse(availabilitylist):
|
|
if not app.config['availability_include_availabilities']:
|
|
node.replace_self([])
|
|
continue
|
|
|
|
content = []
|
|
|
|
for availability_info in env.availability_all_availabilities:
|
|
para = nodes.paragraph(classes=['availability-source'])
|
|
description = _('(The <<original entry>> is located in '
|
|
' %s, line %d.)') % \
|
|
(availability_info['source'], availability_info['lineno'])
|
|
desc1 = description[:description.find('<<')]
|
|
desc2 = description[description.find('>>')+2:]
|
|
para += nodes.Text(desc1, desc1)
|
|
|
|
# Create a reference
|
|
newnode = nodes.reference('', '', internal=True)
|
|
innernode = nodes.emphasis(_('original entry'), _('original entry'))
|
|
try:
|
|
newnode['refuri'] = app.builder.get_relative_uri(
|
|
fromdocname, availability_info['docname'])
|
|
newnode['refuri'] += '#' + availability_info['target']['refid']
|
|
except NoUri:
|
|
# ignore if no URI can be determined, e.g. for LaTeX output
|
|
pass
|
|
newnode.append(innernode)
|
|
para += newnode
|
|
para += nodes.Text(desc2, desc2)
|
|
|
|
# (Recursively) resolve references in the availability content
|
|
availability_entry = availability_info['availability']
|
|
env.resolve_references(availability_entry, availability_info['docname'],
|
|
app.builder)
|
|
|
|
# Insert into the availabilitylist
|
|
content.append(availability_entry)
|
|
content.append(para)
|
|
|
|
node.replace_self(content)
|
|
|
|
|
|
# ----------------------------------------------------------------------- #
|
|
|
|
def purge_availabilities(app, env, docname):
|
|
if not hasattr(env, 'availability_all_availabilities'):
|
|
return
|
|
env.availability_all_availabilities = [availability for availability in env.availability_all_availabilities
|
|
if availability['docname'] != docname]
|
|
|
|
|
|
# ----------------------------------------------------------------------- #
|
|
|
|
def visit_availability_node(self, node):
|
|
self.visit_admonition(node)
|
|
|
|
|
|
# ----------------------------------------------------------------------- #
|
|
|
|
def depart_availability_node(self, node):
|
|
self.depart_admonition(node)
|
|
|
|
|
|
# ----------------------------------------------------------------------- #
|
|
|
|
def setup(app):
|
|
app.add_javascript('javascript/header.js')
|
|
app.add_config_value('availability_include_availabilities', False, False)
|
|
|
|
app.add_node(availabilitylist)
|
|
app.add_node(availability_node,
|
|
html=(visit_availability_node, depart_availability_node),
|
|
latex=(visit_availability_node, depart_availability_node),
|
|
text=(visit_availability_node, depart_availability_node),
|
|
man=(visit_availability_node, depart_availability_node),
|
|
texinfo=(visit_availability_node, depart_availability_node))
|
|
|
|
app.add_directive('availability', Availability)
|
|
app.add_directive('availabilitylist', AvailabilityList)
|
|
app.connect('doctree-read', process_availabilities)
|
|
app.connect('doctree-resolved', process_availability_nodes)
|
|
app.connect('env-purge-doc', purge_availabilities)
|
|
|
|
|
|
# ----------------------------------------------------------------------- #
|