view abctemplate.py @ 738:69a7499817c8 build-default-284

On Nook and A5 prints, start a new page with each tune and centre vertically.. A5 mostly did, but ran into trouble with longer comments on a tune. This may give blank space after tunes where a long comment overflows onto another page, but I think for now it's better to have each tune at the top of the page. Or rather, and this is the other change, in the middle of the page. Centre the page content for A5 and Nook.
author Jim Hague <jim.hague@acm.org>
date Thu, 12 Oct 2017 14:50:51 +0100
parents c81a1ed21877
children
line wrap: on
line source

#!/usr/bin/env python3
#
# Fill in a template with data from fields in an ABC file.
# Fields have any ABC accented characters converted to HTML (default) or Latex.
#
# Rearrange some field contents into display format:
# * In Title fields, change 'sort' form such as 'Exploding Potato, The'
#   to display format 'The Exploding Potato'.
# * In Key fields, translate the ABC key representation to full text,
#   e.g. G#dor becomes G# Dorian.
#
# Recognise continuation header fields and print those too. The ABC standard
# defines continuation fields as starting ':+'. Regrettably none of the tools
# I am using the Booke recognise that syntax, so I am adopting a Booke
# convention of '<header>:+' *also* being a continuation. Note that a
# continuation is a distinct line in the field value; the value has a line
# break between it and the previous line.
#
# Templates are read from file, and are in Python standard library format.
# The following values are substituted:
# * name. The file base name. Base filename without extension.
# * title. The tune title.
# * subtitle. The tune subtitle (second Title field), if any.
# * fulltitle. The tune title followed, if it exists, by " (" subtitle ")"
# * tradition. The Morris tradition the dance tune is from.
# * composer. The tune composer.
# * key. The tune key.
# * parts. The tune parts order (A(AB2)3 etc.).
# * changefile. The name of the 'change' file, if any.
# * changename. The change file base name.
# * changetitle. The change file tune title.
# * changevisibility. "yes" if there's a change value, otherwise "no".
# * credit. The 'credit' value.
# * creditvisibility. "yes" if there's a credit value, otherwise "no".
#

import argparse
import pathlib
import string

from abcfield import getFieldDisplayText, getFullTitle

def getFileData(f, latex):
    res = {}
    input_path = pathlib.Path(args.input.name)
    res["name"] = input_path.stem
    fdir = input_path.parent

    lines = f.readlines()
    res["title"] = getFieldDisplayText(lines, fdir, "T", latex=latex)
    res["subtitle"] = getFieldDisplayText(lines, fdir, "T", n=2, latex=latex)
    res["fulltitle"] = getFullTitle(lines, fdir, latex=latex)
    res["tradition"] = getFieldDisplayText(lines, fdir, "A", latex=latex)
    res["composer"] = getFieldDisplayText(lines, fdir, "C", latex=latex)
    res["key"] = getFieldDisplayText(lines, fdir, "K", latex=latex)
    res["parts"] = getFieldDisplayText(lines, fdir, "P", latex=latex)
    res["notes"] = getFieldDisplayText(lines, fdir, "N", starts="Dottes:", latex=latex)
    res["history"] = getFieldDisplayText(lines, fdir, "H", starts="Dottes:", latex=latex)
    return res

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Substitute values from ABC file into template.')
    parser.add_argument('-l', '--latex', dest='latex',
                        action='store_true',
                        help='output LaTeX formatted values (default is HTML)')
    parser.add_argument('-t', '--template', dest='template',
                        type=argparse.FileType('r'),
                        required=True,
                        help='template file')
    parser.add_argument('-v', '--value', dest='values', action="append",
                        default=[], help='define var=value items for templater')
    parser.add_argument('-n', '--next', dest='nextfile',
                        type=argparse.FileType('r'),
                        help='next tune file')
    parser.add_argument('-p', '--prev', dest='prevfile',
                        type=argparse.FileType('r'),
                        help='previous tune file')
    parser.add_argument('input', type=argparse.FileType('r'),
                        help='input ABC file')
    args = parser.parse_args()

    fields = getFileData(args.input, args.latex)

    vars = {}
    vars["notesvisibility"] = "no"
    vars["historyvisibility"] = "no"

    for name in ["name", "title", "subtitle", "fulltitle", "tradition",
                 "composer", "key", "parts", "notes", "history"]:
        vars[name] = fields[name]

    if vars["notes"]:
        vars["notesvisibility"] = "yes"
    if vars["history"]:
        vars["historyvisibility"] = "yes"

    if args.nextfile:
        fields = getFileData(args.nextfile, args.latex)
    for name in ["name", "title", "subtitle", "fulltitle"]:
        vars["next" + name] = fields[name] if args.nextfile else ""

    if args.prevfile:
        fields = getFileData(args.prevfile, args.latex)
    for name in ["name", "title", "subtitle", "fulltitle"]:
        vars["prev" + name] = fields[name] if args.prevfile else ""

    for val in args.values:
        keyval = val.partition("=")
        vars[keyval[0]] = keyval[2]

    print(string.Template(args.template.read()).substitute(vars))