1 from sphinx
.locale
import l_
, _
2 from sphinx
.domains
import Domain
, ObjType
3 from sphinx
.roles
import XRefRole
4 from sphinx
.domains
.std
import GenericObject
, StandardDomain
5 from sphinx
.directives
import ObjectDescription
6 from sphinx
.util
.nodes
import clean_astext
, make_refnode
7 from sphinx
.util
import ws_re
8 from sphinx
import addnodes
9 from sphinx
.util
.docfields
import Field
10 from docutils
import nodes
12 def get_id_from_cfg(text
):
14 Formats anchor ID from config option.
16 if text
[:6] == '$cfg[\'':
18 if text
[-2:] == '\']':
20 text
= text
.replace('[$i]', '')
21 parts
= text
.split("']['")
25 class ConfigOption(ObjectDescription
):
26 indextemplate
= l_('configuration option; %s')
32 Field('default', label
=l_('Default value'), has_arg
=False,
34 Field('type', label
=l_('Type'), has_arg
=False,
39 def handle_signature(self
, sig
, signode
):
41 signode
+= addnodes
.desc_name(sig
, sig
)
42 # normalize whitespace like XRefRole does
43 name
= ws_re
.sub('', sig
)
46 def add_target_and_index(self
, name
, sig
, signode
):
47 targetparts
= get_id_from_cfg(name
)
48 targetname
= 'cfg_%s' % '_'.join(targetparts
)
49 signode
['ids'].append(targetname
)
50 self
.state
.document
.note_explicit_target(signode
)
53 # Generic index entries
54 indexentry
= self
.indextemplate
% (name
,)
55 self
.indexnode
['entries'].append((indextype
, indexentry
,
56 targetname
, targetname
))
57 self
.indexnode
['entries'].append((indextype
, name
,
58 targetname
, targetname
))
61 if targetparts
[0] == 'Servers' and len(targetparts
) > 1:
62 indexname
= ', '.join(targetparts
[1:])
63 self
.indexnode
['entries'].append((indextype
, l_('server configuration; %s') % indexname
,
64 targetname
, targetname
))
65 self
.indexnode
['entries'].append((indextype
, indexname
,
66 targetname
, targetname
))
68 indexname
= ', '.join(targetparts
)
69 self
.indexnode
['entries'].append((indextype
, indexname
,
70 targetname
, targetname
))
72 self
.env
.domaindata
['config']['objects'][self
.objtype
, name
] = \
73 self
.env
.docname
, targetname
76 class ConfigSectionXRefRole(XRefRole
):
78 Cross-referencing role for configuration sections (adds an index entry).
81 def result_nodes(self
, document
, env
, node
, is_ref
):
84 varname
= node
['reftarget']
85 tgtid
= 'index-%s' % env
.new_serialno('index')
86 indexnode
= addnodes
.index()
87 indexnode
['entries'] = [
88 ('single', varname
, tgtid
, varname
),
89 ('single', _('configuration section; %s') % varname
, tgtid
, varname
)
91 targetnode
= nodes
.target('', '', ids
=[tgtid
])
92 document
.note_explicit_target(targetnode
)
93 return [indexnode
, targetnode
, node
], []
95 class ConfigSection(ObjectDescription
):
96 indextemplate
= l_('configuration section; %s')
99 def handle_signature(self
, sig
, signode
):
101 name
= self
.parse_node(self
.env
, sig
, signode
)
104 signode
+= addnodes
.desc_name(sig
, sig
)
105 # normalize whitespace like XRefRole does
106 name
= ws_re
.sub('', sig
)
109 def add_target_and_index(self
, name
, sig
, signode
):
110 targetname
= '%s-%s' % (self
.objtype
, name
)
111 signode
['ids'].append(targetname
)
112 self
.state
.document
.note_explicit_target(signode
)
113 if self
.indextemplate
:
114 colon
= self
.indextemplate
.find(':')
116 indextype
= self
.indextemplate
[:colon
].strip()
117 indexentry
= self
.indextemplate
[colon
+1:].strip() % (name
,)
120 indexentry
= self
.indextemplate
% (name
,)
121 self
.indexnode
['entries'].append((indextype
, indexentry
,
122 targetname
, targetname
))
123 self
.env
.domaindata
['config']['objects'][self
.objtype
, name
] = \
124 self
.env
.docname
, targetname
127 class ConfigOptionXRefRole(XRefRole
):
129 Cross-referencing role for configuration options (adds an index entry).
132 def result_nodes(self
, document
, env
, node
, is_ref
):
135 varname
= node
['reftarget']
136 tgtid
= 'index-%s' % env
.new_serialno('index')
137 indexnode
= addnodes
.index()
138 indexnode
['entries'] = [
139 ('single', varname
, tgtid
, varname
),
140 ('single', _('configuration option; %s') % varname
, tgtid
, varname
)
142 targetnode
= nodes
.target('', '', ids
=[tgtid
])
143 document
.note_explicit_target(targetnode
)
144 return [indexnode
, targetnode
, node
], []
147 class ConfigFileDomain(Domain
):
152 'option': ObjType(l_('config option'), 'option'),
153 'section': ObjType(l_('config section'), 'section'),
156 'option': ConfigOption
,
157 'section': ConfigSection
,
160 'option': ConfigOptionXRefRole(),
161 'section': ConfigSectionXRefRole(),
165 'objects': {}, # (type, name) -> docname, labelid
168 def clear_doc(self
, docname
):
169 for key
, (fn
, _
) in self
.data
['objects'].items():
171 del self
.data
['objects'][key
]
173 def resolve_xref(self
, env
, fromdocname
, builder
,
174 typ
, target
, node
, contnode
):
175 docname
, labelid
= self
.data
['objects'].get((typ
, target
), ('', ''))
179 return make_refnode(builder
, fromdocname
, docname
,
182 def get_objects(self
):
183 for (type, name
), info
in self
.data
['objects'].iteritems():
184 yield (name
, name
, type, info
[0], info
[1],
185 self
.object_types
[type].attrs
['searchprio'])
188 app
.add_domain(ConfigFileDomain
)