Browse Source

[WIP] Basic version of song importation work (but I do not think it compiles)

pull/47/head
Louis 10 years ago
parent
commit
2fbff31ca9
  1. 3
      songbook_core/build.py
  2. 42
      songbook_core/content/__init__.py
  3. 2
      songbook_core/content/section.py
  4. 57
      songbook_core/content/song.py
  5. 2
      songbook_core/content/songsection.py
  6. 12
      songbook_core/data/templates/songs.tex
  7. 32
      songbook_core/songs.py

3
songbook_core/build.py

@ -13,7 +13,6 @@ from subprocess import Popen, PIPE, call
from songbook_core import __DATADIR__ from songbook_core import __DATADIR__
from songbook_core import content from songbook_core import content
from songbook_core import errors from songbook_core import errors
from songbook_core.files import recursive_find
from songbook_core.index import process_sxd from songbook_core.index import process_sxd
from songbook_core.songs import Song, SongbookContent from songbook_core.songs import Song, SongbookContent
from songbook_core.templates import TexRenderer from songbook_core.templates import TexRenderer
@ -129,8 +128,6 @@ class Songbook(object):
- output: a file object, in which the file will be written. - output: a file object, in which the file will be written.
""" """
self.contentlist = content.process_content(self.config['content'], self.config) 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( renderer = TexRenderer(
self.config['template'], self.config['template'],
self.config['datadir'], self.config['datadir'],

42
songbook_core/content/__init__.py

@ -34,14 +34,8 @@ class Content:
True if the renderer has to close previous block, and begin a new one, True if the renderer has to close previous block, and begin a new one,
False otherwise. False otherwise.
# Default
The default behavior of this method (if not defined in this child
class) is: begin a new block if the previous item is not an instance of
the same class.
""" """
return False return True
def begin_block(self): def begin_block(self):
"""Return the string to begin a block.""" """Return the string to begin a block."""
@ -94,6 +88,7 @@ def render_content(content):
rendered += previous.end_block() + EOL rendered += previous.end_block() + EOL
rendered += elem.begin_block() + EOL rendered += elem.begin_block() + EOL
rendered += elem.render() + EOL rendered += elem.render() + EOL
previous = elem
if isinstance(last, Content): if isinstance(last, Content):
rendered += last.end_block() + EOL rendered += last.end_block() + EOL
@ -105,37 +100,10 @@ def process_content(content, config = None):
plugins = load_plugins() plugins = load_plugins()
for elem in content: for elem in content:
if isinstance(elem, basestring): if isinstance(elem, basestring):
TODO elem = ["song", elem]
if len(content) == 0: if len(content) == 0:
TODO content = ["song"]
if elem[0] not in plugins: if elem[0] not in plugins:
raise ContentError(elem[0], "Unknown content type.") raise ContentError(elem[0], "Unknown content type.")
contentlist.extend(plugins[elem[0]](*elem)) contentlist.extend(plugins[elem[0]](elem[0], config, *elem[1:]))
return contentlist 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)
# )

2
songbook_core/content/section.py

@ -26,7 +26,7 @@ class Section(Content):
else: else:
return r'\{}[{}]{{{}}}'.format(self.keyword, self.short, self.name) return r'\{}[{}]{{{}}}'.format(self.keyword, self.short, self.name)
def parse(keyword, *arguments): def parse(keyword, config, *arguments):
if (keyword not in KEYWORDS) and (len(arguments) != 1): if (keyword not in KEYWORDS) and (len(arguments) != 1):
raise ContentError(keyword, "Starred section names must have exactly one argument.") raise ContentError(keyword, "Starred section names must have exactly one argument.")
if (len(arguments) not in [1, 2]): if (len(arguments) not in [1, 2]):

57
songbook_core/content/song.py

@ -0,0 +1,57 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import glob
import os
from songbook_core.content import Content
from songbook_core.files import recursive_find
class Song(Content):
def __init__(self, filename):
self.filename = filename
def begin_new_block(self, previous):
return not isinstance(previous, Song)
def begin_block(self):
#TODO index return r'\begin{songs}{((indexes|default("")))}'
return r'\begin{songs}{titleidx,authidx}'
def end_block(self):
return r'\end{songs}'
def render(self):
return r'\input{{{}}}'.format(self.filename)
def parse(keyword, config, *arguments):
songlist = []
if not arguments:
import ipdb; ipdb.set_trace()
arguments = [
os.path.relpath(
filename,
os.path.join(config['datadir'][0], 'songs'),
)
for filename
in recursive_find(
os.path.join(config['datadir'][0], 'songs'),
"*.sg"
)
]
for elem in arguments:
before = len(songlist)
for songdir in [os.path.join(d, 'songs') for d in config['datadir']]:
for filename in glob.iglob(os.path.join(songdir, elem)):
songlist.append(Song(filename))
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}

2
songbook_core/content/songsection.py

@ -16,7 +16,7 @@ class SongSection(Content):
def render(self): def render(self):
return r'\{}{{{}}}'.format(self.keyword, self.name) return r'\{}{{{}}}'.format(self.keyword, self.name)
def parse(keyword, *arguments): def parse(keyword, config, *arguments):
if (keyword not in KEYWORDS) and (len(arguments) != 1): if (keyword not in KEYWORDS) and (len(arguments) != 1):
raise ContentError(keyword, "Starred section names must have exactly one argument.") raise ContentError(keyword, "Starred section names must have exactly one argument.")
return [SongSection(keyword, *arguments)] return [SongSection(keyword, *arguments)]

12
songbook_core/data/templates/songs.tex

@ -94,18 +94,6 @@
\phantomsection \phantomsection
\addcontentsline{toc}{section}{\songlistname} \addcontentsline{toc}{section}{\songlistname}
%!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) )) ((render_content(content) ))
(* endblock *) (* endblock *)

32
songbook_core/songs.py

@ -107,35 +107,3 @@ class SongbookContent(object):
data = parsetex(filename) data = parsetex(filename)
song = Song(filename, data['languages'], data['titles'], data['args']) song = Song(filename, data['languages'], data['titles'], data['args'])
self.content.append(("song", song)) self.content.append(("song", song))
def append(self, type, value):
""" Append a generic element to the content list"""
self.content.append((type, value))
def append_list(self, contentlist):
"""Ajoute une liste de chansons à la liste
L'argument est une liste de chaînes, représentant des noms de fichiers
sous la forme d'expressions régulières destinées à être analysées avec
le module glob.
"""
for type, elem in contentlist:
if type == "song":
# Add all the songs matching the regex
before = len(self.content)
for songdir in self.songdirs:
for filename in glob.iglob(os.path.join(songdir, elem)):
self.append_song(filename)
if len(self.content) > before:
break
if len(self.content) == before:
# No songs were added
LOGGER.warning(
"Expression '{}' did not match any file".format(elem)
)
else:
self.append(type, elem)
def languages(self):
"""Renvoie la liste des langues utilisées par les chansons"""
return set().union(*[set(song.languages) for type, song in self.content if type=="song"])

Loading…
Cancel
Save