diff --git a/songbook.py b/songbook.py index 5fe664a8..97a45095 100755 --- a/songbook.py +++ b/songbook.py @@ -8,96 +8,117 @@ import glob import re import json -def makeTexFile(songbook, output): +def matchRegexp(reg, iterable): + return [ m.group(1) for m in (reg.match(l) for l in iterable) if m ] + +def songslist(songs): + directories = set(["img/"] + map(lambda x: "songs/" + os.path.dirname(x), songs)) + result = ['\\graphicspath{'] + [ ' {{{0}/}},'.format(d) for d in directories ] + ['}'] + [ '\\input{{songs/{0}}}'.format(s.strip()) for s in songs ] + return '\n'.join(result) + +def parseTemplate(template): + embeddedJsonPattern = re.compile(r"^%%:") + f = open(template) + code = [ line[3:-1] for line in f if embeddedJsonPattern.match(line) ] + f.close() + data = json.loads(''.join(code)) + return data["parameters"] + +def toValue(parameter, data): + if "type" not in parameter: + return data + elif parameter["type"] == "stringlist": + if "join" in parameter: + joinText = parameter["join"] + else: + 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)) + +def formatDefinition(name, value): + return '\\set@{name}{{{value}}}\n'.format(name=name, value=value) + +def makeTexFile(sb, output): name = output[:-4] # default value - dir = ['img'] template = "songbook.tmpl" songs = [] - booktype = ["chorded"] # parse the songbook data - if "template" in songbook: - template = songbook["template"] - if "songs" in songbook: - songs = songbook["songs"] - if "booktype" in songbook: - booktype = songbook["booktype"] + if "template" in sb: + template = sb["template"] + del sb["template"] + if "songs" in sb: + songs = sb["songs"] + del sb["songs"] + + parameters = parseTemplate("templates/"+template) # output relevant fields out = open(output, 'w') - - # output \template - out.write('\\newcommand{\\template}{\n') - for key in ["title", "author", "subtitle", "version", "mail", "picture", "picturecopyright", "footer", "licence"]: - if key in songbook: - out.write(' \\'+key+'{{{data}}}\n'.format(data=songbook[key])) - out.write('}\n') - # output \booktype - out.write('\\newcommand{{\\booktype}}{{{data}}}'.format(data=','.join(booktype))) - # output \songlist - if not type(songs) is list: - if songs == "all": - l = glob.glob('songs/*/*.sg') - l.sort() - songs = map(lambda x: x[6:], l) + 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"})) + # 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))) + # output songslist + if songs == "all": + songs = map(lambda x: x[6:], glob.glob('songs/*/*.sg')) + songs.sort() if len(songs) > 0: - out.write('\\newcommand{\\songslist}{\n') - dir += map(os.path.dirname, map(lambda x:"songs/"+x, songs)) - dir = set(dir) - out.write(' \\graphicspath{\n') - for dirname in dir: - out.write(' {{{imagedir}/}},\n'.format(imagedir=dirname)) - out.write(' }\n') - for song in songs: - out.write(' \\input{{songs/{songfile}}}\n'.format(songfile=song.strip())) - out.write('}\n') - tmpl = open("templates/"+template) - out.write(tmpl.read().replace("SONGBOOKNAME", name+"_index")) - tmpl.close() - out.close() + out.write(formatDefinition('songslist', songslist(songs))) + out.write('\\makeatother\n') + + # output template + commentPattern = re.compile(r"^\s*%") + f = open("templates/"+template) + content = [ line for line in f if not commentPattern.match(line) ] + f.close() + out.write(''.join(content)) + out.close() def makeDepend(sb, output): name = output[:-2] - # pattern that get dependencies dependsPattern = re.compile(r"^[^%]*(?:include|input)\{(.*?)\}") indexPattern = re.compile(r"^[^%]*\\(?:newauthor|new)index\{.*\}\{(.*?)\}") lilypondPattern = re.compile(r"^[^%]*\\(?:lilypond)\{(.*?)\}") # check for deps (in sb data) - deps = [] - if type(sb["songs"]) is list: - deps += map(lambda x: "songs/"+x, sb["songs"]) - for k in sb.keys(): - if not type(sb[k]) is list: - match = dependsPattern.match(sb[k]) - if match: - deps += [match.group(1)] + deps = matchRegexp(dependsPattern, [ v for v in sb.itervalues() if type(v) is not list ]) + if sb["songs"] == "all": + deps += glob.glob('songs/*/*.sg') + else: + deps += map(lambda x: "songs/" + x, sb["songs"]) # check for lilypond deps (in songs data) if necessary lilypond = [] - if "booktype" in sb.keys() and "lilypond" in sb["booktype"]: + if "booktype" in sb and "lilypond" in sb["booktype"]: for filename in deps: tmpl = open(filename) - for l in tmpl: - match = lilypondPattern.match(l) - if match: - lilypond.append(match.group(1)) + lilypond += matchRegexp(lilypondPattern, tmpl) tmpl.close() # check for index (in template file) if "template" in sb: - filename = "templates/"+sb["template"] + filename = sb["template"] else: - filename = "templates/songbook.tmpl" - idx = [] - tmpl = open(filename) - for l in tmpl: - match = indexPattern.match(l) - if match: - idx.append(match.group(1).replace("SONGBOOKNAME", name+"_index")) + filename = "songbook.tmpl" + tmpl = open("templates/"+filename) + idx = map(lambda x: x.replace("\getname", name), matchRegexp(indexPattern, tmpl)) tmpl.close() # write .d file diff --git a/songbook.sb b/songbook.sb index 26e40491..c520a714 100644 --- a/songbook.sb +++ b/songbook.sb @@ -7,6 +7,6 @@ "picture" : "feel-the-music", "picturecopyright" : "foxygamergirl @ deviantart.com", "footer" : "\\begin{flushleft}\\includegraphics[width=3cm]{on-fire}\\end{flushleft}", -"licence" : "\\input{license.tex}", +"license" : "\\input{license.tex}", "songs" : "all" } diff --git a/templates/songbook.tmpl b/templates/songbook.tmpl index 7b657e54..a19300db 100644 --- a/templates/songbook.tmpl +++ b/templates/songbook.tmpl @@ -21,53 +21,40 @@ % % Modified to serve personnal purposes. Newer versions can be % obtained from http://www.lohrun.net. - -% Template optionnal parameters (to be read by songbook-client) -% template mandatory parameter are currently booktype, template and songs -% the first two have default values but not last one -%%:{"parameters" : [ -%%: {"name":"title", "description":"Title", "type":"string"}, -%%: {"name":"author", "description":"Author", "type":"string", "default":"Alexandre"}, -%%: {"name":"version", "description":"Version", "type":"string", "default":"1"}, -%%: {"name":"subtitle", "description":"Subtitle", "type":"string"}, -%%: {"name":"mail", "description":"Email", "type":"string"}, -%%: {"name":"picture", "description":"Picture", "type":"string"}, -%%: {"name":"picturecopyright", "description":"Copyright", "type":"string"}, -%%: {"name":"footer", "description":"Footer", "type":"string"}, -%%: {"name":"license", "description":"License", "type":"string"} -%%: ] +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Template parameters +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%:{"parameters" : { +%%: "title" : {"description":"Title", "default":"Recueil de chansons pour guitare"}, +%%: "author" : {"description":"Author", "default":"Romain Goffe \\and Alexandre Dupas"}, +%%: "version" : {"description":"Version", "default":"3.1"}, +%%: "subtitle" : {"description":"Subtitle"}, +%%: "mail" : {"description":"Email", "default":"crep@team-on-fire.com"}, +%%: "picture" : {"description":"Picture", "default":"feel-the-music"}, +%%: "picturecopyright" : {"description":"Copyright", "default":"foxygamergirl@deviantart.com"}, +%%: "footer" : {"description":"Footer", "default":"\\begin{flushleft}\\includegraphics[width=3cm]{on-fire}\\end{flushleft}"}, +%%: "license" : {"description":"License", "default":"\\input{license.tex}"}, +%%: "booktype" : {"description":"Booktype", "type":"stringlist", "default":["chorded"], "join":","} +%%: } %%:} - -% template variables -\providecommand{\template}{} -\providecommand{\songslist}{} -\providecommand{\booktype}{chorded} -% default template -\newcommand{\defaulttemplate}{ - \title{Recueil de chansons pour guitare} - \author{Romain Goffe \and Alexandre Dupas} - \subtitle{} - \version{3.1} - \mail{crep@team-on-fire.com} - \picture{feel-the-music} - \picturecopyright{©foxygamergirl @ deviantart.com} - \footer{ - \begin{flushleft} - \includegraphics[width=3cm]{on-fire} - \end{flushleft} - } - \licence{\input{license.tex}} -} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % begin document -\documentclass[\booktype]{crepbook} +\documentclass[\getbooktype]{crepbook} \usepackage[utf8]{inputenc} \usepackage[english,french]{babel} -\defaulttemplate -\template +\title{\gettitle} +\author{\getauthor} +\subtitle{\getsubtitle} +\version{\getversion} +\mail{\getmail} +\picture{\getpicture} +\picturecopyright{\getpicturecopyright} +\footer{\getfooter} +\licence{\getlicense} -\newindex{titleidx}{SONGBOOKNAME_title} -\newauthorindex{authidx}{SONGBOOKNAME_auth} +\newindex{titleidx}{\getname_title} +\newauthorindex{authidx}{\getname_auth} \graphicspath{ {img/}, @@ -82,8 +69,9 @@ \songsection{Chansons} \begin{songs}{titleidx,authidx} - \songslist + \getsongslist \end{songs} \end{document} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % end document diff --git a/test.sb b/test.sb index 4c666bb2..af1ac8f8 100644 --- a/test.sb +++ b/test.sb @@ -1,9 +1,13 @@ { "template" : "songbook.tmpl", -"booktype" : ["lyric"], -"title" : "Ceci est un test du template", +"author" : "Alex", +"version" : "1", +"booktype" : [ + "chorded", + "lilypond" + ], "songs" : [ - "Le_Donjon_de_Naheulbeuk/Geste_heroique.sg", - "Le_Donjon_de_Naheulbeuk/La_biere_du_donjon.sg" - ] + "Le_Donjon_de_Naheulbeuk/La_biere_du_donjon.sg", + "Le_Donjon_de_Naheulbeuk/Geste_heroique.sg" + ] }