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.
 
 
 
 

81 lines
2.6 KiB

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import glob
import jinja2
import logging
import os
from songbook_core.content import Content, process_content, ContentError
from songbook_core.files import recursive_find
from songbook_core.songs import Song
LOGGER = logging.getLogger(__name__)
class SongRenderer(Content, Song):
def begin_new_block(self, previous, __context):
return not isinstance(previous, SongRenderer)
def begin_block(self, context):
indexes = context.resolve("indexes")
if isinstance(indexes, jinja2.runtime.Undefined):
indexes = ""
return r'\begin{songs}{%s}' % indexes
def end_block(self, __context):
return r'\end{songs}'
def render(self, context):
outdir = os.path.dirname(context['filename'])
if os.path.abspath(self.path).startswith(os.path.abspath(outdir)):
path = os.path.relpath(self.path, outdir)
else:
path = os.path.abspath(self.path)
return r'\input{{{}}}'.format(path)
def parse(keyword, argument, contentlist, config):
if 'languages' not in config:
config['languages'] = set()
songlist = []
for songdir in config['songdir']:
if contentlist:
break
contentlist = [
os.path.relpath(filename, songdir)
for filename
in recursive_find(songdir, "*.sg")
]
for elem in contentlist:
before = len(songlist)
for songdir in config['songdir']:
for filename in glob.iglob(os.path.join(songdir, elem)):
LOGGER.debug('Parsing file "{}"'.format(filename))
song = SongRenderer(filename, config)
songlist.append(song)
config["languages"].update(song.languages)
if len(songlist) > before:
break
if len(songlist) == before:
# No songs were added
LOGGER.warning(
"Expression '{}' did not match any file".format(elem)
)
return songlist
CONTENT_PLUGINS = {'song': parse}
class OnlySongsError(ContentError):
def __init__(self, not_songs):
self.not_songs = not_songs
def __str__(self):
return "Only songs are allowed, and the following items are not:" + str(not_songs)
def process_songs(content, config = None):
contentlist = process_content(content, config)
not_songs = [item for item in contentlist if not isinstance(item, SongRenderer)]
if not_songs:
raise OnlySongsError(not_songs)
return contentlist