Browse Source

Merge pull request #165 from patacrep/argument_simplification

Simplify some method arguments
pull/169/head
Louis 9 years ago
parent
commit
b18a202f0d
  1. 3
      patacrep/content/song.py
  2. 2
      patacrep/data/templates/layout.tex
  3. 8
      patacrep/data/templates/songs.tex
  4. 2
      patacrep/data/templates/songs/chordpro/latex/song
  5. 83
      patacrep/songs/__init__.py
  6. 7
      patacrep/songs/chordpro/__init__.py
  7. 14
      patacrep/songs/latex/__init__.py
  8. 4
      patacrep/templates.py
  9. 2
      test/test_chordpro/test_parser.py
  10. 8
      test/test_compilation/datadir.tex.control

3
patacrep/content/song.py

@ -33,6 +33,7 @@ class SongRenderer(Content):
"""Return the string to end a block."""
return r'\end{songs}'
#pylint: disable=unused-argument
def render(self, context):
"""Return the string that will render the song."""
return textwrap.dedent("""\
@ -43,7 +44,7 @@ class SongRenderer(Content):
""").format(
separator="%"*80,
path=files.path2posix(self.song.subpath),
song=self.song.render(output=context['filename']),
song=self.song.render(),
)
def __lt__(self, other):

2
patacrep/data/templates/layout.tex

@ -28,7 +28,7 @@
\makeatletter
\def\input@path{ %
(* for dir in datadir *)
{(( path2posix(dir) ))/latex/} %
{(( dir | path2posix ))/latex/} %
(* endfor *)
}
\makeatother

8
patacrep/data/templates/songs.tex

@ -81,15 +81,15 @@
(( super() ))
(* for lang in _langs|sort -*)
\PassOptionsToPackage{(( lang2babel(lang) ))}{babel}
\PassOptionsToPackage{(( lang | lang2babel ))}{babel}
(* endfor *)
\usepackage[(( lang2babel(lang) ))]{babel}
\lang{(( lang2babel(lang) ))}
\usepackage[(( lang | lang2babel ))]{babel}
\lang{(( lang | lang2babel ))}
\usepackage{graphicx}
\graphicspath{ %
(* for dir in datadir *)
{(( path2posix(dir) ))/} %
{(( dir | path2posix ))/} %
(* endfor *)
}

2
patacrep/data/templates/songs/chordpro/latex/song

@ -1,5 +1,5 @@
(* if lang is defined -*)
\selectlanguage{(( lang2babel(lang) ))}
\selectlanguage{(( lang | lang2babel ))}
(* endif *)
(*- if metadata.columns is defined *)

83
patacrep/songs/__init__.py

@ -80,7 +80,7 @@ class Song:
# Version format of cached song. Increment this number if we update
# information stored in cache.
CACHE_VERSION = 2
CACHE_VERSION = 3
# List of attributes to cache
cached_attributes = [
@ -88,7 +88,6 @@ class Song:
"unprefixed_titles",
"cached",
"data",
"subpath",
"lang",
"authors",
"_filehash",
@ -98,44 +97,30 @@ class Song:
def __init__(self, subpath, config, *, datadir=None):
if datadir is None:
self.datadir = ""
# Only songs in datadirs may be cached
self.use_cache = False
else:
self.datadir = datadir
self.use_cache = config.get('_cache', False)
self.fullpath = os.path.join(self.datadir, subpath)
self.subpath = subpath
self._filehash = None
self.encoding = config["encoding"]
self.default_lang = config["lang"]
self.config = config
if self.datadir and self.config['_cache']:
# Only songs in datadirs are cached
self._filehash = hashlib.md5(
open(self.fullpath, 'rb').read()
).hexdigest()
if os.path.exists(cached_name(datadir, subpath)):
try:
cached = pickle.load(open(
cached_name(datadir, subpath),
'rb',
))
if (
cached['_filehash'] == self._filehash
and cached['_version'] == self.CACHE_VERSION
):
for attribute in self.cached_attributes:
setattr(self, attribute, cached[attribute])
return
except: # pylint: disable=bare-except
LOGGER.warning("Could not use cached version of {}.".format(
self.fullpath
))
if self._cache_retrieved():
return
# Data extraction from the latex song
self.titles = []
self.data = {}
self.cached = None
self.lang = None
self._parse(config)
self._parse()
# Post processing of data
self.subpath = subpath
self.unprefixed_titles = [
unprefixed_title(
title,
@ -153,22 +138,52 @@ class Song:
self._version = self.CACHE_VERSION
self._write_cache()
@property
def cached_name(self):
"""Name of the file used for the cache"""
return cached_name(self.datadir, self.subpath)
@property
def filehash(self):
"""Compute (and cache) the md5 hash of the file"""
if self._filehash is None:
self._filehash = hashlib.md5(
open(self.fullpath, 'rb').read()
).hexdigest()
return self._filehash
def _cache_retrieved(self):
"""If relevant, retrieve self from the cache."""
if self.use_cache and os.path.exists(self.cached_name):
try:
cached = pickle.load(open(self.cached_name, 'rb',))
if (
cached['_filehash'] == self.filehash
and cached['_version'] == self.CACHE_VERSION
):
for attribute in self.cached_attributes:
setattr(self, attribute, cached[attribute])
return True
except: # pylint: disable=bare-except
LOGGER.warning("Could not use cached version of {}.".format(
self.fullpath
))
return False
def _write_cache(self):
"""If relevant, write a dumbed down version of self to the cache."""
if self.datadir and self.config['_cache']:
cached = {}
for attribute in self.cached_attributes:
cached[attribute] = getattr(self, attribute)
if self.use_cache:
cached = {attr: getattr(self, attr) for attr in self.cached_attributes}
pickle.dump(
cached,
open(cached_name(self.datadir, self.subpath), 'wb'),
open(self.cached_name, 'wb'),
protocol=-1
)
def __repr__(self):
return repr((self.titles, self.data, self.fullpath))
def render(self, output=None, *args, **kwargs):
def render(self, *args, **kwargs):
"""Return the code rendering this song.
Arguments:
@ -176,14 +191,14 @@ class Song:
"""
raise NotImplementedError()
def _parse(self, config): # pylint: disable=no-self-use
def _parse(self): # pylint: disable=no-self-use
"""Parse song.
It set the following attributes:
- titles: the list of (raw) titles. This list will be processed to
remove prefixes.
- lang: the main language of the song, as language code..
- lang: the main language of the song, as language code.
- authors: the list of (raw) authors. This list will be processed to
'clean' it (see function :func:`patacrep.authors.processauthors`).
- data: song metadata. Used (among others) to sort the songs.

7
patacrep/songs/chordpro/__init__.py

@ -25,26 +25,25 @@ class ChordproSong(Song):
output_language = None
def _parse(self, config):
def _parse(self):
"""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
self.lang = song.get_data_argument('language', self.config['lang'])
self.lang = song.get_data_argument('language', self.default_lang)
self.data = song.meta
self.cached = {
'song': song,
}
def render(self, output=None, template="song"): # pylint: disable=arguments-differ
def render(self, template="song"): # pylint: disable=arguments-differ
context = {
'lang': self.lang,
"titles": self.titles,
"authors": self.authors,
"metadata": self.data,
"render": self._render_ast,
"config": self.config,
"content": self.cached['song'].content,
}

14
patacrep/songs/latex/__init__.py

@ -15,7 +15,7 @@ class Latex2LatexSong(Song):
"""Song written in LaTeX, rendered in LaTeX"""
# pylint: disable=abstract-method
def _parse(self, __config):
def _parse(self):
"""Parse content, and return the dictionary of song data."""
with encoding.open_read(self.fullpath, encoding=self.encoding) as song:
self.data = parse_song(song.read(), self.fullpath)
@ -29,16 +29,12 @@ class Latex2LatexSong(Song):
else:
self.authors = []
def render(self, output):
def render(self):
"""Return the code rendering the song."""
# pylint: disable=signature-differs
if output is None:
raise ValueError(output)
path = files.path2posix(files.relpath(
self.fullpath,
os.path.dirname(output)
))
return r'\import{{{}/}}{{{}}}'.format(os.path.dirname(path), os.path.basename(path))
filename = os.path.basename(self.fullpath)
path = os.path.abspath(os.path.dirname(self.fullpath))
return r'\import{{{}/}}{{{}}}'.format(files.path2posix(path), filename)
def set_lang(self, language):
"""Set the language code"""

4
patacrep/templates.py

@ -84,8 +84,8 @@ class Renderer:
self.jinjaenv.filters['escape_tex'] = _escape_tex
self.jinjaenv.trim_blocks = True
self.jinjaenv.lstrip_blocks = True
self.jinjaenv.globals["path2posix"] = files.path2posix
self.jinjaenv.globals["lang2babel"] = lang2babel
self.jinjaenv.filters["path2posix"] = files.path2posix
self.jinjaenv.filters["lang2babel"] = lang2babel
self.template = self.jinjaenv.get_template(template)

2
test/test_chordpro/test_parser.py

@ -62,7 +62,7 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest):
with disable_logging():
song = self.song_plugins[LANGUAGES[destformat]]['sgc'](sourcename, self.config)
self.assertMultiLineEqual(
song.render(output=sourcename).strip(),
song.render().strip(),
expectfile.read().strip(),
)

8
test/test_compilation/datadir.tex.control

@ -92,7 +92,7 @@ guitar,
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% songs/./datadir.sg
\import{datadir_datadir/songs/}{datadir.sg}
\import{@TEST_FOLDER@/datadir_datadir/songs/}{datadir.sg}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% songs/./datadir.sgc
@ -119,7 +119,7 @@ Chordpro}[
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% songs/./datadir2.sg
\import{datadir_datadir/songs/}{datadir2.sg}
\import{@TEST_FOLDER@/datadir_datadir/songs/}{datadir2.sg}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% songs/./datadir2.sgc
@ -146,7 +146,7 @@ Chordpro}[
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% songs/./relative.sg
\import{datadir_datadir/songs/}{relative.sg}
\import{@TEST_FOLDER@/datadir_datadir/songs/}{relative.sg}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% songs/./relative.sgc
@ -173,7 +173,7 @@ Chordpro}[
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% songs/./subdir/subdir.sg
\import{datadir_datadir/songs/subdir/}{subdir.sg}
\import{@TEST_FOLDER@/datadir_datadir/songs/subdir/}{subdir.sg}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% songs/./subdir/subdir.sgc

Loading…
Cancel
Save