#!/usr/bin/env python # -*- coding: utf-8 -*- import os import re import shutil import subprocess import sys OUTDIR = 'out' PDFDIR = 'pdf' IMG_OUTDIR = os.path.join(OUTDIR, 'images') PDFFILE = 'singalongs.pdf' PDFBOOKLETFILE = 'singalongs_booklet.pdf' PSFILE = 'singalongs.ps' TEXFILE = 'singalongs.tex' LYTEXFILE = os.path.join(OUTDIR, 'singalongs.lytex') GITFILE = 'revision.tex' def build(): make_paths() assemble() git_info() copy() build_book() build_booklet() def make_paths(): if not os.path.exists(OUTDIR): os.makedirs(OUTDIR) if not os.path.exists(PDFDIR): os.makedirs(PDFDIR) def assemble(): lilyfiles = find_ly_files() songmap = build_songmap(lilyfiles) lytex_source = build_lytex('singalongs.tex', songmap) with open(LYTEXFILE, 'w') as f: f.write(lytex_source) def git_info(): latest_rev = subprocess.check_output('git log -1 --format="%h"', shell=True) latest = '\\newcommand{\\revision}{' + latest_rev.decode('utf-8').strip() + '}' with open(GITFILE, 'w') as f: f.write(latest) def copy(): shutil.copy('lilysettings.ly', OUTDIR) shutil.copy('headfoot.tex', OUTDIR) shutil.copy('settings.tex', OUTDIR) shutil.copy(GITFILE, OUTDIR) if os.path.exists(IMG_OUTDIR): shutil.rmtree(IMG_OUTDIR) shutil.copytree('images', IMG_OUTDIR) def build_book(): lilycmd = 'lilypond-book --latex-program=lualatex --process="lilypond -dinclude-settings=lilysettings.ly" --pdf -o {0} {1}'.format(OUTDIR, LYTEXFILE) pdfcmd = 'lualatex {}'.format(TEXFILE) indexcmd = 'makeindex {}'.format(TEXFILE) subprocess.call(lilycmd, shell=True) subprocess.call(pdfcmd, shell=True, cwd=OUTDIR) subprocess.call(indexcmd, shell=True, cwd=OUTDIR) subprocess.call(pdfcmd, shell=True, cwd=OUTDIR) shutil.copy(os.path.join(OUTDIR, PDFFILE), os.path.join(PDFDIR, PDFFILE)) os.remove(GITFILE) def build_booklet(): pdf2pscmd = 'pdf2ps {0} {1}'.format(os.path.join(OUTDIR, PDFFILE), os.path.join(OUTDIR, PSFILE)) psbookcmd = 'psbook {0} {1}'.format(os.path.join(OUTDIR, PSFILE), os.path.join(OUTDIR, 'booklet_tmp.ps')) pstopscmd = "pstops -pA4 '1:0@1.0(0cm,0cm)' {0} {1}".format(os.path.join(OUTDIR, 'booklet_tmp.ps'), os.path.join(OUTDIR, 'booklet_tmp00.ps')) psnupcmd = 'psnup -2 {0} {1}'.format(os.path.join(OUTDIR, 'booklet_tmp00.ps'), os.path.join(OUTDIR, 'booklet.ps')) ps2pdfcmd = 'ps2pdf {0} {1}'.format(os.path.join(OUTDIR, 'booklet.ps'), os.path.join(PDFDIR, PDFBOOKLETFILE)) subprocess.call(pdf2pscmd, shell=True) subprocess.call(psbookcmd, shell=True) subprocess.call(pstopscmd, shell=True) subprocess.call(psnupcmd, shell=True) subprocess.call(ps2pdfcmd, shell=True) def clean(): shutil.rmtree(OUTDIR) lily_template = """ \chapter {[[title]]} \lilypondfile{[[scorefile]]} ~\\ ~\\ \input{[[lyricfile]]} """ def find_ly_files(path='./scores'): lilyfiles = [] for found_file in os.listdir(path): if found_file.endswith(".ly"): filepath = os.path.join(path, found_file) lilyfiles.append(filepath) return lilyfiles def build_songmap(lilyfiles, lyric_folder='./lyrics'): songmap = [] for scorefile in lilyfiles: filename_with_ext = os.path.basename(scorefile) filename = os.path.splitext(filename_with_ext)[0] lyricfile = os.path.join(lyric_folder, "{0}.tex".format(filename)) title = find_title(scorefile) # for windows systems scorefile = scorefile.replace('\\', '/') lyricfile = lyricfile.replace('\\', '/') songmap.append({'scorefile': scorefile, 'lyricfile': lyricfile, 'title': title }) return songmap def find_title(scorefile): with open(scorefile) as opened_file: score = opened_file.read() title = re.findall('title = "(.*)"', score) return title[0] def build_lytex(base_template, songmap): lilychapters = [] for song in sorted(songmap, key=lambda k: k['scorefile']): lilychapter = lily_template.replace('[[title]]', song['title']) lilychapter = lilychapter.replace('[[scorefile]]', song['scorefile']) lilychapter = lilychapter.replace('[[lyricfile]]', song['lyricfile']) lilychapters.append(lilychapter) lilychapters_string = create_lilychapter_string(lilychapters) with open(base_template) as opened_file: template = opened_file.read() template = template.replace('\\musicbooklet', lilychapters_string) return template def create_lilychapter_string(lilychapters): lilychapter_string = '' for lilychapter in lilychapters: lilychapter_string += '{0}\n'.format(lilychapter) return lilychapter_string if __name__ == "__main__": action = sys.argv[1] if len(sys.argv) > 1 else 'build' globals()[action]()