summaryrefslogtreecommitdiff
path: root/macros/unicodetex/latex/lilyglyphs/scripts/lily-image-commands.py
diff options
context:
space:
mode:
Diffstat (limited to 'macros/unicodetex/latex/lilyglyphs/scripts/lily-image-commands.py')
-rwxr-xr-xmacros/unicodetex/latex/lilyglyphs/scripts/lily-image-commands.py321
1 files changed, 321 insertions, 0 deletions
diff --git a/macros/unicodetex/latex/lilyglyphs/scripts/lily-image-commands.py b/macros/unicodetex/latex/lilyglyphs/scripts/lily-image-commands.py
new file mode 100755
index 0000000000..fce67ad53c
--- /dev/null
+++ b/macros/unicodetex/latex/lilyglyphs/scripts/lily-image-commands.py
@@ -0,0 +1,321 @@
+#!/usr/bin/env python
+
+# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+# %
+# This file is part of the 'lilyglyphs' LaTeX package. %
+# ========== %
+# %
+# https://github.com/openlilylib/lilyglyphs %
+# http://www.openlilylib.org/lilyglyphs %
+# %
+# Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+# %
+# 'lilyglyphs' is free software: you can redistribute it and/or modify %
+# it under the terms of the LaTeX Project Public License, either %
+# version 1.3 of this license or (at your option) any later version. %
+# You may find the latest version of this license at %
+# http://www.latex-project.org/lppl.txt %
+# more information on %
+# http://latex-project.org/lppl/ %
+# and version 1.3 or later is part of all distributions of LaTeX %
+# version 2005/12/01 or later. %
+# %
+# This work has the LPPL maintenance status 'maintained'. %
+# The Current Maintainer of this work is Urs Liska (see above). %
+# %
+# This work consists of the files listed in the file 'manifest.txt' %
+# which can be found in the 'license' directory. %
+# %
+# This program is distributed in the hope that it will be useful, %
+# but WITHOUT ANY WARRANTY; without even the implied warranty of %
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+# %
+# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+import os, sys, getopt, datetime, subprocess, argparse, lilyglyphs_common as lg
+
+
+
+# ###############
+# string to be printed before the actual command
+lily_src_prefix = """\\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+"""
+
+# string to be printed after the actual command definition
+lily_src_score = """
+ \\score {
+ \\new Staff \\with {
+ \\remove "Staff_symbol_engraver"
+ \\remove "Clef_engraver"
+ \\remove "Time_signature_engraver"
+ }
+"""
+
+def main():
+ """Do the actual work of the script"""
+ print ''
+ print 'buildglyphimages.py,'
+ print 'Part of lilyglyphs.'
+ print ''
+
+ # set CWD and ensure the necessary subdirs are present
+ check_paths()
+ print ''
+
+ # load and parse input file
+ lg.read_input_file(in_file)
+ read_entries()
+ print ''
+
+ # generate LilyPond source files for each command
+ # and compile them
+ write_lily_src_files()
+ print ''
+ lg.compile_lily_files()
+ print ''
+
+ # remove intermediate files and move pdfs to pdf directory
+ lg.cleanup_lily_files()
+ print ''
+
+ # generate latex commands and example code
+ # and write them to the output file
+ lg.generate_latex_commands()
+ print ''
+ write_latex_file()
+
+
+def check_paths():
+ """Sets CWD to 'glyphimages' subdir or root of lilyglyphs_private
+ and makes sure that the necessary subdirectories are present"""
+
+ # one level above 'definitions' is 'glyphimages'
+ os.chdir(os.path.join(in_path, '..'))
+
+ # check the presence of the necessary subdirectories
+ # and create them if necessary
+ # (otherwise we'll get errors when trying to write in them)
+ ls = os.listdir('.')
+ if not lg.dir_lysrc in ls:
+ os.mkdir(lg.dir_lysrc)
+ if not lg.dir_pdfs in ls:
+ os.mkdir(lg.dir_pdfs)
+ if not lg.dir_cmd in ls:
+ os.mkdir(lg.dir_cmd)
+
+def cmd_filename(cmd_name):
+ if cmd_name.startswith('lily'):
+ return cmd_name[:4] + '-' + cmd_name[4:]
+ elif cmd_name.startswith('lily-'):
+ return cmd_name
+ else:
+ return 'lily-' + cmd_name
+
+# set default scale and raise arguments to empty
+scale = ''
+rais = ''
+
+def read_entries():
+ """Parses the input source file and extracts glyph entries"""
+ print 'Read entries of LilyPond commands:'
+ for i in range(len(lg.definitions_file)):
+ if '%%lilyglyphs' in lg.definitions_file[i]:
+ i = read_entry(i)
+ print lg.lily_files
+
+def read_entry(i):
+ """Reads a single glyph entry from the input file and stores it
+ in the global dictionary lg.in_cmds"""
+ global scale, rais
+ # read comment line(s)
+ i += 1
+ is_protected = False
+ comment = []
+ # loop over the comment line(s)
+ while i < len(lg.definitions_file):
+ line = lg.definitions_file[i].strip()
+ # check for 'protected' entries that shouldn't be processed newly
+ if not line[0] == '%':
+ break
+ elif '%%protected' in line:
+ is_protected = True
+ elif 'scale=' in line:
+ dummy, scale = line.split('=')
+ elif 'raise=' in line:
+ dummy, rais = line.split('=')
+ else:
+ line = line[1:].strip()
+ comment.append(line)
+ i += 1
+
+ # remove any empty lines
+ while len(lg.definitions_file[i].strip()) == 0:
+ i += 1
+
+ # read command name
+ line = lg.definitions_file[i].strip()
+ cmd_name = line[: line.find('=') - 1]
+ print '- ' + cmd_name,
+ if is_protected:
+ print '(protected and skipped)'
+ else:
+ print '' #(for line break only)
+
+ # read actual command until we find a line the begins with a closing curly bracket
+ i += 1
+ lilySrc = []
+ while lg.definitions_file[i][0] != '}':
+ lilySrc.append(lg.definitions_file[i])
+ i += 1
+ if not is_protected:
+ lg.in_cmds[cmd_name] = {}
+ lg.in_cmds[cmd_name]['comment'] = comment
+ lg.in_cmds[cmd_name]['lilySrc'] = lilySrc
+ lg.in_cmds[cmd_name]['element'] = cmd_filename(cmd_name)
+ lg.in_cmds[cmd_name]['type'] = 'image'
+ if scale:
+ lg.in_cmds[cmd_name]['scale'] = scale
+ if rais:
+ lg.in_cmds[cmd_name]['raise'] = rais
+
+ lg.lily_files.append(cmd_filename(cmd_name))
+ return i
+
+
+def usage():
+ print """buildglyphimages. Part of the lilyglyphs package.
+ Parses a template file, creates
+ single .ly files from it, uses LilyPond to create single glyph
+ pdf files and set up template files to be used in LaTeX.
+ The input file has to be located in the glyphimages folder
+ of either the lilyglyph package itself or of a copy of
+ the lilyglyphs_private directory structure contained in the
+ distribution.
+ For detailed instructions refer to the manual.
+ Usage:
+ buildglyphimages.py in-file-name.
+ """
+
+def write_file_info(name, fout):
+ """Formats file specific information for the lilyPond source file"""
+ long_line = '% This file defines a single glyph to be created with LilyPond: %\n'
+ width = len(long_line) - 1
+ header = '%' * width + '\n'
+ spacer = '%' + ' ' * (width - 2) + '%\n'
+ padding = width - len(name) - 8
+ fout.write(header)
+ fout.write(spacer)
+ fout.write(long_line)
+ fout.write(spacer)
+ fout.write('% ' + name + '.ly' + ' ' * padding + '%\n')
+ fout.write(spacer)
+ fout.write(header)
+ fout.write(lg.signature())
+ fout.write('\n\n')
+
+def write_latex_file():
+ """Composes LaTeX file and writes it to disk"""
+ print 'Generate LaTeX file'
+ print lg.dir_cmd, in_basename
+ lg.write_latex_file(os.path.join(os.getcwd(), lg.dir_cmd, in_basename + '.tex'))
+
+def write_lily_src_files():
+ """Generates one .ly file for each found new command"""
+ skip_cmds = []
+ print 'Write .ly files for each entry:'
+ for cmd_name in lg.in_cmds:
+ print '- ' + cmd_name
+ gen_src_name = os.path.join(lg.dir_lysrc, cmd_filename(cmd_name) + '.ly')
+ # handle existing commands
+ if os.path.exists(gen_src_name):
+ action = ''
+ while not (action == 'Y' or action == 'N'):
+ action = raw_input('already present. Overwrite (y/n)? ')
+ action = action.upper()
+ if action == 'N':
+ skip_cmds.append(cmd_name)
+ continue
+
+ # open a single lily src file for write access
+ fout = open(gen_src_name, 'w')
+
+ #output the license information
+ fout.write(lg.lilyglyphs_copyright_string)
+ fout.write('\n')
+
+ #output information on the actual file
+ write_file_info(cmd_name, fout)
+
+ #write the default LilyPond stuff
+ fout.write(lily_src_prefix)
+
+ # write the comment for the command
+ fout.write('%{\n')
+ for line in lg.in_cmds[cmd_name]['comment']:
+ fout.write(line + '\n')
+ fout.write('%}\n\n')
+
+ # write the actual command
+ fout.write(cmd_name + ' = {\n')
+ for line in lg.in_cmds[cmd_name]['lilySrc']:
+ fout.write(line + '\n')
+ fout.write('}\n')
+
+ # write the score definition
+ fout.write(lily_src_score)
+
+ # finish the LilyPond file
+ fout.write(' \\' + cmd_name + '\n')
+ fout.write('}\n\n')
+
+ fout.close()
+
+ # remove skipped commands from in_cmds
+ print skip_cmds
+ for cmd_name in skip_cmds:
+ del lg.in_cmds[cmd_name]
+ lg.lily_files.remove(cmd_filename(cmd_name))
+
+# ####################################
+# Finally launch the program
+if __name__ == "__main__":
+
+ # parse command line arguments
+ parser = argparse.ArgumentParser(
+ description='Process templates to LilyPond input files,' +
+ 'compile these and generate LaTeX commands.',
+ parents=[lg.common_arguments])
+ parser.add_argument('i',
+ type=lg.is_file,
+ metavar='INPUT',
+ help='File with command templates.')
+ args = parser.parse_args()
+
+ # if we have exactly one existing file
+ # join its components and run the program
+
+ # process filename argument, providing absolute path
+ script_path, script_name = os.path.split(sys.argv[0])
+
+ in_file = os.path.join(os.getcwd(), vars(args)['i'])
+ # check if the input file is in the right place
+ # this has to be the definitions subdir of
+ # the package directory or the lilyglyphs_private dir
+ in_path, in_filename = os.path.split(in_file)
+ in_path = os.path.normpath(in_path)
+ if not (('lilyglyphs' in in_path) and (in_path.endswith('definitions'))):
+ print 'File in the wrong location: ' + in_path
+ usage()
+ sys.exit(2)
+ in_basename, in_ext = os.path.splitext(in_filename)
+ main()