@ -6,6 +6,7 @@ from jinja2 import Environment, FileSystemLoader, ChoiceLoader, PackageLoader, \
TemplateNotFound , nodes
TemplateNotFound , nodes
from jinja2 . ext import Extension
from jinja2 . ext import Extension
from jinja2 . meta import find_referenced_templates as find_templates
from jinja2 . meta import find_referenced_templates as find_templates
import codecs
import os
import os
import re
import re
import json
import json
@ -21,6 +22,25 @@ _LATEX_SUBS = (
( re . compile ( r ' \ . \ . \ .+ ' ) , r ' \\ ldots ' ) ,
( re . compile ( r ' \ . \ . \ .+ ' ) , r ' \\ ldots ' ) ,
)
)
VARIABLE_REGEXP = re . compile ( r """
\( \* \ * variables \ * \* \) # Match (* variables *)
( # Match and capture the following:
( ? : # Start of non-capturing group, used to match a single character
( ? ! # only if it's impossible to match the following:
\( \* \ * # - a literal (*
( ? : # Inner non-capturing group, used for the following alternation:
variables # - Either match the word variables
| # or
endvariables # - the word endvariables
) # End of inner non-capturing group
\ * \* \) # - a literal *)
) # End of negative lookahead assertion
. # Match any single character
) * # Repeat as often as possible
) # End of capturing group 1
\( \* \ * endvariables \ * \* \) # until (* endvariables *) is matched.""",
re . VERBOSE | re . DOTALL )
class VariablesExtension ( Extension ) :
class VariablesExtension ( Extension ) :
""" Extension to jinja2 to silently ignore variable block.
""" Extension to jinja2 to silently ignore variable block.
@ -96,7 +116,7 @@ class TexRenderer(object):
''' Get and return a dictionary with the default values
''' Get and return a dictionary with the default values
for all the variables
for all the variables
'''
'''
data = self . parse_templates ( )
data = self . get_template_variables ( self . template )
variables = dict ( )
variables = dict ( )
for name , param in data . items ( ) :
for name , param in data . items ( ) :
variables [ name ] = self . _get_default ( param )
variables [ name ] = self . _get_default ( param )
@ -124,39 +144,57 @@ class TexRenderer(object):
return variable
return variable
def parse_templates ( self ) :
def get_template_variables ( self , template , skip = None ) :
''' Recursively parse all the used templates to extract all the
""" Parse the template to extract the variables as a dictionary.
variables as a dictionary .
'''
If the template includes or extends other templates , load them as well .
templates = self . get_templates ( self . template )
templates | = set ( [ self . template . name ] )
Arguments :
- template : the name of the template , as a string .
- skip : a list of templates ( as strings ) to skip : if they are included
in ' template ' ( or one of its subtemplates ) , it is not parsed .
"""
if not skip :
skip = [ ]
variables = { }
variables = { }
regex = re . compile ( r ' \ ( \ * variables \ * \ ) \ n(?P<variables>.*) '
( current , templates ) = self . parse_template ( template )
' \ ( \ * endvariables \ * \ ) ' , re . DOTALL )
for subtemplate in templates :
for template_name in templates :
if subtemplate in skip :
filename = self . texenv . get_template ( template_name ) . filename
continue
with open ( filename , ' r ' ) as template_file :
variables . update (
content = template_file . read ( )
self . get_template_variables (
match = re . search ( regex , content )
subtemplate ,
if match :
skip + templates
content = match . group ( ' variables ' )
)
variables . update ( json . loads ( content ) )
)
variables . update ( current )
return variables
return variables
def get_templates ( self , template ) :
def parse_template ( self , template ) :
''' Recursively get a set of all the templates used
""" Return (variables, templates).
by a particular template .
'''
Argument :
with open ( template . filename , ' r ' ) as template_file :
- template : name of the template to parse .
content = template_file . readlines ( )
new_templates = list ( find_templates ( self . texenv . parse ( content ) ) )
Return values :
all_templates = set ( new_templates )
- variables : a dictionary of variables contained in ' template ' , NOT
if len ( new_templates ) > 0 :
recursively ( included templates are not parsed ) .
for new_template_name in new_templates :
- templates : list of included temlates , NOT recursively .
new_template = self . texenv . get_template ( new_template_name )
"""
# union of the sets
all_templates | = self . get_templates ( new_template )
subvariables = { }
return all_templates
with codecs . open (
self . texenv . get_template ( template ) . filename ,
' r ' ,
' utf-8 '
) as template_file :
content = template_file . read ( )
subtemplates = list ( find_templates ( self . texenv . parse ( content ) ) )
match = re . findall ( VARIABLE_REGEXP , content )
if match :
for var in match :
subvariables . update ( json . loads ( var ) )
return ( subvariables , subtemplates )
def render_tex ( self , output , context ) :
def render_tex ( self , output , context ) :
''' Render a template into a .tex file
''' Render a template into a .tex file