diff --git a/songbook_core/build.py b/songbook_core/build.py index 4101341b..496e7f9c 100755 --- a/songbook_core/build.py +++ b/songbook_core/build.py @@ -11,6 +11,7 @@ import re from subprocess import Popen, PIPE, call from songbook_core import __DATADIR__ +from songbook_core import content from songbook_core import errors from songbook_core.files import recursive_find from songbook_core.index import process_sxd @@ -66,6 +67,8 @@ class Songbook(object): Argument: - config : a dictionary containing the configuration + + TODO Move this function elsewhere """ Song.sort = config['sort'] if 'titleprefixwords' in config: @@ -94,34 +97,7 @@ class Songbook(object): self.config.update(raw_songbook) self._set_datadir() - # Compute song list - if self.config['content'] is None: - self.config['content'] = [( - "song", - os.path.relpath( - filename, - os.path.join(self.config['datadir'][0], 'songs'), - )) - for filename - in recursive_find( - os.path.join(self.config['datadir'][0], 'songs'), - '*.sg', - ) - ] - else: - content = self.config["content"] - self.config["content"] = [] - for elem in content: - if isinstance(elem, basestring): - self.config["content"].append(("song", elem)) - elif isinstance(elem, list): - self.config["content"].append((elem[0], elem[1])) - else: - raise errors.SBFileError( - "Syntax error: could not decode the content " - "of {0}".format(self.basename) - ) - + # TODO This should be moved elsewhere # Ensure self.config['authwords'] contains all entries for (key, value) in DEFAULT_AUTHWORDS.items(): if key not in self.config['authwords']: @@ -146,18 +122,15 @@ class Songbook(object): self.config['datadir'] = abs_datadir - def _parse_songs(self): - """Parse content included in songbook.""" - self.contentlist = SongbookContent(self.config['datadir']) - self.contentlist.append_list(self.config['content']) - def write_tex(self, output): """Build the '.tex' file corresponding to self. Arguments: - output: a file object, in which the file will be written. """ - self._parse_songs() + self.contentlist = content.process_content(self.config['content'], self.config) + #TODO self.contentlist = SongbookContent(self.config['datadir']) + #TODO self.contentlist.append_list(self.config['content']) renderer = TexRenderer( self.config['template'], self.config['datadir'], @@ -166,6 +139,7 @@ class Songbook(object): context = renderer.get_variables() context.update(self.config) + context['render_content'] = content.render_content context['titleprefixkeys'] = ["after", "sep", "ignore"] context['content'] = self.contentlist context['filename'] = output.name[:-4] diff --git a/songbook_core/content/__init__.py b/songbook_core/content/__init__.py index 68323ee8..a143be26 100644 --- a/songbook_core/content/__init__.py +++ b/songbook_core/content/__init__.py @@ -9,6 +9,7 @@ import os from songbook_core.errors import SongbookError LOGGER = logging.getLogger(__name__) +EOL = '\n' class Content: """Content item of type 'example'.""" @@ -77,3 +78,64 @@ def load_plugins(): continue plugins[key] = value return plugins + +def render_content(content): + rendered = "" + previous = None + last = None + for elem in content: + if not isinstance(elem, Content): + LOGGER.error("Ignoring bad content item '{}'.".format(elem)) + continue + + last = elem + if elem.begin_new_block(previous): + if previous: + rendered += previous.end_block() + EOL + rendered += elem.begin_block() + EOL + rendered += elem.render() + EOL + + if isinstance(last, Content): + rendered += last.end_block() + EOL + + return rendered + +def process_content(content, config = None): + contentlist = [] + plugins = load_plugins() + for elem in content: + if isinstance(elem, basestring): + TODO + if len(content) == 0: + TODO + if elem[0] not in plugins: + raise ContentError(elem[0], "Unknown content type.") + contentlist.extend(plugins[elem[0]](*elem)) + return contentlist + ## Compute song list + #if self.config['content'] is None: + # self.config['content'] = [( + # "song", + # os.path.relpath( + # filename, + # os.path.join(self.config['datadir'][0], 'songs'), + # )) + # for filename + # in recursive_find( + # os.path.join(self.config['datadir'][0], 'songs'), + # '*.sg', + # ) + # ] + #else: + # content = self.config["content"] + # self.config["content"] = [] + # for elem in content: + # if isinstance(elem, basestring): + # self.config["content"].append(("song", elem)) + # elif isinstance(elem, list): + # self.config["content"].append((elem[0], elem[1])) + # else: + # raise errors.SBFileError( + # "Syntax error: could not decode the content " + # "of {0}".format(self.basename) + # ) diff --git a/songbook_core/content/section.py b/songbook_core/content/section.py index 99f66ef7..7956c602 100644 --- a/songbook_core/content/section.py +++ b/songbook_core/content/section.py @@ -21,12 +21,12 @@ class Section(Content): self.short = short def render(self): - if (short is None): + if (self.short is None): return r'\{}{{{}}}'.format(self.keyword, self.name) else: return r'\{}[{}]{{{}}}'.format(self.keyword, self.short, self.name) -def parse(keyword, arguments): +def parse(keyword, *arguments): if (keyword not in KEYWORDS) and (len(arguments) != 1): raise ContentError(keyword, "Starred section names must have exactly one argument.") if (len(arguments) not in [1, 2]): diff --git a/songbook_core/content/songsection.py b/songbook_core/content/songsection.py index 0b246e65..7327696c 100644 --- a/songbook_core/content/songsection.py +++ b/songbook_core/content/songsection.py @@ -9,14 +9,14 @@ KEYWORDS = [ ] class SongSection(Content): - def __init__(self, keyword): + def __init__(self, keyword, name): self.keyword = keyword self.name = name def render(self): return r'\{}{{{}}}'.format(self.keyword, self.name) -def parse(keyword, arguments): +def parse(keyword, *arguments): if (keyword not in KEYWORDS) and (len(arguments) != 1): raise ContentError(keyword, "Starred section names must have exactly one argument.") return [SongSection(keyword, *arguments)] diff --git a/songbook_core/data/templates/songs.tex b/songbook_core/data/templates/songs.tex index 2b208f08..d3e6db17 100644 --- a/songbook_core/data/templates/songs.tex +++ b/songbook_core/data/templates/songs.tex @@ -70,9 +70,10 @@ (* block songbookpreambule *) (( super() )) - (* for lang in content.languages() *) - \PassOptionsToPackage{((lang))}{babel} - (* endfor *) + %!TODO + %!(* for lang in content.languages() *) + %!\PassOptionsToPackage{((lang))}{babel} + %!(* endfor *) \usepackage[((lang))]{babel} \lang{((lang))} @@ -93,15 +94,18 @@ \phantomsection \addcontentsline{toc}{section}{\songlistname} - \begin{songs}{((indexes|default('')))} - (* for type, elem in content.content *) - (* if type=="song" *) - \input{((elem.path))} - (* elif type=="section" *) - \end{songs} - \songsection{((elem))} - \begin{songs}{((indexes|default('')))} - (* endif *) - (* endfor *) - \end{songs} + %!TODO + %!\begin{songs}{((indexes|default('')))} + %! (* for type, elem in content.content *) + %! (* if type=="song" *) + %! \input{((elem.path))} + %! (* elif type=="section" *) + %! \end{songs} + %! \songsection{((elem))} + %! \begin{songs}{((indexes|default('')))} + %! (* endif *) + %! (* endfor *) + %!\end{songs} + (( render_content(content) )) + (* endblock *)