Skip to content

Instantly share code, notes, and snippets.

@shuLhan
Created October 2, 2016 07:48
Show Gist options
  • Save shuLhan/e51024a01bc5a485dee4c81ad13b55c4 to your computer and use it in GitHub Desktop.
Save shuLhan/e51024a01bc5a485dee4c81ad13b55c4 to your computer and use it in GitHub Desktop.
Sphinx directive to parse and include Ansible playbook
##
## Directive for Ansible playbook.
##
## This directive will parse all the top comment on playbook and use it as
## content in documentation, and display the rest of it as a script.
##
## Installation,
## - copy the script to your sphinx `doc` directory
## - enable local extension in `conf.py`
##
## import os
## import sys
## sys.path.insert(0, os.path.abspath('.'))
##
## - change `playbook_path` in this script
## - add directive in your document, e.g,
##
## .. _playbook:: playbook_name.yml
##
from docutils import nodes
from docutils.statemachine import ViewList
from docutils.parsers.rst import Directive, directives, Parser
class playbook_node(nodes.Structural, nodes.Element):
pass
class Playbook(Directive):
playbook_path = "../"
has_content = False
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
add_index = True
option_spec = {}
"""
parse will parsing the playbook file and return comment at the top as
the content and the rest as code.
"""
def parse(self, src):
with open(src, "r") as ins:
content = []
code = []
for line in ins:
lstripped = line.lstrip()
if lstripped.startswith('##'):
v = lstripped.lstrip('#')
v = v.lstrip()
content.append(v)
else:
code.append(line)
content = ViewList(initlist=content)
code = ''.join(code)
return content, code
def run(self):
pb_name = self.arguments[0]
pb_id = nodes.make_id(pb_name)
section = nodes.section(ids=[pb_id])
title = nodes.title()
title += nodes.Text(pb_name)
section += title
content, code = self.parse("%s%s" % (self.playbook_path
, self.arguments[0]))
node_content = nodes.paragraph()
self.state.nested_parse(content, 0, node_content)
node_code = nodes.literal_block(code, code, language='yaml')
cheader_par = nodes.paragraph()
self.state.nested_parse(
ViewList(
initlist=[
'**Show/Hide Code**'
]
)
, 0
, cheader_par
)
cheader = nodes.container(classes=['header'])
cheader += cheader_par
ctoggle = nodes.container(classes=['toggle'])
ctoggle += cheader
ctoggle += node_code
node = playbook_node()
node += section
node += node_content
node += ctoggle
self.state.parent.children += node
return [ ]
def visit_playbook_node(self, node):
pass
def depart_playbook_node(self, node):
pass
def setup(app):
app.add_node(playbook_node
, html=(visit_playbook_node, depart_playbook_node)
)
app.add_directive('playbook', Playbook)
return {'version': '0.1'}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment