Skip to content

Commit

Permalink
Merge pull request #47 from patacrep/contentPlugins
Browse files Browse the repository at this point in the history
Gestion de `content` par des plugins
  • Loading branch information
Luthaf committed Jun 17, 2014
2 parents 4244d9a + 710ffe5 commit 107d199
Show file tree
Hide file tree
Showing 17 changed files with 755 additions and 250 deletions.
2 changes: 1 addition & 1 deletion songbook
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class ParseStepsAction(argparse.Action):
(
getattr(namespace, self.dest)
+ [value.strip() for value in values[0].split(',')]
),
),
)

class VerboseAction(argparse.Action):
Expand Down
31 changes: 31 additions & 0 deletions songbook_core/authors.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,37 @@

"""Authors string management."""

import re

DEFAULT_AUTHWORDS = {
"after": ["by"],
"ignore": ["unknown"],
"sep": ["and"],
}

def compile_authwords(authwords):
"""Convert strings of authwords to compiled regular expressions.
This regexp will later be used to match these words in authors strings.
"""
# Fill missing values
for (key, value) in DEFAULT_AUTHWORDS.items():
if key not in authwords:
authwords[key] = value

# Compilation
authwords['after'] = [
re.compile(r"^.*%s\b(.*)" % word)
for word in authwords['after']
]
authwords['sep'] = [
re.compile(r"^(.*)%s (.*)$" % word)
for word in ([" %s" % word for word in authwords['sep']] + [','])
]

return authwords


def split_author_names(string):
r"""Split author between first and last name.
Expand Down
139 changes: 40 additions & 99 deletions songbook_core/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,17 @@
import glob
import logging
import os.path
import re
from subprocess import Popen, PIPE, call

from songbook_core import __DATADIR__
from songbook_core import authors
from songbook_core import content
from songbook_core import errors
from songbook_core.files import recursive_find
from songbook_core.index import process_sxd
from songbook_core.songs import Song, SongbookContent
from songbook_core.templates import TexRenderer

LOGGER = logging.getLogger(__name__)
EOL = "\n"
DEFAULT_AUTHWORDS = {
"after": ["by"],
"ignore": ["unknown"],
"sep": ["and"],
}
DEFAULT_STEPS = ['tex', 'pdf', 'sbx', 'pdf', 'clean']
GENERATED_EXTENSIONS = [
"_auth.sbx",
Expand All @@ -36,6 +30,12 @@
"_title.sbx",
"_title.sxd",
]
DEFAULT_CONFIG = {
'template': "default.tex",
'lang': 'english',
'content': [],
'titleprefixwords': [],
}



Expand All @@ -50,83 +50,12 @@ class Songbook(object):

def __init__(self, raw_songbook, basename):
super(Songbook, self).__init__()
self.config = raw_songbook
self.basename = basename
# Default values: will be updated while parsing raw_songbook
self.config = {
'template': "default.tex",
'lang': 'english',
'sort': [u"by", u"album", u"@title"],
'content': None,
}
self._parse_raw(raw_songbook)

@staticmethod
def _set_songs_default(config):
"""Set the default values for the Song() class.
Argument:
- config : a dictionary containing the configuration
"""
Song.sort = config['sort']
if 'titleprefixwords' in config:
Song.prefixes = config['titleprefixwords']
else:
Song.prefixes = []
Song.authwords['after'] = [
re.compile(r"^.*%s\b(.*)" % after)
for after
in config['authwords']["after"]
]
Song.authwords['ignore'] = config['authwords']['ignore']
Song.authwords['sep'] = [
re.compile(r"^(.*)%s (.*)$" % sep)
for sep in ([
" %s" % sep for sep in config['authwords']["sep"]
] + [','])
]

def _parse_raw(self, raw_songbook):
"""Parse raw_songbook.
The principle is: some special keys have their value processed; others
are stored verbatim in self.config.
"""
self.config.update(raw_songbook)
self.contentlist = []
# Some special keys have their value processed.
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)
)

# Ensure self.config['authwords'] contains all entries
for (key, value) in DEFAULT_AUTHWORDS.items():
if key not in self.config['authwords']:
self.config['authwords'][key] = value

def _set_datadir(self):
"""Set the default values for datadir"""
try:
Expand All @@ -140,38 +69,50 @@ def _set_datadir(self):
if os.path.exists(path) and os.path.isdir(path):
abs_datadir.append(os.path.abspath(path))
else:
LOGGER.warning("Ignoring non-existent datadir '{}'.".format(path))
LOGGER.warning(
"Ignoring non-existent datadir '{}'.".format(path)
)

abs_datadir.append(__DATADIR__)

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'])
self.config['_songdir'] = [
os.path.join(path, 'songs')
for path in self.config['datadir']
]

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()
# Updating configuration
config = DEFAULT_CONFIG
config.update(self.config)
renderer = TexRenderer(
self.config['template'],
self.config['datadir'],
self.config['lang'],
config['template'],
config['datadir'],
config['lang'],
)
config.update(self.config)
config.update(renderer.get_variables())

config['authwords'] = authors.compile_authwords(config['authwords'])

context = renderer.get_variables()
context.update(self.config)
context['titleprefixkeys'] = ["after", "sep", "ignore"]
context['content'] = self.contentlist
context['filename'] = output.name[:-4]
self.config = config
# Configuration set

self.contentlist = content.process_content(
self.config.get('content', []),
self.config,
)
self.config['render_content'] = content.render_content
self.config['titleprefixkeys'] = ["after", "sep", "ignore"]
self.config['content'] = self.contentlist
self.config['filename'] = output.name[:-4]

self._set_songs_default(context)
renderer.render_tex(output, context)
renderer.render_tex(output, self.config)


class SongbookBuilder(object):
Expand Down
Loading

0 comments on commit 107d199

Please sign in to comment.