diff options
author | Karl Berry <karl@freefriends.org> | 2022-11-07 20:29:26 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2022-11-07 20:29:26 +0000 |
commit | e0a35a2f5cf21734d3f8d18f4fb734487d6fb354 (patch) | |
tree | f1c5e0977fe9d1baa8d364b4c382f18a6f07f4f9 /Master/texmf-dist/doc | |
parent | fd564106f892f61d00995f5bf92bbe09700339ab (diff) |
songproj (7nov22)
git-svn-id: svn://tug.org/texlive/trunk@64966 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/doc')
-rw-r--r-- | Master/texmf-dist/doc/latex/songproj/LICENSE | 24 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/songproj/README.md | 66 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/songproj/examples/clementine.txt | 39 | ||||
-rwxr-xr-x | Master/texmf-dist/doc/latex/songproj/song2tex.py | 101 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/songproj/songproj.pdf | bin | 0 -> 100783 bytes |
5 files changed, 230 insertions, 0 deletions
diff --git a/Master/texmf-dist/doc/latex/songproj/LICENSE b/Master/texmf-dist/doc/latex/songproj/LICENSE new file mode 100644 index 00000000000..9b4bccb254c --- /dev/null +++ b/Master/texmf-dist/doc/latex/songproj/LICENSE @@ -0,0 +1,24 @@ +Copyright (C) 2022 by Tanguy Ortolo <tanguy+latex@ortolo.eu> + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/Master/texmf-dist/doc/latex/songproj/README.md b/Master/texmf-dist/doc/latex/songproj/README.md new file mode 100644 index 00000000000..1c3c073b52e --- /dev/null +++ b/Master/texmf-dist/doc/latex/songproj/README.md @@ -0,0 +1,66 @@ +songproj +======== + +Commands and environments for generating Beamer slideshows with song lyrics, +typically for religious services with a projector. + +Author: Tanguy Ortolo +License: 3-Clause BSD + +Description +----------- + +This package, together with the Beamer class, is used to generate slideshows +with song lyrics. This is typically used in religious services in churches +equipped with a projector, for which this package has been written, but it can +be useful for any type of singing assembly. It provides environments to +describe a song in a natural way, and formatting it into slides with overlays. + +Example +------- + +Detailed usage can be found in the PDF documentation. Here is a simple example: + +```latex +\documentclass{beamer} +\usepackage{songproj} +\begin{document} + \begin{frame} + \begin{song}{2} + \longest{Light she was, and like a fairy,} + \begin{couplet} + In a cavern, in a canyon, \\ + Excavating for a mine. \\ + Dwelt a miner, forty-niner, \\ + And his daughter, Clementine. \\ + \end{couplet} + \begin{refrain} + Oh my darling, oh my darling, \\ + Oh my darling Clementine, \\ + You are lost and gone forever, \\ + Dreadful sorry, Clementine. \\ + \end{refrain} + \begin{couplet} + Light she was, and like a fairy, \\ + And her shoes were number nine, \\ + Herring boxes, without topses, \\ + Sandals were for Clementine. \\ + \end{couplet} + \begin{couplet} + […] + \end{couplet} + \end{song} + \end{frame} +\end{document} +``` + +Add-on script +------------- + +This package comes with an additional script, `song2tex.py`, that can be used +to convert plain-text song lyrics to the expected LaTeX markup. The file +`example/clementine.txt` can be used to test it: + +```sh +./song2tex.py examples/clementine.txt /tmp/clementine.tex +``` diff --git a/Master/texmf-dist/doc/latex/songproj/examples/clementine.txt b/Master/texmf-dist/doc/latex/songproj/examples/clementine.txt new file mode 100644 index 00000000000..d0cc0f8aa81 --- /dev/null +++ b/Master/texmf-dist/doc/latex/songproj/examples/clementine.txt @@ -0,0 +1,39 @@ +1. In a cavern, in a canyon, +Excavating for a mine. +Dwelt a miner, forty-niner, +And his daughter, Clementine. + +C. Oh my darling, oh my darling, +Oh my darling Clementine, +You are lost and gone forever, +Dreadful sorry, Clementine. + +2. Light she was, and like a fairy, +And her shoes were number nine, +Herring boxes, without topses, +Sandals were for Clementine. + +3. Drove she ducklings to the water, +Ev'ry morning just at nine, +Hit her foot against a splinter +Fell into the foaming brine. + +4. Ruby lips above the water, +Blowing bubbles, soft and fine, +Alas, for me! I was no swimmer, +So I lost my Clementine. + +5. In a churchyard, near the canyon, +Where the myrtle boughs entwine, +There grow roses, and other posies, +Fertilized by Clementine. + +6. Then the miner, forty-niner, +Soon began to peak and pine, +Thought he "oughter jine" his daughter, +Now he's with his Clementine. + +7. In my dreams she still doth haunt me, +Robed in garments soaked in brine; +Though in life I used to hug her, +Now she's dead, I'll draw the line. diff --git a/Master/texmf-dist/doc/latex/songproj/song2tex.py b/Master/texmf-dist/doc/latex/songproj/song2tex.py new file mode 100755 index 00000000000..dc32da2b3fa --- /dev/null +++ b/Master/texmf-dist/doc/latex/songproj/song2tex.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python3 + +import argparse +import enum +import re + + +# The following regexp match the typical markers of refrain and couplet: +re_refrain = re.compile(r'(R(efrain)?|C(horus)?)( |[-./] ?)', re.IGNORECASE) +re_couplet = re.compile(r'\d+( |[-./] ?)') + + +def match_rest(regexp, s): + """Match the start of string s against the given regexp: + * if it matches, return the non-matching part; + * it it does not matches, return None.""" + if (m := regexp.match(s)) is not None: + return s[m.end():] + else: + return None + + +class State(enum.Enum): + """A state indicates in what context we are while parsing a song.""" + LIMBO = 0 # Not in the refrain or in a couplet + REFRAIN = 1 # In the refrain + COUPLET = 2 # In a couplet + + +def parse_song(lines, re_refrain, re_couplet): + # At the beginning of the song, we are not in the refrain or in a couplet. + state = State.LIMBO + # This variable will be used to record the longest line seen so far. + longest = '' + for line in lines: + line = line.rstrip() + if state == State.LIMBO: + # We are not in the refrain or in a couplet. Depending on what we find: + if (rest := match_rest(re_refrain, line)) is not None: + # when a refrain start marker is found, enter the refrain. + yield '\\begin{refrain}\n' + state = State.REFRAIN + line = rest + yield ' {} \\\\\n'.format(line) + elif (rest := match_rest(re_couplet, line)) is not None: + # when a couplet start marker is found, enter a couplet. + yield '\\begin{couplet}\n' + state = State.COUPLET + line = rest + yield ' {} \\\\\n'.format(line) + elif line != '': + # when a non-empty line is found, also enter a couplet as all. + yield '\\begin{couplet}\n' + state = State.COUPLET + yield ' {} \\\\\n'.format(line) + elif state == State.REFRAIN: + # We are in the refrain. Depending on what we find: + if line != '': + # when a non-empty line is found, stay in the refrain. + yield ' {} \\\\\n'.format(line) + else: + # when an empty line is found, leave the refrain. + yield '\\end{refrain}\n\n' + state = State.LIMBO + elif state == State.COUPLET: + # We are in a couplet. Depending on what we find: + if line != '': + # when a non-empty line is found, stay in the couplet. + yield ' {} \\\\\n'.format(line) + else: + # when an empty line is found, leave the couplet. + yield '\\end{couplet}\n\n' + state = State.LIMBO + # No matter what we found, we have a song line, possibly empty, that we + # have to check to see if it could not be the new longest line seen so far. + if len(line) > len(longest): + longest = line + # The song text file is now finished. We may still be in the refrain or in a + # couplet, that we have to close. + if state == State.REFRAIN: + yield '\\end{refrain}\n\n' + elif state == State.COUPLET: + yield '\\end{couplet}\n\n' + # Now print the longest line of the entire song. + yield '\\longest{{{}}}\n'.format(longest) + + +def main(args=None): + parser = argparse.ArgumentParser(description="Convert song text to LaTeX songproj markup") + parser.add_argument("--refrain", '-r', type=re.compile, default=re_refrain, metavar="REGEXP", + help="specify the refrain marker (regexp, default to \"{}\")".format(re_refrain.pattern)) + parser.add_argument("--couplet", '-c', type=re.compile, default=re_couplet, metavar="REGEXP", + help="specify the couplet marker (regexp, default \"{}\")".format(re_couplet.pattern)) + parser.add_argument("infile", help="input song text file", type=argparse.FileType('r')) + parser.add_argument("outfile", help="output LaTeX file", type=argparse.FileType('w')) + args = parser.parse_args(args) + for line in parse_song(args.infile, args.refrain, args.couplet): + args.outfile.write(line) + +if __name__ == "__main__": + main() diff --git a/Master/texmf-dist/doc/latex/songproj/songproj.pdf b/Master/texmf-dist/doc/latex/songproj/songproj.pdf Binary files differnew file mode 100644 index 00000000000..24216ce1505 --- /dev/null +++ b/Master/texmf-dist/doc/latex/songproj/songproj.pdf |