mirror of https://github.com/patacrep/patacrep.git
Engine for LaTeX songbooks
http://www.patacrep.com
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
94 lines
3.2 KiB
94 lines
3.2 KiB
"""Chordpro parser"""
|
|
|
|
from jinja2 import Environment, FileSystemLoader, contextfunction
|
|
import jinja2
|
|
import os
|
|
import pkg_resources
|
|
|
|
from patacrep import encoding, files
|
|
from patacrep.songs import Song
|
|
from patacrep.songs.chordpro.syntax import parse_song
|
|
from patacrep.templates import Renderer
|
|
|
|
class ChordproSong(Song):
|
|
"""Chordpros song parser."""
|
|
|
|
@staticmethod
|
|
def iter_template_paths(templatedirs, output_format):
|
|
"""Iterate over paths in which templates are to be searched.
|
|
|
|
:param iterator templatedirs: Iterators of additional directories (the
|
|
default hard-coded template directory is returned last).
|
|
:param str output_format: Song output format, which is appended to
|
|
each directory.
|
|
"""
|
|
for directory in templatedirs:
|
|
yield os.path.join(directory, output_format)
|
|
yield os.path.join(
|
|
os.path.abspath(pkg_resources.resource_filename(__name__, 'data')),
|
|
output_format,
|
|
)
|
|
|
|
def _parse(self, config):
|
|
"""Parse content, and return the dictionary of song data."""
|
|
with encoding.open_read(self.fullpath, encoding=self.encoding) as song:
|
|
song = parse_song(song.read(), self.fullpath)
|
|
self.authors = song.authors
|
|
self.titles = song.titles
|
|
|
|
# Lang inverted priority (last one is preferred):
|
|
# config['lang']
|
|
# song.language
|
|
# song.lang
|
|
self.lang = self.config['lang']
|
|
language = song.get_data_argument('language')
|
|
if language:
|
|
# self.lang is automatically updated
|
|
self.language = language
|
|
self.lang = song.get_data_argument('lang', self.lang)
|
|
|
|
self.data = song.meta
|
|
self.cached = {
|
|
'song': song,
|
|
}
|
|
|
|
def render(self, output_format, output=None, template="song", templatedirs=None): # pylint: disable=arguments-differ
|
|
if templatedirs is None:
|
|
templatedirs = []
|
|
|
|
context = {
|
|
'language': self.language,
|
|
'lang': self.lang,
|
|
"titles": self.titles,
|
|
"authors": self.authors,
|
|
"metadata": self.data,
|
|
"render": self._render_ast,
|
|
"config": self.config,
|
|
"content": self.cached['song'].content,
|
|
}
|
|
|
|
jinjaenv = Environment(loader=FileSystemLoader(
|
|
self.iter_template_paths(templatedirs, output_format)
|
|
))
|
|
jinjaenv.filters['search_image'] = self.search_image
|
|
jinjaenv.filters['search_partition'] = self.search_partition
|
|
|
|
try:
|
|
return Renderer(
|
|
template=template,
|
|
encoding='utf8',
|
|
jinjaenv=jinjaenv,
|
|
).template.render(context)
|
|
except jinja2.exceptions.TemplateNotFound:
|
|
raise NotImplementedError("Cannot convert to format '{}'.".format(output_format))
|
|
|
|
@staticmethod
|
|
@contextfunction
|
|
def _render_ast(context, content):
|
|
"""Render ``content``."""
|
|
context.vars['content'] = content
|
|
return context.environment.get_template(content.template()).render(context)
|
|
|
|
SONG_PARSERS = {
|
|
'sgc': ChordproSong,
|
|
}
|
|
|