Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gestion de content par des plugins #47

Merged
merged 28 commits into from
Jun 17, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
bcac69b
WIP: Draft of content plugin management
May 24, 2014
a5fa34f
corrections
May 24, 2014
4adb5ed
Merge branch 'master' into contentPlugins
Jun 13, 2014
7c4ca25
[WIP] Draft of section and songsection plugins
Jun 13, 2014
3f9cdc6
[WIP] Plugins section and songsection work (no song yet)
Jun 13, 2014
2fbff31
[WIP] Basic version of song importation work (but I do not think it c…
Jun 14, 2014
2f3d57b
[WIP] indexes work again
Jun 14, 2014
29b5878
[WIP] Songs are now parsed using PlasTeX
Jun 14, 2014
e7519bc
[WIP] Song languages work
Jun 14, 2014
b7db9bc
[WIP] Managing titleprefixwords
Jun 14, 2014
9f33b31
Deleting useless stuff (and preparing 'sort' content plugin)
Jun 14, 2014
b695e30
[WIP] Managing authwords
Jun 14, 2014
7474516
comment
Jun 14, 2014
414716c
Sorted out configuration defaults (between hard-coded defaults, templ…
Jun 14, 2014
7b4a42e
Fix case where configuration file contain no content keyword at all
Jun 14, 2014
0a4d763
Added plugin 'sorted'
Jun 14, 2014
e87c6d4
Simplifying normalization of strings used to sort songs
Jun 14, 2014
fa8674d
Introduction d'un paramètre config['songdir'] ; Peuplement par défaut…
Jun 14, 2014
1e2dfc7
Implémentation du plugin cwd (#43)
Jun 14, 2014
1332263
Introduction de variables de configuration privées
Jun 14, 2014
d066386
The code is pylint compliant.
Jun 14, 2014
099f218
Correction de bug : rétablit le songdir original après traitement des…
Jun 15, 2014
e6afeb9
Nouveau plugin : inclusion de fichiers LaTeX
Jun 15, 2014
5dc1cf4
Solving error in management of default values of configuration
Jun 16, 2014
f727f13
Remplacement d'une erreur par un warning
Jun 16, 2014
93a421f
typo
Jun 17, 2014
2e12374
Ajout d'un message en cas de clef de tri incorrecte
Jun 17, 2014
710ffe5
Unification du traitement des chemins relatifs
Jun 17, 2014
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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