From 7721e400a7098162d7520bb821a6e9bb3e7f5405 Mon Sep 17 00:00:00 2001 From: Louis Date: Fri, 14 Feb 2014 23:35:37 +0100 Subject: [PATCH] =?UTF-8?q?Modification=20du=20moteur=20pour=20prendre=20e?= =?UTF-8?q?n=20compte=20la=20s=C3=A9paration=20du=20moteur=20et=20donn?= =?UTF-8?q?=C3=A9es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- readme.md | 10 +++----- songbook.py | 63 ++++++++++++++++++++++++----------------------- songbook/build.py | 46 ++++++++++++++++++++-------------- songbook/songs.py | 17 +++++++------ 4 files changed, 73 insertions(+), 63 deletions(-) diff --git a/readme.md b/readme.md index 92e8488d..a307fd33 100644 --- a/readme.md +++ b/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.py > -Look for existing songbook files in ./books. For example: +Look for existing songbook files in /books. For example: -> ./songbook.py -s ./books/songbook_en.sb -> evince songbook_en.pdf +> /songbook.py /books/songbook_en.sb +> songbook_en.pdf # Documentation diff --git a/songbook.py b/songbook.py index cc9ad315..5997b2e0 100755 --- a/songbook.py +++ b/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() diff --git a/songbook/build.py b/songbook/build.py index 5a7104b9..347d2835 100644 --- a/songbook/build.py +++ b/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) - - os.environ['TEXMFHOME'] = MOD_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') + # First pdflatex pass if call(["pdflatex", "--shell-escape", texFile]): sys.exit(1) diff --git a/songbook/songs.py b/songbook/songs.py index 1588981b..a0277582 100644 --- a/songbook/songs.py +++ b/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.