| ## Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| ## use this file except in compliance with the License. You may obtain a copy of |
| ## the License at |
| ## |
| ## http://www.apache.org/licenses/LICENSE-2.0 |
| ## |
| ## Unless required by applicable law or agreed to in writing, software |
| ## distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| ## WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| ## License for the specific language governing permissions and limitations under |
| ## the License. |
| |
| from sphinx import addnodes |
| from sphinx.roles import XRefRole |
| from sphinx.domains import Domain, ObjType, Index |
| from sphinx.directives import ObjectDescription |
| from sphinx.util.nodes import make_refnode |
| import html |
| |
| |
| class ConfigObject(ObjectDescription): |
| def handle_signature(self, sig, signode): |
| if "::" in sig: |
| name, descr = map(lambda i: i.strip(), sig.split("::")) |
| else: |
| name, descr = sig.strip(), "" |
| |
| signode["name"] = name |
| signode["descr"] = descr |
| |
| domain, objtype = self.name.split(":") |
| if objtype == "section": |
| self.env.temp_data["section"] = signode["name"] |
| name = "[%s]" % signode["name"] |
| |
| signode += addnodes.desc_name(name, name) |
| |
| return signode["name"] |
| |
| def needs_arglist(self): |
| return False |
| |
| def add_target_and_index(self, name, sig, signode): |
| section = self.env.temp_data["section"] |
| domain, objtype = self.name.split(":") |
| data = self.env.domaindata[domain][objtype] |
| if objtype == "section": |
| data[name] = (self.env.docname, signode["descr"]) |
| signode["ids"].append(signode["name"]) |
| elif objtype == "option": |
| idx = "%s/%s" % (section, signode["name"]) |
| data[idx] = (self.env.docname, signode["descr"]) |
| signode["ids"].append(idx) |
| else: |
| assert "unknown object type %r" % objtype |
| |
| |
| class ConfigIndex(Index): |
| |
| name = "ref" |
| localname = "Configuration Quick Reference" |
| shortname = "Config Quick Reference" |
| |
| def generate(self, docnames=None): |
| content = dict( |
| (html.escape(name), [(name, 1, info[0], name, "", "", info[1])]) |
| for name, info in self.domain.data["section"].items() |
| ) |
| |
| options = self.domain.data["option"] |
| for idx, info in sorted(options.items()): |
| path, descr = info |
| section, name = idx.split("/", 1) |
| content[html.escape(section)].append( |
| (name, 2, path, "%s/%s" % (section, name), "", "", descr) |
| ) |
| |
| return (sorted(content.items()), False) |
| |
| |
| class ConfigDomain(Domain): |
| |
| name = "config" |
| label = "CONFIG" |
| |
| object_types = { |
| "section": ObjType("section", "section", "obj"), |
| "option": ObjType("option", "option", "obj"), |
| } |
| |
| directives = {"section": ConfigObject, "option": ConfigObject} |
| |
| roles = {"section": XRefRole(), "option": XRefRole()} |
| |
| initial_data = {"section": {}, "option": {}} |
| |
| indices = [ConfigIndex] |
| |
| def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode): |
| if typ == "section": |
| info = self.data[typ][target] |
| title = "[%s]" % target |
| elif typ == "option": |
| assert "/" in target, "option without section: %r" % target |
| section, option = target.split("/", 1) |
| info = self.data[typ][target] |
| title = option |
| else: |
| assert "unknown role %r for target %r" % (typ, target) |
| return make_refnode(builder, fromdocname, info[0], target, contnode, title) |
| |
| |
| def setup(app): |
| app.add_domain(ConfigDomain) |