66 lines
1.9 KiB
Python
66 lines
1.9 KiB
Python
import os.path
|
|
|
|
from docutils import nodes
|
|
from docutils.parsers.rst import Directive
|
|
|
|
from pygments.lexers import get_lexer_by_name
|
|
|
|
|
|
def setup(app):
|
|
app.add_directive('switcher', SwitcherDirective)
|
|
app.add_directive('case', CaseDirective)
|
|
|
|
app.connect('env-updated', add_statics)
|
|
|
|
return {
|
|
'parallel_read_safe': False,
|
|
'parallel_write_safe': True
|
|
}
|
|
|
|
def add_statics(app, env):
|
|
app.add_js_file('js/switcher.js')
|
|
env.config.html_static_path.append(statics())
|
|
|
|
|
|
statics = lambda *p: os.path.join(
|
|
os.path.abspath(os.path.dirname(__file__)),
|
|
'static', *p)
|
|
|
|
|
|
class SwitcherDirective(Directive):
|
|
has_content = True
|
|
|
|
def run(self):
|
|
self.assert_has_content()
|
|
|
|
body = nodes.compound('\n'.join(self.content), classes=['tab-content'])
|
|
self.state.nested_parse(self.content, self.content_offset, body)
|
|
|
|
titles = []
|
|
for child in body.children:
|
|
if isinstance(child, nodes.literal_block):
|
|
titles.append(get_lexer_by_name(child['language']).name)
|
|
else:
|
|
assert child['names'], (
|
|
"A switcher case must be either a code block or a compound with a name"
|
|
)
|
|
titles.append(' '.join(child['names']))
|
|
tabs = nodes.bullet_list('', *[
|
|
nodes.list_item('', nodes.Text(title), classes=['nav-link'])
|
|
for title in titles
|
|
], classes=['nav nav-tabs'] )
|
|
node = nodes.compound('', tabs, body, classes=['content-switcher'])
|
|
return [node]
|
|
|
|
|
|
class CaseDirective(Directive):
|
|
required_arguments = 1
|
|
final_argument_whitespace = True
|
|
has_content = True
|
|
|
|
def run(self):
|
|
self.assert_has_content()
|
|
node = nodes.compound('\n'.join(self.content), names=[self.arguments[0]])
|
|
self.state.nested_parse(self.content, self.content_offset, node)
|
|
return [node]
|