Mercurial > dottes
changeset 588:afc031477784
Replace sed substitution with Python templating for HTML and LaTeX output.
author | Jim Hague <jim.hague@acm.org> |
---|---|
date | Wed, 02 Nov 2016 00:21:18 +0000 |
parents | 1b79867b4f35 |
children | 5db7e72d4219 |
files | abcfield.py abctemplate.py dottes.html.learnertune dottes.html.tune dottes.html.tuneindex dottes.tex.firstline-tune dottes.tex.tune makeBookeTunePages.sh makeWeb.sh |
diffstat | 9 files changed, 155 insertions(+), 123 deletions(-) [+] |
line wrap: on
line diff
--- a/abcfield.py Mon Oct 31 23:55:28 2016 +0000 +++ b/abcfield.py Wed Nov 02 00:21:18 2016 +0000 @@ -156,7 +156,7 @@ # Return the raw text for a given field. Optionally the nth field is taken, # or the field data must start with a designated string to be recognised. def getFieldText(inf, field, n = 1, starts = None): - res = None + res = "" for line in inf: line = line.strip() if len(line) > 2 and line[1] == ':':
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/abctemplate.py Wed Nov 02 00:21:18 2016 +0000 @@ -0,0 +1,88 @@ +#!/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. +# * composer. The tune composer. +# * key. The tune key. +# * 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 + +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('input', type=argparse.FileType('r'), + help='input ABC file') + args = parser.parse_args() + + with args.input as f: + lines = f.readlines() + + input_path = pathlib.Path(args.input.name) + + vars = dict() + vars["changename"] = "" + vars["changetitle"] = "" + vars["changevisibility"] = "no" + vars["creditvisibility"] = "no" + + vars["name"] = input_path.stem + vars["title"] = getFieldDisplayText(lines, "T", latex=args.latex) + vars["subtitle"] = getFieldDisplayText(lines, "T", n=2, latex=args.latex) + vars["composer"] = getFieldDisplayText(lines, "C", latex=args.latex) + vars["key"] = getFieldDisplayText(lines, "K", latex=args.latex) + vars["changefile"] = getFieldDisplayText(lines, "N", starts="Change:", latex=args.latex) + vars["credit"] = getFieldDisplayText(lines, "N", starts="Credit:", latex=args.latex) + + if vars["changefile"]: + vars["changevisibility"] = "yes" + vars["changename"] = pathlib.Path(vars["changefile"]).stem + cf = pathlib.Path(input_path.parent, vars["changefile"]) + with cf.open() as f: + vars["changetitle"] = getFieldDisplayText(f, "T", latex=args.latex) + + if vars["credit"]: + vars["creditvisibility"] = "yes" + + for val in args.values: + keyval = val.partition("=") + vars[keyval[0]] = keyval[2] + + print(string.Template(args.template.read()).substitute(vars))
--- a/dottes.html.learnertune Mon Oct 31 23:55:28 2016 +0000 +++ b/dottes.html.learnertune Wed Nov 02 00:21:18 2016 +0000 @@ -2,7 +2,7 @@ <html lang="en"> <head> <meta charset="utf-8" /> - <title>Cry Havoc tunes - learning @TITLE@</title> + <title>Cry Havoc tunes - learning ${title}</title> <link rel="stylesheet" href="../css/reset.css" /> <link rel="stylesheet" href="../css/text.css" /> <link rel="stylesheet" href="../css/960.css" /> @@ -33,7 +33,7 @@ <div class="dottes-tune-header"> <div class="dottes-tune-header-row"> <div class="dottes-tune-header-left"> - <a class="dottes-tune-icon-link" href="@TUNE@.html"> + <a class="dottes-tune-icon-link" href="${name}.html"> <img class="dottes-tune-table-image" src="../img/music.png" alt="Dottes"> </a> @@ -43,15 +43,15 @@ </a> </div> <div class="dottes-tune-header-middle"> - <h1>@TITLE@</h1> - <h2>@SUBTITLE@</h2> + <h1>${title}</h1> + <h2>${subtitle}</h2> </div> <div class="dottes-tune-header-right"> - <em>@COMPOSER@</em> + <em>${composer}</em> </div> </div> </div> - <p>@TITLE@ is in the key of @KEY@. + <p>${title} is in the key of ${key}. <div class="dottes-tune-footer"> <div class="dottes-tune-footer-row"> <div class="dottes-tune-footer-left"> @@ -59,14 +59,14 @@ </div> <div class="dottes-tune-footer-centre"> <audio controls loop> - <source src="../@MASTERBOOKE@/normal-@TUNE@.mp3" type="audio/mpeg" /> - <source src="../@MASTERBOOKE@/normal-@TUNE@.ogg" type="audio/ogg" /> + <source src="../${masterbooke}/normal-${name}.mp3" type="audio/mpeg" /> + <source src="../${masterbooke}/normal-${name}.ogg" type="audio/ogg" /> <object classid="clsid:22D6F312-B0F6-11D0-94AB-0080C74C7E95"> - <param name="FileName" value="normal-@TUNE@.mp3" /> + <param name="FileName" value="normal-${name}.mp3" /> <param name="autoStart" value="false" /> <param name="autoplay" value="false" /> <param name="playCount" value="100000" /> - <object type="audio/mpeg" data="normal-@TUNE@.mp3"> + <object type="audio/mpeg" data="normal-${name}.mp3"> <param name="controller" value="true" /> <param name="autoplay" value="false" /> <param name="playCount" value="100000" /> @@ -77,9 +77,9 @@ <div class="dottes-tune-footer-right"> <ul class="tune-data-list"> <li><a class="dottes-link-tune dottes-mp3" download - href="../@MASTERBOOKE@/@TUNE@.mp3">MP3</a></li> + href="../${masterbooke}/${name}.mp3">MP3</a></li> <li><a class="dottes-link-tune dottes-ogg" download - href="../@MASTERBOOKE@/@TUNE@.ogg">OGG</a></li> + href="../${masterbooke}/${name}.ogg">OGG</a></li> </ul> </div> </div> @@ -89,14 +89,14 @@ </div> <div class="dottes-tune-footer-centre"> <audio controls loop> - <source src="../@MASTERBOOKE@/littleslow-@TUNE@.mp3" type="audio/mpeg" /> - <source src="../@MASTERBOOKE@/littleslow-@TUNE@.ogg" type="audio/ogg" /> + <source src="../${masterbooke}/littleslow-${name}.mp3" type="audio/mpeg" /> + <source src="../${masterbooke}/littleslow-${name}.ogg" type="audio/ogg" /> <object classid="clsid:22D6F312-B0F6-11D0-94AB-0080C74C7E95"> - <param name="FileName" value="littleslow-@TUNE@.mp3" /> + <param name="FileName" value="littleslow-${name}.mp3" /> <param name="autoStart" value="false" /> <param name="autoplay" value="false" /> <param name="playCount" value="100000" /> - <object type="audio/mpeg" data="littleslow-@TUNE@.mp3"> + <object type="audio/mpeg" data="littleslow-${name}.mp3"> <param name="controller" value="true" /> <param name="autoplay" value="false" /> <param name="playCount" value="100000" /> @@ -107,9 +107,9 @@ <div class="dottes-tune-footer-right"> <ul class="tune-data-list"> <li><a class="dottes-link-tune dottes-mp3" download - href="../@MASTERBOOKE@/littleslow-@TUNE@.mp3">MP3</a></li> + href="../${masterbooke}/littleslow-${name}.mp3">MP3</a></li> <li><a class="dottes-link-tune dottes-ogg" download - href="../@MASTERBOOKE@/littleslow-@TUNE@.ogg">OGG</a></li> + href="../${masterbooke}/littleslow-${name}.ogg">OGG</a></li> </ul> </div> </div> @@ -119,14 +119,14 @@ </div> <div class="dottes-tune-footer-centre"> <audio controls loop> - <source src="../@MASTERBOOKE@/slow-@TUNE@.mp3" type="audio/mpeg" /> - <source src="../@MASTERBOOKE@/slow-@TUNE@.ogg" type="audio/ogg" /> + <source src="../${masterbooke}/slow-${name}.mp3" type="audio/mpeg" /> + <source src="../${masterbooke}/slow-${name}.ogg" type="audio/ogg" /> <object classid="clsid:22D6F312-B0F6-11D0-94AB-0080C74C7E95"> - <param name="FileName" value="slow-@TUNE@.mp3" /> + <param name="FileName" value="slow-${name}.mp3" /> <param name="autoStart" value="false" /> <param name="autoplay" value="false" /> <param name="playCount" value="100000" /> - <object type="audio/mpeg" data="slow-@TUNE@.mp3"> + <object type="audio/mpeg" data="slow-${name}.mp3"> <param name="controller" value="true" /> <param name="autoplay" value="false" /> <param name="playCount" value="100000" /> @@ -137,9 +137,9 @@ <div class="dottes-tune-footer-right"> <ul class="tune-data-list"> <li><a class="dottes-link-tune dottes-mp3" download - href="../@MASTERBOOKE@/slow-@TUNE@.mp3">MP3</a></li> + href="../${masterbooke}/slow-${name}.mp3">MP3</a></li> <li><a class="dottes-link-tune dottes-ogg" download - href="../@MASTERBOOKE@/slow-@TUNE@.ogg">OGG</a></li> + href="../${masterbooke}/slow-${name}.ogg">OGG</a></li> </ul> </div> </div> @@ -149,14 +149,14 @@ </div> <div class="dottes-tune-footer-centre"> <audio controls loop> - <source src="../@MASTERBOOKE@/veryslow-@TUNE@.mp3" type="audio/mpeg" /> - <source src="../@MASTERBOOKE@/veryslow-@TUNE@.ogg" type="audio/ogg" /> + <source src="../${masterbooke}/veryslow-${name}.mp3" type="audio/mpeg" /> + <source src="../${masterbooke}/veryslow-${name}.ogg" type="audio/ogg" /> <object classid="clsid:22D6F312-B0F6-11D0-94AB-0080C74C7E95"> - <param name="FileName" value="veryslow-@TUNE@.mp3" /> + <param name="FileName" value="veryslow-${name}.mp3" /> <param name="autoStart" value="false" /> <param name="autoplay" value="false" /> <param name="playCount" value="100000" /> - <object type="audio/mpeg" data="veryslow-@TUNE@.mp3"> + <object type="audio/mpeg" data="veryslow-${name}.mp3"> <param name="controller" value="true" /> <param name="autoplay" value="false" /> <param name="playCount" value="100000" /> @@ -167,9 +167,9 @@ <div class="dottes-tune-footer-right"> <ul class="tune-data-list"> <li><a class="dottes-link-tune dottes-mp3" download - href="../@MASTERBOOKE@/veryslow-@TUNE@.mp3">MP3</a></li> + href="../${masterbooke}/veryslow-${name}.mp3">MP3</a></li> <li><a class="dottes-link-tune dottes-ogg" download - href="../@MASTERBOOKE@/veryslow-@TUNE@.ogg">OGG</a></li> + href="../${masterbooke}/veryslow-${name}.ogg">OGG</a></li> </ul> </div> </div>
--- a/dottes.html.tune Mon Oct 31 23:55:28 2016 +0000 +++ b/dottes.html.tune Wed Nov 02 00:21:18 2016 +0000 @@ -2,7 +2,7 @@ <html lang="en"> <head> <meta charset="utf-8" /> - <title>Cry Havoc tunes - @TITLE@</title> + <title>Cry Havoc tunes - ${title}</title> <link rel="stylesheet" href="../css/reset.css" /> <link rel="stylesheet" href="../css/text.css" /> <link rel="stylesheet" href="../css/960.css" /> @@ -24,7 +24,7 @@ <div class="dottes-tune-header"> <div class="dottes-tune-header-row"> <div class="dottes-tune-header-left"> - <a class="dottes-tune-icon-link" href="learner-@TUNE@.html"> + <a class="dottes-tune-icon-link" href="learner-${name}.html"> <img class="dottes-tune-table-image" src="../img/learner.png" alt="Learner"> </a> @@ -34,49 +34,49 @@ </a> </div> <div class="dottes-tune-header-middle"> - <h1>@TITLE@</h1> - <h2>@SUBTITLE@</h2> + <h1>${title}</h1> + <h2>${subtitle}</h2> </div> <div class="dottes-tune-header-right"> - <em>@COMPOSER@</em> + <em>${composer}</em> </div> </div> </div> - <img class="dottes-png" src="@TUNE@.png" alt="@TITLE@ dots"> - <div class="dottes-credit-@CREDITVISIBILITY@"> - From @CREDIT@. + <img class="dottes-png" src="${name}.png" alt="${title} dots"> + <div class="dottes-credit-${creditvisibility}"> + From ${credit}. </div> - <div class="dottes-change-@CHANGEVISIBILITY@"> + <div class="dottes-change-${changevisibility}"> Change: <a class="dottes-change-link" - href="@CHANGETUNE@">@CHANGETITLE@</a> + href="${changename}.html">${changetitle}</a> </div> <div class="dottes-tune-footer"> <div class="dottes-tune-footer-row"> <div class="dottes-tune-footer-left"> <ul class="tune-data-list"> <li><a class="dottes-link-tune dottes-pdf" download - href="@TUNE@.pdf">PDF</a></li> + href="${name}.pdf">PDF</a></li> <li><a class="dottes-link-tune dottes-midi" download - href="../@MASTERBOOKE@/@TUNE@.mid">MIDI</a></li> + href="../${masterbooke}/${name}.mid">MIDI</a></li> <li><a class="dottes-link-tune dottes-mp3" download - href="../@MASTERBOOKE@/@TUNE@.mp3">MP3</a></li> + href="../${masterbooke}/${name}.mp3">MP3</a></li> <li><a class="dottes-link-tune dottes-ogg" download - href="../@MASTERBOOKE@/@TUNE@.ogg">OGG</a></li> + href="../${masterbooke}/${name}.ogg">OGG</a></li> <li><a class="dottes-link-tune dottes-abc" download - href="@TUNE@.abc">ABC</a></li> + href="${name}.abc">ABC</a></li> <li><a class="dottes-link-tune dottes-xml" download - href="@TUNE@.xml">XML</a></li> + href="${name}.xml">XML</a></li> </ul> </div> <div class="dottes-tune-footer-centre"> <audio controls> - <source src="../@MASTERBOOKE@/@TUNE@.mp3" type="audio/mpeg" /> - <source src="../@MASTERBOOKE@/@TUNE@.ogg" type="audio/ogg" /> + <source src="../${masterbooke}/${name}.mp3" type="audio/mpeg" /> + <source src="../${masterbooke}/${name}.ogg" type="audio/ogg" /> <object classid="clsid:22D6F312-B0F6-11D0-94AB-0080C74C7E95"> - <param name="FileName" value="@TUNE@.mp3" /> + <param name="FileName" value="${name}.mp3" /> <param name="autoStart" value="false" /> <param name="autoplay" value="false" /> - <object type="audio/mpeg" data="@TUNE@.mp3"> + <object type="audio/mpeg" data="${name}.mp3"> <param name="controller" value="true" /> <param name="autoplay" value="false" /> </object> @@ -84,7 +84,7 @@ </audio> </div> <div class="dottes-tune-footer-right"> - Last changed @LASTCHANGED@ + Last changed ${lastchanged} </div> </div> </div>
--- a/dottes.html.tuneindex Mon Oct 31 23:55:28 2016 +0000 +++ b/dottes.html.tuneindex Wed Nov 02 00:21:18 2016 +0000 @@ -1,14 +1,14 @@ <div class="dottes-tune-list-item"> <div class="dottes-tune-list-item-link"> - <a class="dottes-tune-link" href="@TUNE@.html">@TITLE@</a> - <a href="learner-@TUNE@.html"> + <a class="dottes-tune-link" href="${name}.html">${title}</a> + <a href="learner-${name}.html"> <img class="dottes-tune-table-image" src="../img/learner.png" alt="Learner"> </a> </div> <div class="dottes-tune-list-item-image"> - <a href="@TUNE@.html"> - <img class="dottes-tune-table-image" src="firstline-@TUNE@.png" - alt="@TITLE@ first line"> + <a href="${name}.html"> + <img class="dottes-tune-table-image" src="firstline-${name}.png" + alt="${title} first line"> </a> </div> </div>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dottes.tex.firstline-tune Wed Nov 02 00:21:18 2016 +0000 @@ -0,0 +1,1 @@ +\showfirstline{$name}{$title}{$graphicsdir/firstline-$name}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dottes.tex.tune Wed Nov 02 00:21:18 2016 +0000 @@ -0,0 +1,1 @@ +\showtune{$name}{$title}{$subtitle}{$composer}{$graphicsdir/$name}{$changename}{$changetitle}{$credit}
--- a/makeBookeTunePages.sh Mon Oct 31 23:55:28 2016 +0000 +++ b/makeBookeTunePages.sh Wed Nov 02 00:21:18 2016 +0000 @@ -30,21 +30,6 @@ find $booke -name "*.abc" | sort | while read filename do - name=`basename $filename .abc` - title=`$dir/abcfield.py --field T --latex --display $filename` - subtitle=`$dir/abcfield.py --index 2 --field T --latex --display $filename` - composer=`$dir/abcfield.py --field C --latex $filename` - - changefile=`$dir/abcfield.py --field N --starts "Change:" $filename` - changename="" - changetitle="" - if [ -n "$changefile" ]; then - changename=`basename $changefile .abc` - changetitle=`$dir/abcfield.py --field T --latex --display $booke/$changefile` - fi - - credit=`$dir/abcfield.py --field N --starts "Credit:" $filename` - echo -E "\showtune{$name}{$title}{$subtitle}{$composer}{$graphicsdir/$name}{$changename}{$changetitle}{$credit}" >> $tunesoutput - - echo -E "\showfirstline{$name}{$title}{$graphicsdir/firstline-$name}" >> $indexoutput + $dir/abctemplate.py --latex --value "graphicsdir=$graphicsdir" --template $dir/dottes.tex.tune $filename >> $tunesoutput + $dir/abctemplate.py --latex --value "graphicsdir=$graphicsdir" --template $dir/dottes.tex.firstline-tune $filename >> $indexoutput done
--- a/makeWeb.sh Mon Oct 31 23:55:28 2016 +0000 +++ b/makeWeb.sh Wed Nov 02 00:21:18 2016 +0000 @@ -66,25 +66,6 @@ do name=`basename $filename .abc` - # Extract items to substitute in the web page. - title=`$dir/abcfield.py --field T --display $filename` - subtitle=`$dir/abcfield.py --index 2 --field T --display $filename` - composer=`$dir/abcfield.py --field C $filename` - changefile=`$dir/abcfield.py --field N --starts "Change:" $filename` - changetitle="" - changevisibility="no" - if [ -n "$changefile" ]; then - changetitle=`$dir/abcfield.py --field T --display $bookedir/$changefile` - changevisibility="yes" - fi - credit=`$dir/abcfield.py --field N --starts "Credit:" $filename` - creditvisibility="no" - if [ -n "$credit" ]; then - creditvisibility="yes" - fi - lastchanged=`hg log --limit 1 --template "{date|shortdate}" $masterbookedir/${name}.abc` - key=`$dir/abcfield.py --field K --display $filename` - # Copy the ABC into the web. cp $filename $webdir @@ -101,38 +82,14 @@ popd > /dev/null fi + # Get date and time of last change to tune. + lastchanged=`hg log --limit 1 --template "{date|shortdate}" $masterbookedir/${name}.abc` + # Generate the tune web page. tunepage=${name}.html learnerpage=learner-${name}.html - # If the title contains HTML character entities, escape - # initial '&' in the title - it means things to sed. - sed -e "s/@TITLE@/${title//&/\\&}/" \ - -e "s/@SUBTITLE@/${subtitle}/" \ - -e "s/@COMPOSER@/${composer}/" \ - -e "s/@KEY@/${key}/" \ - -e "s/@MASTERBOOKE@/${masterbooke}/" \ - -e "s/@CHANGETITLE@/${changetitle//&/\\&}/" \ - -e "s/@CHANGETUNE@/${changefile/.abc/.html}/" \ - -e "s/@CHANGEVISIBILITY@/${changevisibility}/" \ - -e "s/@CREDIT@/${credit}/" \ - -e "s/@CREDITVISIBILITY@/${creditvisibility}/" \ - -e "s/@LASTCHANGED@/${lastchanged}/" \ - -e "s/@TUNE@/${name}/" dottes.html.tune > $webdir/$tunepage - - sed -e "s/@TITLE@/${title//&/\\&}/" \ - -e "s/@SUBTITLE@/${subtitle}/" \ - -e "s/@COMPOSER@/${composer}/" \ - -e "s/@KEY@/${key}/" \ - -e "s/@MASTERBOOKE@/${masterbooke}/" \ - -e "s/@CHANGETITLE@/${changetitle//&/\\&}/" \ - -e "s/@CHANGETUNE@/${changefile/.abc/.html}/" \ - -e "s/@CHANGEVISIBILITY@/${changevisibility}/" \ - -e "s/@CREDIT@/${credit}/" \ - -e "s/@CREDITVISIBILITY@/${creditvisibility}/" \ - -e "s/@LASTCHANGED@/${lastchanged}/" \ - -e "s/@TUNE@/${name}/" dottes.html.learnertune > $webdir/$learnerpage - - sed -e "s/@TITLE@/${title//&/\\&}/" \ - -e "s/@TUNE@/${name}/" dottes.html.tuneindex >> $webdir/$tunelist + $dir/abctemplate.py --value "masterbooke=${masterbooke}" --value "lastchanged=${lastchanged}" --template dottes.html.tune $filename > $webdir/$tunepage + $dir/abctemplate.py --value "masterbooke=${masterbooke}" --value "lastchanged=${lastchanged}" --template dottes.html.learnertune $filename > $webdir/$learnerpage + $dir/abctemplate.py --template dottes.html.tuneindex $filename >> $webdir/$tunelist done