Hi, I needed to document which blocks are available in a jinja2 template that I am providing to my users, so I have created the attached script which takes a jinja template and outputs a SVG file which shows which blocks are inside which blocks. I am then converting the SVG file to PNG and PDF with Batik and include them in my Sphinx-documentation.
I thought this could maybe be interesting for some of you, so here is the script. Also attached is the output from running this on Sphinx' layout.html template from the basic theme. Martin -- You received this message because you are subscribed to the Google Groups "sphinx-dev" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/sphinx-dev?hl=en.
#!/usr/bin/env python-2.5.1
#from lxml import etree
import xml.etree.cElementTree as etree
import optparse
import re
import os.path
import sys
startblock_endblock_re=re.compile(r'\{%\-? (?P<tag>(block|endblock)) +(?P<name>\S*) *\-?%\}')
colors=range(10, 255, 32)
def color_of_level(level):
col=colors[level]
return 'rgb(%d,%d,%d)' % (col,col,col)
def main():
parser=optparse.OptionParser(add_help_option=False)
parser.add_option('--help', action='store_true', help='print help text', default=False)
parser.add_option('-t', '--template', action='store', help='jinja template to document')
parser.add_option('-o', '--output', action='store', help='SVG file to write')
parser.add_option('-w', '--min-width', action='store', help='Minimal width, default: %default', type='float', default=30)
parser.add_option('-h', '--min-height', action='store', help='Minimal height, default: %default', type='float', default=30)
parser.add_option('-x', '--x-padding', action='store', help='Horizontal padding between boxes, default: %default', type='float', default=20)
parser.add_option('-y', '--y-padding', action='store', help='Vertical padding between boxes, default: %default', type='float', default=10)
parser.add_option('-f', '--first-y-padding', action='store', help='Vertical padding between a box and its first child, default: %default', type='float', default=27)
parser.add_option('-l', '--label-y-offset', action='store', help='Vertical padding between a box and its label, default: %default', type='float', default=20)
parser.add_option('-c', '--char-width', action='store', help='Amount of space allocated for one char of text, default: %default', type='float', default=8.0)
opt,arg=parser.parse_args()
if opt.help:
parser.print_help()
return
if opt.template is None:
parser.error('No input template given')
JinjaBlock.opt=opt
file=JinjaBlock(os.path.basename(opt.template))
stack=[file]
for mo in startblock_endblock_re.finditer(open(opt.template).read()):
if mo.group('tag')=='block':
block=JinjaBlock(mo.group('name'))
stack[-1].add_child(block)
stack.append(block)
else:
stack.pop()
# construct the SVG document
root = etree.Element('svg', version="1.1", xmlns="http://www.w3.org/2000/svg")
width,height=file.draw(root, x=0, y=0)
root.attrib['width']=str(width+2)
root.attrib['height']=str(height+2)
# output the file
if opt.output is None:
outfile=sys.stdout
else:
outfile=open(opt.output, 'w')
#outfile.write(etree.tostring(root, pretty_print=True, xml_declaration=True, encoding="UTF-8"))
outfile.write(etree.tostring(root, encoding="UTF-8"))
class JinjaBlock(object):
opt=None
x_padding=20
y_padding=10
first_y_padding=30
def __init__(self, name):
self.name=name
self.children=[]
def add_child(self, child):
self.children.append(child)
def draw(self, canvas, x, y, depth=0):
width=self.opt.char_width*len(self.name) + 2.0*self.opt.x_padding
width=max(self.opt.min_width,width)
height=0
first=True
for child in self.children:
if first:
y_padding=self.opt.first_y_padding
first=False
else:
y_padding=self.opt.y_padding
height+=y_padding
child_width, child_height = child.draw(canvas, x=x+self.opt.x_padding, y=y+height, depth=depth+1)
width=max(width, child_width+2*self.opt.x_padding)
height+=child_height
height+=self.opt.y_padding
height=max(height, self.opt.min_height)
etree.SubElement(canvas, 'rect',
x=str(x), y=str(y),
rx="10", ry="10",
width=str(width), height=str(height),
style="fill:%s;stroke-width:1;stroke:rgb(154,33,235);fill-opacity:0.1" % color_of_level(depth))
text=etree.SubElement(canvas, 'text',
x=str(x+0.5*self.opt.x_padding),
y=str(y+self.opt.label_y_offset),
style="font-family:Verdana")
text.text=self.name
return width, height
if __name__=='__main__':
main()
<<attachment: layout.svg>>
layout.pdf
Description: Adobe PDF document
