sing-alongs/make.py

157 lines
4.6 KiB
Python
Raw Normal View History

#!/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]()