Browse Source

Use yaml in tex templates

pull/184/head
Oliverpool 9 years ago
parent
commit
86dd4d014b
  1. 5
      patacrep/build.py
  2. 37
      patacrep/data/templates/default.tex
  3. 47
      patacrep/data/templates/songs.tex
  4. 58
      patacrep/templates.py
  5. 14
      patacrep/utils.py

5
patacrep/build.py

@ -81,9 +81,8 @@ class Songbook(object):
config['book']['lang'], config['book']['lang'],
config['book']['encoding'], config['book']['encoding'],
) )
# todo: better management of template variables
#config.update(renderer.get_variables()) self.config['template'] = renderer.get_all_variables(self.config.get('template', {}))
#config.update(self.config)
config['_compiled_authwords'] = authors.compile_authwords( config['_compiled_authwords'] = authors.compile_authwords(
copy.deepcopy(config['authors']) copy.deepcopy(config['authors'])

37
patacrep/data/templates/default.tex

@ -19,26 +19,23 @@
%!- https://github.com/patacrep/ %!- https://github.com/patacrep/
(* variables *) (* variables *)
{ schema:
"classoptions": {"description": {"en": "LaTeX class options", "fr": "Options de la classe LaTeX"}, type: //rec
"type": "flag", required:
"join": ",", title:
"mandatory": true, _description: _("Title")
"default": {"default":[]} type: //str
}, author:
"title": {"description": {"en": "Title", "fr": "Titre"}, _description: _("Author")
"default": {"en": "Guitar songbook", "fr": "Recueil de chansons pour guitare"}, type: //str
"mandatory":true optional:
}, classoptions:
"author": {"description": {"en": "Author", "fr": "Auteur"}, _description: _("LaTeX class options")
"default": {"en": "The Patacrep Team", "fr": "L'équipe Patacrep"}, type: //arr
"mandatory":true contents: //str
}, default:
"notenamesout": {"description": {"en": "Note names. Can be 'solfedge' (Do, Re, Mi...) or 'alphascale' (A, B, C...).", title: "Guitar songook"
"fr": "Nom des notes : 'solfedge' (Do, Ré, Mi...) ou 'alphascale' (A, B, C...)."}, author: "The Patacrep Team"
"default": {"default": "alphascale", "fr": "solfedge"}
}
}
(* endvariables -*) (* endvariables -*)
(*- extends "songs.tex" -*) (*- extends "songs.tex" -*)

47
patacrep/data/templates/songs.tex

@ -18,53 +18,6 @@
%!- The latest version of this program can be obtained from %!- The latest version of this program can be obtained from
%!- https://github.com/patacrep/ %!- https://github.com/patacrep/
(* variables *)
{
"instruments": {"description": {"en": "Instruments", "fr": "Instruments"},
"type": "flag",
"values": {"guitar": {"en": "Guitare", "fr": "Guitare"},
"ukulele": {"en": "Ukulele", "fr": "Ukulele"}
},
"join": ",",
"mandatory": true,
"default": {"default":["guitar"]}
},
"bookoptions": {"description": {"en": "Options", "fr": "Options"},
"type": "flag",
"values": {"diagram": {"en": "Chords diagrams", "fr": "Diagrammes d'accords"},
"importantdiagramonly": {"en": "Only importants diagrames", "fr": "Diagrammes importants uniquement"},
"lilypond": {"en": "Lilypond music sheets", "fr": "Partitions lilypond"},
"pictures": {"en": "Cover pictures", "fr": "Couvertures d'albums"},
"tabs": {"en": "Tablatures", "fr": "Tablatures"},
"repeatchords": {"en": "Repeat chords", "fr": "Répéter les accords"},
"onesongperpage": {"en": "One song per page", "fr": "Une chanson par page"}
},
"join": ",",
"mandatory": true,
"default": {"default":["diagram","pictures"]}
},
"booktype": {"description": {"en": "Type", "fr": "Type"},
"type": "enum",
"values": {"chorded": {"en": "With guitar chords", "fr": "Avec accords de guitare" },
"lyric": {"en": "Lyrics only", "fr": "Paroles uniquement"}
},
"default": {"default":"chorded"},
"mandatory": true
},
"lang": {"description": {"en": "Language", "fr": "Langue"},
"default": {"en": "en", "fr": "fr"}
},
"titleprefixwords": {"description": {"en": "Ignore some words in the beginning of song titles",
"fr": "Ignore des mots dans le classement des chansons"},
"default": {"default": []}
},
"authwords": {"description": {"en": "Set of options to process author string (LaTeX commands authsepword, authignoreword, authbyword)",
"fr": "Options pour traiter les noms d'auteurs (commandes LaTeX authsepword, authignoreword, authbyword)"},
"default": {"default": {}}
}
}
(* endvariables -*)
(*- extends "layout.tex" -*) (*- extends "layout.tex" -*)
(* block songbookpackages *) (* block songbookpackages *)

58
patacrep/templates.py

@ -1,14 +1,15 @@
"""Template for .tex generation settings and utilities""" """Template for .tex generation settings and utilities"""
import re import re
import json
import yaml
from jinja2 import Environment, FileSystemLoader, ChoiceLoader, \ from jinja2 import Environment, FileSystemLoader, ChoiceLoader, \
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
from patacrep import errors, files from patacrep import errors, files, utils, Rx
from patacrep.latex import lang2babel from patacrep.latex import lang2babel
import patacrep.encoding import patacrep.encoding
@ -131,37 +132,28 @@ class TexBookRenderer(Renderer):
), ),
) )
def get_variables(self): def get_all_variables(self, user_config):
'''Get and return a dictionary with the default values '''
for all the variables Validate template variables (and set defaults when needed)
''' '''
data = self.get_template_variables(self.template) 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) template_config = user_config.get(name, {})
variables[name] = self._get_variables(param, template_config)
return variables return variables
def _get_default(self, parameter): def _get_variables(self, parameter, user_config):
'''Get the default value for the parameter, according to the language. '''Get the default value for the parameter, according to the language.
''' '''
default = None schema = parameter.get('schema', {}).copy()
try: schema = utils.remove_keys(schema, ['_description'])
default = parameter['default']
except KeyError: data = utils.DictOfDict(parameter.get('default', {}))
return None data.update(user_config)
if self.lang in default:
variable = default[self.lang]
elif "default" in default:
variable = default["default"]
elif "en" in default:
variable = default["en"]
elif len(default):
variable = default.popitem()[1]
else:
variable = None
return variable utils.validate_yaml_schema(data, schema)
return data
def get_template_variables(self, template, skip=None): def get_template_variables(self, template, skip=None):
"""Parse the template to extract the variables as a dictionary. """Parse the template to extract the variables as a dictionary.
@ -177,16 +169,18 @@ class TexBookRenderer(Renderer):
skip = [] skip = []
variables = {} variables = {}
(current, templates) = self.parse_template(template) (current, templates) = self.parse_template(template)
if current:
variables[template.name] = current
for subtemplate in templates: for subtemplate in templates:
if subtemplate in skip: if subtemplate in skip:
continue continue
variables.update( subtemplate = self.jinjaenv.get_template(subtemplate)
self.get_template_variables( variables.update(self.get_template_variables(
subtemplate, subtemplate,
skip + templates skip + templates
) )
) )
variables.update(current)
return variables return variables
def parse_template(self, template): def parse_template(self, template):
@ -213,17 +207,17 @@ class TexBookRenderer(Renderer):
if match: if match:
for var in match: for var in match:
try: try:
subvariables.update(json.loads(var)) subvariables.update(yaml.load(var))
except ValueError as exception: except ValueError as exception:
raise errors.TemplateError( raise errors.TemplateError(
exception, exception,
( (
"Error while parsing json in file " "Error while parsing yaml in file "
"{filename}. The json string was:" "{filename}. The yaml string was:"
"\n'''\n{jsonstring}\n'''" "\n'''\n{yamlstring}\n'''"
).format( ).format(
filename=templatename, filename=templatename,
jsonstring=var, yamlstring=var,
) )
) )

14
patacrep/utils.py

@ -99,7 +99,6 @@ def remove_keys(data, keys=None, recursive=True):
def validate_config_schema(config): def validate_config_schema(config):
""" """
Check that the songbook config respects the excepted songbook schema Check that the songbook config respects the excepted songbook schema
""" """
data = config.copy() data = config.copy()
@ -108,11 +107,20 @@ def validate_config_schema(config):
with encoding.open_read(schema_path) as schema_file: with encoding.open_read(schema_path) as schema_file:
schema_struct = yaml.load(schema_file) schema_struct = yaml.load(schema_file)
schema_struct = remove_keys(schema_struct, ['_description']) schema_struct = remove_keys(schema_struct, ['_description'])
schema = rx_checker.make_schema(schema_struct) validate_yaml_schema(data, schema_struct)
def validate_yaml_schema(data, schema):
"""
Check that the data respects the schema
"""
rx_checker = Rx.Factory({"register_core_types": True})
schema = rx_checker.make_schema(schema)
if not isinstance(data, dict):
data = dict(data)
try: try:
schema.validate(data) schema.validate(data)
except Rx.SchemaMismatch as exception: except Rx.SchemaMismatch as exception:
msg = 'Could not parse songbook file:\n' + str(exception) msg = 'Could not parse songbook file:\n' + str(exception)
raise errors.SBFileError(msg) raise errors.SBFileError(msg)
return True

Loading…
Cancel
Save