Browse Source

Modification du moteur pour prendre en compte la séparation du moteur et données

- changement de la signature de songbook.py
- modification du module utilisé pour l'analyse de la ligne de commande
- utilisation des expressions régulières pour définir la liste de
  chansons
pull/3/head
Louis 11 years ago
parent
commit
7721e400a7
  1. 10
      readme.md
  2. 63
      songbook.py
  3. 44
      songbook/build.py
  4. 17
      songbook/songs.py

10
readme.md

@ -17,18 +17,16 @@ is precised in the header.
> git clone git://github.com/crep4ever/songbook-core.git
> git clone git://github.com/crep4ever/songbook-data.git
> mv songbook-data songbook-core/songs
# Run
> cd songbook-core
> ./songbook.py -s <songbook_file.sb>
> <songbook-core>/songbook.py <songbook_file.sb>
> <pdfreader> <songbook_file.pdf>
Look for existing songbook files in ./books. For example:
Look for existing songbook files in <songbook-data>/books. For example:
> ./songbook.py -s ./books/songbook_en.sb
> evince songbook_en.pdf
> <songbook-core>/songbook.py <songbook-data>/books/songbook_en.sb
> <pdfreader> songbook_en.pdf
# Documentation

63
songbook.py

@ -2,45 +2,41 @@
# -*- coding: utf-8 -*-
#
from songbook.build import buildsongbook
import getopt
import argparse
import json
import locale
import os.path
import textwrap
import sys
from songbook.build import buildsongbook
from songbook import __VERSION__
def argument_parser(args):
parser = argparse.ArgumentParser(description="A song book compiler")
parser.add_argument('--version', help='Show version', action='version',
version='%(prog)s ' + __VERSION__)
def usage():
print "No usage information yet."
parser.add_argument('book', nargs=1, help=textwrap.dedent("""\
Book to compile.
"""))
parser.add_argument('--datadir', '-d', nargs=1, type=str, action='store', default=".",
help=textwrap.dedent("""\
Data location. Expected (not necessarily required) subdirectories are 'songs', 'img', 'latex', 'templates'.
"""))
options = parser.parse_args(args)
return options
def main():
locale.setlocale(locale.LC_ALL, '') # set script locale to match user's
try:
opts, args = getopt.getopt(sys.argv[1:],
"hs:l:",
["help","songbook=","library="])
except getopt.GetoptError, err:
# print help and exit
print str(err)
usage()
sys.exit(2)
sbFile = None
library = './'
for o, a in opts:
if o in ("-h", "--help"):
usage()
sys.exit()
elif o in ("-s", "--songbook"):
sbFile = a
elif o in ("-l", "--library"):
if not a.endswith('/'):
a += '/'
library = a
else:
assert False, "unhandled option"
options = argument_parser(sys.argv[1:])
sbFile = options.book[0]
basename = os.path.basename(sbFile)[:-3]
@ -48,7 +44,12 @@ def main():
sb = json.load(f)
f.close()
buildsongbook(sb, basename, library)
if 'datadir' in sb.keys():
if not os.path.isabs(sb['datadir']):
sb['datadir'] = os.path.join(os.path.dirname(sbFile), sb['datadir'])
else:
sb['datadir'] = options.datadir
buildsongbook(sb, basename)
if __name__ == '__main__':
main()

44
songbook/build.py

@ -2,10 +2,12 @@
# -*- coding: utf-8 -*-
from subprocess import call
import codecs
import glob
import json
import os.path
import re
import sys
from songbook.files import recursiveFind
from songbook.index import processSXD
@ -55,9 +57,10 @@ def formatDeclaration(name, parameter):
def formatDefinition(name, value):
return '\\set@{name}{{{value}}}\n'.format(name=name, value=value)
def makeTexFile(sb, library, output, core_dir):
def makeTexFile(sb, output):
datadir = sb['datadir']
name = output[:-4]
template_dir = core_dir+'templates/'
template_dir = os.path.join(datadir, 'templates')
# default value
template = "patacrep.tmpl"
songs = []
@ -111,18 +114,22 @@ def makeTexFile(sb, library, output, core_dir):
Song.prefixes = prefixes
Song.authwords = authwords
parameters = parseTemplate(template_dir+template)
parameters = parseTemplate(os.path.join(template_dir, template))
# compute songslist
if songs == "all":
songs = map(lambda x: x[len(library) + 6:], recursiveFind(os.path.join(library, 'songs'), '*.sg'))
songslist = SongsList(library, sb["lang"])
songs = [
os.path.relpath(filename, os.path.join(datadir, 'songs'))
for filename
in recursiveFind(os.path.join(datadir, 'songs'), '*.sg')
]
songslist = SongsList(datadir, sb["lang"])
songslist.append_list(songs)
sb["languages"] = ",".join(songslist.languages())
# output relevant fields
out = open(output, 'w')
out = codecs.open(output, 'w', 'utf-8')
out.write('%% This file has been automatically generated, do not edit!\n')
out.write('\\makeatletter\n')
# output automatic parameters
@ -142,36 +149,37 @@ def makeTexFile(sb, library, output, core_dir):
# output template
commentPattern = re.compile(r"^\s*%")
with open(template_dir+template) as f:
with codecs.open(os.path.join(template_dir, template), 'r', 'utf-8') as f:
content = [ line for line in f if not commentPattern.match(line) ]
for index, line in enumerate(content):
if re.compile("getLibraryImgDirectory").search(line):
line = line.replace("\\getLibraryImgDirectory", core_dir + "img/")
if re.compile("getDataImgDirectory").search(line):
if os.path.abspath(os.path.join(datadir, "img")).startswith(os.path.abspath(os.path.dirname(output))):
imgdir = os.path.relpath(os.path.join(datadir, "img"), os.path.dirname(output))
else:
imgdir = os.path.abspath(os.path.join(datadir, "img"))
line = line.replace("\\getDataImgDirectory", ' {%s/} ' % imgdir)
content[index] = line
out.write(''.join(content))
out.write(u''.join(content))
out.close()
def buildsongbook(sb, basename, library):
def buildsongbook(sb, basename):
"""Build a songbook
Arguments:
- sb: Python representation of the .sb songbook configuration file.
- library: directory containing the "songs" directory, itself containing
songs.
- basename: basename of the songbook to be built.
"""
MOD_DIR = os.path.dirname(os.path.abspath(__file__))
CORE_DIR = MOD_DIR + '/../'
texFile = basename + ".tex"
# Make TeX file
makeTexFile(sb, library, texFile, CORE_DIR)
makeTexFile(sb, texFile)
os.environ['TEXINPUTS'] += os.pathsep + os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'latex')
os.environ['TEXINPUTS'] += os.pathsep + os.path.join(sb['datadir'], 'latex')
os.environ['TEXMFHOME'] = MOD_DIR + '/../'
# First pdflatex pass
if call(["pdflatex", "--shell-escape", texFile]):
sys.exit(1)

17
songbook/songs.py

@ -2,6 +2,7 @@
# -*- coding: utf-8 -*-
from unidecode import unidecode
import glob
import locale
import os.path
import re
@ -71,7 +72,7 @@ class SongsList:
"""Manipulation et traitement de liste de chansons"""
def __init__(self, library, language):
self._library = library
self._songdir = os.path.join(library, 'songs')
self._language = language
# Liste triée des chansons
@ -85,11 +86,10 @@ class SongsList:
pour en extraire et traiter certaines information (titre, langue,
album, etc.).
"""
path = os.path.join(self._library, 'songs', filename)
# Exécution de PlasTeX
data = parsetex(path)
data = parsetex(filename)
song = Song(path, data['languages'], data['titles'], data['args'])
song = Song(filename, data['languages'], data['titles'], data['args'])
low, high = 0, len(self.songs)
while low != high:
middle = (low + high) / 2
@ -102,10 +102,13 @@ class SongsList:
def append_list(self, filelist):
"""Ajoute une liste de chansons à la liste
L'argument est une liste de chaînes, représentant des noms de fichiers.
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 filename in filelist:
self.append(filename)
for regexp in filelist:
for filename in glob.iglob(os.path.join(self._songdir, regexp)):
self.append(filename)
def latex(self):
"""Renvoie le code LaTeX nécessaire pour intégrer la liste de chansons.

Loading…
Cancel
Save