Browse Source

Début de la mise à niveau pep8 (#4)

pull/3/head
Luthaf 11 years ago
parent
commit
fa948b7186
  1. 31
      songbook.py
  2. 19
      songbook/authors.py
  3. 41
      songbook/build.py
  4. 2
      songbook/files.py
  5. 62
      songbook/index.py
  6. 2
      songbook/plastex-songs.py
  7. 12
      songbook/plastex.py
  8. 20
      songbook/songs.py

31
songbook.py

@ -12,6 +12,7 @@ import sys
from songbook.build import buildsongbook
from songbook import __VERSION__
def argument_parser(args):
parser = argparse.ArgumentParser(description="A song book compiler")
@ -24,34 +25,38 @@ def argument_parser(args):
parser.add_argument('--datadir', '-d', nargs=1, type=str, action='store',
help=textwrap.dedent("""\
Data location. Expected (not necessarily required) subdirectories are 'songs', 'img', 'latex', 'templates'.
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
# set script locale to match user's
locale.setlocale(locale.LC_ALL, '')
options = argument_parser(sys.argv[1:])
sbFile = options.book[0]
songbook_path = options.book[0]
basename = os.path.basename(sbFile)[:-3]
basename = os.path.basename(songbook_path)[:-3]
f = open(sbFile)
sb = json.load(f)
f.close()
with open(songbook_path) as songbook_file:
songbook = json.load(songbook_file)
if options.datadir is not None:
sb['datadir'] = options.datadir
elif 'datadir' in sb.keys():
if not os.path.isabs(sb['datadir']):
sb['datadir'] = os.path.join(os.path.dirname(sbFile), sb['datadir'])
songbook['datadir'] = options.datadir
elif 'datadir' in songbook.keys():
if not os.path.isabs(songbook['datadir']):
songbook['datadir'] = os.path.join(os.path.dirname(songbook_path),
songbook['datadir']
)
else:
sb['datadir'] = os.path.dirname(sbFile)
buildsongbook(sb, basename)
songbook['datadir'] = os.path.dirname(songbook_path)
buildsongbook(songbook, basename)
if __name__ == '__main__':
main()

19
songbook/authors.py

@ -1,6 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
def split_author_names(string):
"""Split author between first and last name.
@ -30,6 +31,7 @@ def split_author_names(string):
brace_count -= 1
return string[:last_space], string[last_space:]
def split_sep_author(string, sep):
authors = []
match = sep.match(string)
@ -40,12 +42,16 @@ def split_sep_author(string, sep):
authors.append(string)
return authors
def processauthors(authors_string, after = [], ignore = [], sep = []):
def processauthors(authors_string, after=[], ignore=[], sep=[]):
"""Return a list of authors
For example, we are processing:
# processauthors(
# "Lyrics by William Blake (from Milton, 1808), music by Hubert Parry (1916), and sung by The Royal\ Choir~of~Nowhere (just here to show you how processing is done)",
# "Lyrics by William Blake (from Milton, 1808),
music by Hubert Parry (1916),
and sung by The Royal\ Choir~of~Nowhere
(just here to show you how processing is done)",
# after = ["by"],
# ignore = ["anonymous"],
# sep = ["and"]
@ -54,10 +60,12 @@ def processauthors(authors_string, after = [], ignore = [], sep = []):
The "authors_string" string is processed as:
1) First, parenthesis (and its content) are removed.
# "Lyrics by William Blake, music by Hubert Parry, and sung by The Royal\ Choir~of~Nowhere"
# "Lyrics by William Blake, music by Hubert Parry,
and sung by The Royal\ Choir~of~Nowhere"
2) String is split, separators being comma and words from "sep".
# ["Lyrics by William Blake", "music by Hubert Parry", "sung by The Royal\ Choir~of~Nowhere"]
# ["Lyrics by William Blake", "music by Hubert Parry",
"sung by The Royal\ Choir~of~Nowhere"]
3) Everything before words in "after" is removed.
# ["William Blake", "Hubert Parry", "The Royal\ Choir~of~Nowhere"]
@ -113,7 +121,8 @@ def processauthors(authors_string, after = [], ignore = [], sep = []):
authors_list = dest
# Cleaning: removing empty authors and unnecessary spaces
authors_list = [author.lstrip() for author in authors_list if author.lstrip()]
authors_list = [author.lstrip()
for author in authors_list if author.lstrip()]
# Moving first names after last names
dest = []

41
songbook/build.py

@ -14,17 +14,19 @@ from songbook.index import processSXD
from songbook.songs import Song, SongsList
from songbook import __SHAREDIR__
def parseTemplate(template):
embeddedJsonPattern = re.compile(r"^%%:")
f = open(template)
code = [ line[3:-1] for line in f if embeddedJsonPattern.match(line) ]
f.close()
with open(template) as template_file:
code = [line[3:-1] for line in template_file if embeddedJsonPattern.match(line)]
data = json.loads(''.join(code))
parameters = dict()
for param in data:
parameters[param["name"]] = param
return parameters
def toValue(parameter, data):
if "type" not in parameter:
return data
@ -37,7 +39,7 @@ def toValue(parameter, data):
elif parameter["type"] == "color":
return data[1:]
elif parameter["type"] == "font":
return data+'pt'
return data + 'pt'
elif parameter["type"] == "enum":
return data
elif parameter["type"] == "file":
@ -49,15 +51,20 @@ def toValue(parameter, data):
joinText = ''
return joinText.join(data)
def formatDeclaration(name, parameter):
value = ""
if "default" in parameter:
value = parameter["default"]
return '\\def\\set@{name}#1{{\\def\\get{name}{{#1}}}}\n'.format(name=name) + formatDefinition(name, toValue(parameter, value))
return ('\\def\\set@{name}#1{{\\def\\get{name}{{#1}}}}\n'.format(name=name)
+ formatDefinition(name, toValue(parameter, value))
)
def formatDefinition(name, value):
return '\\set@{name}{{{value}}}\n'.format(name=name, value=value)
def clean(basename):
generated_extensions = [
"_auth.sbx",
@ -76,6 +83,7 @@ def clean(basename):
return True
def makeTexFile(sb, output):
datadir = sb['datadir']
name = output[:-4]
@ -87,7 +95,7 @@ def makeTexFile(sb, output):
authwords_tex = ""
authwords = {"after": ["by"], "ignore": ["unknown"], "sep": ["and"]}
# parse the songbook data
if "template" in sb:
template = sb["template"]
@ -117,10 +125,12 @@ def makeTexFile(sb, output):
authwords_tex += "\\auth%sword{%s}\n" % (key, word)
sb["authwords"] = authwords_tex
if "after" in authwords:
authwords["after"] = [re.compile(r"^.*%s\b(.*)" % after) for after in authwords["after"]]
authwords["after"] = [re.compile(r"^.*%s\b(.*)" % after)
for after in authwords["after"]]
if "sep" in authwords:
authwords["sep"] = [" %s" % sep for sep in authwords["sep"]] + [","]
authwords["sep"] = [re.compile(r"^(.*)%s (.*)$" % sep) for sep in authwords["sep"] ]
authwords["sep"] = [re.compile(r"^(.*)%s (.*)$" % sep)
for sep in authwords["sep"]]
if "lang" not in sb:
sb["lang"] = "french"
@ -152,15 +162,15 @@ def makeTexFile(sb, output):
out.write('%% This file has been automatically generated, do not edit!\n')
out.write('\\makeatletter\n')
# output automatic parameters
out.write(formatDeclaration("name", {"default":name}))
out.write(formatDeclaration("songslist", {"type":"stringlist"}))
out.write(formatDeclaration("name", {"default": name}))
out.write(formatDeclaration("songslist", {"type": "stringlist"}))
# output template parameter command
for name, parameter in parameters.iteritems():
out.write(formatDeclaration(name, parameter))
# output template parameter values
for name, value in sb.iteritems():
if name in parameters:
out.write(formatDefinition(name, toValue(parameters[name],value)))
out.write(formatDefinition(name, toValue(parameters[name], value)))
if len(songs) > 0:
out.write(formatDefinition('songslist', songslist.latex()))
@ -169,7 +179,7 @@ def makeTexFile(sb, output):
# output template
commentPattern = re.compile(r"^\s*%")
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):
if re.compile("getDataImgDirectory").search(line):
@ -183,6 +193,7 @@ def makeTexFile(sb, output):
out.write(u''.join(content))
out.close()
def buildsongbook(sb, basename):
"""Build a songbook
@ -191,12 +202,12 @@ def buildsongbook(sb, basename):
- basename: basename of the songbook to be built.
"""
texFile = basename + ".tex"
texFile = basename + ".tex"
# Make TeX file
makeTexFile(sb, texFile)
if not os.environ.has_key('TEXINPUTS'):
if not 'TEXINPUTS' in os.environ.keys():
os.environ['TEXINPUTS'] = ''
os.environ['TEXINPUTS'] += os.pathsep + os.path.join(__SHAREDIR__, 'latex')
os.environ['TEXINPUTS'] += os.pathsep + os.path.join(sb['datadir'], 'latex')
@ -210,7 +221,7 @@ def buildsongbook(sb, basename):
for sxdFile in sxdFiles:
print "processing " + sxdFile
idx = processSXD(sxdFile)
indexFile = open(sxdFile[:-3]+"sbx", "w")
indexFile = open(sxdFile[:-3] + "sbx", "w")
indexFile.write(idx.entriesToStr().encode('utf8'))
indexFile.close()

2
songbook/files.py

@ -5,10 +5,10 @@
import fnmatch
import os
def recursiveFind(root_directory, pattern):
matches = []
for root, dirnames, filenames in os.walk(root_directory):
for filename in fnmatch.filter(filenames, pattern):
matches.append(os.path.join(root, filename))
return matches

62
songbook/index.py

@ -13,7 +13,7 @@ from unidecode import unidecode
import locale
import re
import sys
import warnings
#import warnings
from songbook.authors import processauthors
from songbook.plastex import simpleparse
@ -22,6 +22,7 @@ from songbook.plastex import simpleparse
keywordPattern = re.compile(r"^%(\w+)\s?(.*)$")
firstLetterPattern = re.compile(r"^(?:\{?\\\w+\}?)*[^\w]*(\w)")
def sortkey(value):
'''
From a title, return something usable for sorting. It handles locale (but
@ -30,35 +31,40 @@ def sortkey(value):
'''
return locale.strxfrm(unidecode(simpleparse(value).replace(' ', 'A')))
def processSXDEntry(tab):
return (tab[0], tab[1], tab[2])
def processSXD(filename):
file = open(filename)
index_file = open(filename)
data = []
for line in file:
for line in index_file:
data.append(line.strip())
file.close()
index_file.close()
i = 1
idx = index(data[0])
while len(data) > i and data[i].startswith('%'):
keywords = keywordPattern.match(data[i]).groups()
idx.keyword(keywords[0],keywords[1])
idx.keyword(keywords[0], keywords[1])
i += 1
idx.compileKeywords()
for i in range(i,len(data),3):
entry = processSXDEntry(data[i:i+3])
idx.add(entry[0],entry[1],entry[2])
for i in range(i, len(data), 3):
entry = processSXDEntry(data[i:i + 3])
idx.add(entry[0], entry[1], entry[2])
return idx
class index:
def __init__(self, indextype):
self.data = dict()
self.keywords = dict()
self.prefix_patterns = []
self.authwords = {"after": [], "ignore": [], "sep": []}
if indextype == "TITLE INDEX DATA FILE":
self.indextype = "TITLE"
elif indextype == "SCRIPTURE INDEX DATA FILE":
@ -70,23 +76,21 @@ class index:
def filter(self, key):
letter = firstLetterPattern.match(key).group(1)
if re.match('\d',letter):
if re.match('\d', letter):
letter = '0-9'
return (letter.upper(), key)
def keyword(self, key, word):
if not self.keywords.has_key(key):
if not key in self.keywords.keys():
self.keywords[key] = []
self.keywords[key].append(word)
def compileKeywords(self):
self.prefix_patterns = []
if self.indextype == "TITLE":
if 'prefix' in self.keywords:
for prefix in self.keywords['prefix']:
self.prefix_patterns.append(re.compile(r"^(%s)(\b|\\)(\s*.*)$" % prefix))
self.authwords = {"after": [], "ignore": [], "sep": []}
if self.indextype == "AUTHOR":
for key in self.keywords:
if key in self.authwords:
@ -94,20 +98,22 @@ class index:
for word in self.authwords.keys():
if word in self.keywords:
if word == "after":
self.authwords[word] = [re.compile(r"^.*%s\b(.*)" % after) for after in self.keywords[word]]
self.authwords[word] = [re.compile(r"^.*%s\b(.*)" % after)
for after in self.keywords[word]]
elif word == "sep":
self.authwords[word] = [" %s" % sep for sep in self.authwords[word]] + [","]
self.authwords[word] = [re.compile(r"^(.*)%s (.*)$" % sep) for sep in self.authwords[word] ]
self.authwords[word] = [re.compile(r"^(.*)%s (.*)$" % sep)
for sep in self.authwords[word]]
else:
self.authwords[word] = self.keywords[word]
def _raw_add(self, key, number, link):
(first, key) = self.filter(key)
if not self.data.has_key(first):
if not first in self.data.keys():
self.data[first] = dict()
if not self.data[first].has_key(key):
if not key in self.data[first].keys():
self.data[first][key] = []
self.data[first][key].append({'num':number, 'link':link})
self.data[first][key].append({'num': number, 'link': link})
def add(self, key, number, link):
if self.indextype == "TITLE":
@ -116,8 +122,8 @@ class index:
match = pattern.match(key)
if match:
self._raw_add(
"%s (%s)" % (match.group(2) + match.group(3), match.group(1)),
number, link)
"%s (%s)" % (match.group(2) + match.group(3),
match.group(1)), number, link)
return
self._raw_add(key, number, link)
@ -129,26 +135,26 @@ class index:
self._raw_add(author, number, link)
def refToStr(self, ref):
if sys.version_info >= (2,6):
if sys.version_info >= (2, 6):
return '\\hyperlink{{{0[link]}}}{{{0[num]}}}'.format(ref)
else:
return '\\hyperlink{%(link)s}{%(num)s}' % ref
def entryToStr(self, key, entry):
if sys.version_info >= (2,6):
if sys.version_info >= (2, 6):
return unicode('\\idxentry{{{0}}}{{{1}}}\n').format(key, '\\\\'.join(map(self.refToStr, entry)))
else:
return unicode('\\idxentry{%s}{%s}\n') % (key, '\\\\'.join(map(self.refToStr, entry)))
def idxBlockToStr(self, letter, entries):
str = '\\begin{idxblock}{'+letter+'}'+'\n'
string = '\\begin{idxblock}{' + letter + '}' + '\n'
for key in sorted(entries.keys(), key=sortkey):
str += self.entryToStr(key, entries[key])
str += '\\end{idxblock}'+'\n'
return str
string += self.entryToStr(key, entries[key])
string += '\\end{idxblock}' + '\n'
return string
def entriesToStr(self):
str = ""
string = ""
for letter in sorted(self.data.keys()):
str += self.idxBlockToStr(letter, self.data[letter])
return str
string += self.idxBlockToStr(letter, self.data[letter])
return string

2
songbook/plastex-songs.py

@ -5,6 +5,7 @@ import plasTeX
from songbook.plastex import processUnbreakableSpace
def split_linebreak(texlist):
return_list = []
current = []
@ -18,6 +19,7 @@ def split_linebreak(texlist):
return_list.append(current)
return return_list
class beginsong(plasTeX.Command):
args = '{titles}[ args:dict ]'
def invoke(self, tex):

12
songbook/plastex.py

@ -5,23 +5,27 @@ from plasTeX.TeX import TeX
from plasTeX.Base.LaTeX import Sentences
import codecs
import copy
#import copy
import locale
import os
import sys
def processUnbreakableSpace(node):
"""Replace '~' and '\ ' in node by nodes that will be rendered as unbreakable space.
"""Replace '~' and '\ ' in node by nodes that
will be rendered as unbreakable space.
Return node object for convenience.
"""
if type(node) == Sentences.InterWordSpace or (type(node) == Sentences.NoLineBreak and node.source == '~ '):
if (type(node) == Sentences.InterWordSpace or
(type(node) == Sentences.NoLineBreak and node.source == '~ ')):
node.unicode = unichr(160)
for child in node.childNodes:
processUnbreakableSpace(child)
return node
def simpleparse(text):
"""Parse a simple LaTeX string.
"""
@ -30,6 +34,7 @@ def simpleparse(text):
doc = tex.parse()
return processUnbreakableSpace(doc.textContent)
class SongParser:
"""Analyseur syntaxique de fichiers .sg"""
@ -50,6 +55,7 @@ class SongParser:
tex.input(codecs.open(filename, 'r+', 'utf-8', 'replace'))
return tex.parse()
def parsetex(filename):
"""Analyse syntaxique d'un fichier .sg

20
songbook/songs.py

@ -10,6 +10,7 @@ import re
from songbook.authors import processauthors
from songbook.plastex import parsetex
class Song:
#: Ordre de tri
sort = []
@ -19,10 +20,15 @@ class Song:
authwords = {"after": [], "ignore": [], "sep": []}
def __init__(self, path, languages, titles, args):
self.titles = titles
self.normalized_titles = [locale.strxfrm(unprefixed_title(unidecode(unicode(title, "utf-8")), self.prefixes)) for title in titles]
self.args = args
self.path = path
self.titles = titles
self.normalized_titles = [locale.strxfrm(
unprefixed_title(unidecode(unicode(title, "utf-8")),
self.prefixes
)
)
for title in titles]
self.args = args
self.path = path
self.languages = languages
if "by" in self.args.keys():
self.normalized_authors = [
@ -59,6 +65,7 @@ class Song:
return 1
return 0
def unprefixed_title(title, prefixes):
"""Remove the first prefix of the list in the beginning of title (if any).
"""
@ -68,6 +75,7 @@ def unprefixed_title(title, prefixes):
return match.group(2)
return title
class SongsList:
"""Manipulation et traitement de liste de chansons"""
@ -78,7 +86,6 @@ class SongsList:
# Liste triée des chansons
self.songs = []
def append(self, filename):
"""Ajout d'une chanson à la liste
@ -113,7 +120,8 @@ class SongsList:
def latex(self):
"""Renvoie le code LaTeX nécessaire pour intégrer la liste de chansons.
"""
result = [ '\\input{{{0}}}'.format(song.path.replace("\\","/").strip()) for song in self.songs]
result = ['\\input{{{0}}}'.format(song.path.replace("\\", "/").strip())
for song in self.songs]
result.append('\\selectlanguage{%s}' % self._language)
return '\n'.join(result)

Loading…
Cancel
Save