mirror of
https://github.com/YunoHost-Apps/phpmyadmin_ynh.git
synced 2024-09-03 19:56:46 +02:00
190 lines
6.5 KiB
Python
190 lines
6.5 KiB
Python
|
from sphinx.locale import l_, _
|
||
|
from sphinx.domains import Domain, ObjType
|
||
|
from sphinx.roles import XRefRole
|
||
|
from sphinx.domains.std import GenericObject, StandardDomain
|
||
|
from sphinx.directives import ObjectDescription
|
||
|
from sphinx.util.nodes import clean_astext, make_refnode
|
||
|
from sphinx.util import ws_re
|
||
|
from sphinx import addnodes
|
||
|
from sphinx.util.docfields import Field
|
||
|
from docutils import nodes
|
||
|
|
||
|
def get_id_from_cfg(text):
|
||
|
'''
|
||
|
Formats anchor ID from config option.
|
||
|
'''
|
||
|
if text[:6] == '$cfg[\'':
|
||
|
text = text[6:]
|
||
|
if text[-2:] == '\']':
|
||
|
text = text[:-2]
|
||
|
text = text.replace('[$i]', '')
|
||
|
parts = text.split("']['")
|
||
|
return parts
|
||
|
|
||
|
|
||
|
class ConfigOption(ObjectDescription):
|
||
|
indextemplate = l_('configuration option; %s')
|
||
|
parse_node = None
|
||
|
|
||
|
has_arguments = True
|
||
|
|
||
|
doc_field_types = [
|
||
|
Field('default', label=l_('Default value'), has_arg=False,
|
||
|
names=('default', )),
|
||
|
Field('type', label=l_('Type'), has_arg=False,
|
||
|
names=('type',)),
|
||
|
]
|
||
|
|
||
|
|
||
|
def handle_signature(self, sig, signode):
|
||
|
signode.clear()
|
||
|
signode += addnodes.desc_name(sig, sig)
|
||
|
# normalize whitespace like XRefRole does
|
||
|
name = ws_re.sub('', sig)
|
||
|
return name
|
||
|
|
||
|
def add_target_and_index(self, name, sig, signode):
|
||
|
targetparts = get_id_from_cfg(name)
|
||
|
targetname = 'cfg_%s' % '_'.join(targetparts)
|
||
|
signode['ids'].append(targetname)
|
||
|
self.state.document.note_explicit_target(signode)
|
||
|
indextype = 'single'
|
||
|
|
||
|
# Generic index entries
|
||
|
indexentry = self.indextemplate % (name,)
|
||
|
self.indexnode['entries'].append((indextype, indexentry,
|
||
|
targetname, targetname))
|
||
|
self.indexnode['entries'].append((indextype, name,
|
||
|
targetname, targetname))
|
||
|
|
||
|
# Server section
|
||
|
if targetparts[0] == 'Servers' and len(targetparts) > 1:
|
||
|
indexname = ', '.join(targetparts[1:])
|
||
|
self.indexnode['entries'].append((indextype, l_('server configuration; %s') % indexname,
|
||
|
targetname, targetname))
|
||
|
self.indexnode['entries'].append((indextype, indexname,
|
||
|
targetname, targetname))
|
||
|
else:
|
||
|
indexname = ', '.join(targetparts)
|
||
|
self.indexnode['entries'].append((indextype, indexname,
|
||
|
targetname, targetname))
|
||
|
|
||
|
self.env.domaindata['config']['objects'][self.objtype, name] = \
|
||
|
self.env.docname, targetname
|
||
|
|
||
|
|
||
|
class ConfigSectionXRefRole(XRefRole):
|
||
|
"""
|
||
|
Cross-referencing role for configuration sections (adds an index entry).
|
||
|
"""
|
||
|
|
||
|
def result_nodes(self, document, env, node, is_ref):
|
||
|
if not is_ref:
|
||
|
return [node], []
|
||
|
varname = node['reftarget']
|
||
|
tgtid = 'index-%s' % env.new_serialno('index')
|
||
|
indexnode = addnodes.index()
|
||
|
indexnode['entries'] = [
|
||
|
('single', varname, tgtid, varname),
|
||
|
('single', _('configuration section; %s') % varname, tgtid, varname)
|
||
|
]
|
||
|
targetnode = nodes.target('', '', ids=[tgtid])
|
||
|
document.note_explicit_target(targetnode)
|
||
|
return [indexnode, targetnode, node], []
|
||
|
|
||
|
class ConfigSection(ObjectDescription):
|
||
|
indextemplate = l_('configuration section; %s')
|
||
|
parse_node = None
|
||
|
|
||
|
def handle_signature(self, sig, signode):
|
||
|
if self.parse_node:
|
||
|
name = self.parse_node(self.env, sig, signode)
|
||
|
else:
|
||
|
signode.clear()
|
||
|
signode += addnodes.desc_name(sig, sig)
|
||
|
# normalize whitespace like XRefRole does
|
||
|
name = ws_re.sub('', sig)
|
||
|
return name
|
||
|
|
||
|
def add_target_and_index(self, name, sig, signode):
|
||
|
targetname = '%s-%s' % (self.objtype, name)
|
||
|
signode['ids'].append(targetname)
|
||
|
self.state.document.note_explicit_target(signode)
|
||
|
if self.indextemplate:
|
||
|
colon = self.indextemplate.find(':')
|
||
|
if colon != -1:
|
||
|
indextype = self.indextemplate[:colon].strip()
|
||
|
indexentry = self.indextemplate[colon+1:].strip() % (name,)
|
||
|
else:
|
||
|
indextype = 'single'
|
||
|
indexentry = self.indextemplate % (name,)
|
||
|
self.indexnode['entries'].append((indextype, indexentry,
|
||
|
targetname, targetname))
|
||
|
self.env.domaindata['config']['objects'][self.objtype, name] = \
|
||
|
self.env.docname, targetname
|
||
|
|
||
|
|
||
|
class ConfigOptionXRefRole(XRefRole):
|
||
|
"""
|
||
|
Cross-referencing role for configuration options (adds an index entry).
|
||
|
"""
|
||
|
|
||
|
def result_nodes(self, document, env, node, is_ref):
|
||
|
if not is_ref:
|
||
|
return [node], []
|
||
|
varname = node['reftarget']
|
||
|
tgtid = 'index-%s' % env.new_serialno('index')
|
||
|
indexnode = addnodes.index()
|
||
|
indexnode['entries'] = [
|
||
|
('single', varname, tgtid, varname),
|
||
|
('single', _('configuration option; %s') % varname, tgtid, varname)
|
||
|
]
|
||
|
targetnode = nodes.target('', '', ids=[tgtid])
|
||
|
document.note_explicit_target(targetnode)
|
||
|
return [indexnode, targetnode, node], []
|
||
|
|
||
|
|
||
|
class ConfigFileDomain(Domain):
|
||
|
name = 'config'
|
||
|
label = 'Config'
|
||
|
|
||
|
object_types = {
|
||
|
'option': ObjType(l_('config option'), 'option'),
|
||
|
'section': ObjType(l_('config section'), 'section'),
|
||
|
}
|
||
|
directives = {
|
||
|
'option': ConfigOption,
|
||
|
'section': ConfigSection,
|
||
|
}
|
||
|
roles = {
|
||
|
'option': ConfigOptionXRefRole(),
|
||
|
'section': ConfigSectionXRefRole(),
|
||
|
}
|
||
|
|
||
|
initial_data = {
|
||
|
'objects': {}, # (type, name) -> docname, labelid
|
||
|
}
|
||
|
|
||
|
def clear_doc(self, docname):
|
||
|
for key, (fn, _) in self.data['objects'].items():
|
||
|
if fn == docname:
|
||
|
del self.data['objects'][key]
|
||
|
|
||
|
def resolve_xref(self, env, fromdocname, builder,
|
||
|
typ, target, node, contnode):
|
||
|
docname, labelid = self.data['objects'].get((typ, target), ('', ''))
|
||
|
if not docname:
|
||
|
return None
|
||
|
else:
|
||
|
return make_refnode(builder, fromdocname, docname,
|
||
|
labelid, contnode)
|
||
|
|
||
|
def get_objects(self):
|
||
|
for (type, name), info in self.data['objects'].iteritems():
|
||
|
yield (name, name, type, info[0], info[1],
|
||
|
self.object_types[type].attrs['searchprio'])
|
||
|
|
||
|
def setup(app):
|
||
|
app.add_domain(ConfigFileDomain)
|
||
|
|