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. 46
      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-core.git
> git clone git://github.com/crep4ever/songbook-data.git > git clone git://github.com/crep4ever/songbook-data.git
> mv songbook-data songbook-core/songs
# Run # Run
> cd songbook-core > <songbook-core>/songbook.py <songbook_file.sb>
> ./songbook.py -s <songbook_file.sb>
> <pdfreader> <songbook_file.pdf> > <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 > <songbook-core>/songbook.py <songbook-data>/books/songbook_en.sb
> evince songbook_en.pdf > <pdfreader> songbook_en.pdf
# Documentation # Documentation

63
songbook.py

@ -2,45 +2,41 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
from songbook.build import buildsongbook import argparse
import getopt
import json import json
import locale import locale
import os.path import os.path
import textwrap
import sys 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(): parser.add_argument('book', nargs=1, help=textwrap.dedent("""\
print "No usage information yet." 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(): def main():
locale.setlocale(locale.LC_ALL, '') # set script locale to match user's locale.setlocale(locale.LC_ALL, '') # set script locale to match user's
try:
opts, args = getopt.getopt(sys.argv[1:], options = argument_parser(sys.argv[1:])
"hs:l:",
["help","songbook=","library="]) sbFile = options.book[0]
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"
basename = os.path.basename(sbFile)[:-3] basename = os.path.basename(sbFile)[:-3]
@ -48,7 +44,12 @@ def main():
sb = json.load(f) sb = json.load(f)
f.close() 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__': if __name__ == '__main__':
main() main()

46
songbook/build.py

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

17
songbook/songs.py

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

Loading…
Cancel
Save