mirror of https://github.com/scrapy/scrapy.git
149 lines
4.4 KiB
Python
149 lines
4.4 KiB
Python
from operator import itemgetter
|
|
|
|
from docutils import nodes
|
|
from docutils.parsers.rst import Directive
|
|
from docutils.parsers.rst.roles import set_classes
|
|
from sphinx.util.nodes import make_refnode
|
|
|
|
|
|
class settingslist_node(nodes.General, nodes.Element):
|
|
pass
|
|
|
|
|
|
class SettingsListDirective(Directive):
|
|
def run(self):
|
|
return [settingslist_node("")]
|
|
|
|
|
|
def is_setting_index(node):
|
|
if node.tagname == "index" and node["entries"]:
|
|
# index entries for setting directives look like:
|
|
# [('pair', 'SETTING_NAME; setting', 'std:setting-SETTING_NAME', '')]
|
|
entry_type, info, refid = node["entries"][0][:3]
|
|
return entry_type == "pair" and info.endswith("; setting")
|
|
return False
|
|
|
|
|
|
def get_setting_target(node):
|
|
# target nodes are placed next to the node in the doc tree
|
|
return node.parent[node.parent.index(node) + 1]
|
|
|
|
|
|
def get_setting_name_and_refid(node):
|
|
"""Extract setting name from directive index node"""
|
|
entry_type, info, refid = node["entries"][0][:3]
|
|
return info.replace("; setting", ""), refid
|
|
|
|
|
|
def collect_scrapy_settings_refs(app, doctree):
|
|
env = app.builder.env
|
|
|
|
if not hasattr(env, "scrapy_all_settings"):
|
|
env.scrapy_all_settings = []
|
|
|
|
for node in doctree.traverse(is_setting_index):
|
|
targetnode = get_setting_target(node)
|
|
assert isinstance(targetnode, nodes.target), "Next node is not a target"
|
|
|
|
setting_name, refid = get_setting_name_and_refid(node)
|
|
|
|
env.scrapy_all_settings.append(
|
|
{
|
|
"docname": env.docname,
|
|
"setting_name": setting_name,
|
|
"refid": refid,
|
|
}
|
|
)
|
|
|
|
|
|
def make_setting_element(setting_data, app, fromdocname):
|
|
refnode = make_refnode(
|
|
app.builder,
|
|
fromdocname,
|
|
todocname=setting_data["docname"],
|
|
targetid=setting_data["refid"],
|
|
child=nodes.Text(setting_data["setting_name"]),
|
|
)
|
|
p = nodes.paragraph()
|
|
p += refnode
|
|
|
|
item = nodes.list_item()
|
|
item += p
|
|
return item
|
|
|
|
|
|
def replace_settingslist_nodes(app, doctree, fromdocname):
|
|
env = app.builder.env
|
|
|
|
for node in doctree.traverse(settingslist_node):
|
|
settings_list = nodes.bullet_list()
|
|
settings_list.extend(
|
|
[
|
|
make_setting_element(d, app, fromdocname)
|
|
for d in sorted(env.scrapy_all_settings, key=itemgetter("setting_name"))
|
|
if fromdocname != d["docname"]
|
|
]
|
|
)
|
|
node.replace_self(settings_list)
|
|
|
|
|
|
def setup(app):
|
|
app.add_crossref_type(
|
|
directivename="setting",
|
|
rolename="setting",
|
|
indextemplate="pair: %s; setting",
|
|
)
|
|
app.add_crossref_type(
|
|
directivename="signal",
|
|
rolename="signal",
|
|
indextemplate="pair: %s; signal",
|
|
)
|
|
app.add_crossref_type(
|
|
directivename="command",
|
|
rolename="command",
|
|
indextemplate="pair: %s; command",
|
|
)
|
|
app.add_crossref_type(
|
|
directivename="reqmeta",
|
|
rolename="reqmeta",
|
|
indextemplate="pair: %s; reqmeta",
|
|
)
|
|
app.add_role("source", source_role)
|
|
app.add_role("commit", commit_role)
|
|
app.add_role("issue", issue_role)
|
|
app.add_role("rev", rev_role)
|
|
|
|
app.add_node(settingslist_node)
|
|
app.add_directive("settingslist", SettingsListDirective)
|
|
|
|
app.connect("doctree-read", collect_scrapy_settings_refs)
|
|
app.connect("doctree-resolved", replace_settingslist_nodes)
|
|
|
|
|
|
def source_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
|
|
ref = "https://github.com/scrapy/scrapy/blob/master/" + text
|
|
set_classes(options)
|
|
node = nodes.reference(rawtext, text, refuri=ref, **options)
|
|
return [node], []
|
|
|
|
|
|
def issue_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
|
|
ref = "https://github.com/scrapy/scrapy/issues/" + text
|
|
set_classes(options)
|
|
node = nodes.reference(rawtext, "issue " + text, refuri=ref, **options)
|
|
return [node], []
|
|
|
|
|
|
def commit_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
|
|
ref = "https://github.com/scrapy/scrapy/commit/" + text
|
|
set_classes(options)
|
|
node = nodes.reference(rawtext, "commit " + text, refuri=ref, **options)
|
|
return [node], []
|
|
|
|
|
|
def rev_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
|
|
ref = "http://hg.scrapy.org/scrapy/changeset/" + text
|
|
set_classes(options)
|
|
node = nodes.reference(rawtext, "r" + text, refuri=ref, **options)
|
|
return [node], []
|