summaryrefslogtreecommitdiff
path: root/Build/source/texk/musixtnt/musixtnt-2015-02-09
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/musixtnt/musixtnt-2015-02-09')
-rw-r--r--Build/source/texk/musixtnt/musixtnt-2015-02-09/AUTHORS5
-rw-r--r--Build/source/texk/musixtnt/musixtnt-2015-02-09/ChangeLog55
-rw-r--r--Build/source/texk/musixtnt/musixtnt-2015-02-09/Makefile.am20
-rw-r--r--Build/source/texk/musixtnt/musixtnt-2015-02-09/README53
-rw-r--r--Build/source/texk/musixtnt/musixtnt-2015-02-09/acinclude.m485
-rw-r--r--Build/source/texk/musixtnt/musixtnt-2015-02-09/configure.ac24
-rw-r--r--Build/source/texk/musixtnt/musixtnt-2015-02-09/fixmsxpart.1185
-rw-r--r--Build/source/texk/musixtnt/musixtnt-2015-02-09/fixmsxpart.c889
-rwxr-xr-xBuild/source/texk/musixtnt/musixtnt-2015-02-09/fixmsxpart.test37
-rw-r--r--Build/source/texk/musixtnt/musixtnt-2015-02-09/msxlint.136
-rw-r--r--Build/source/texk/musixtnt/musixtnt-2015-02-09/msxlint.c422
-rwxr-xr-xBuild/source/texk/musixtnt/musixtnt-2015-02-09/msxlint.test28
-rw-r--r--Build/source/texk/musixtnt/musixtnt-2015-02-09/tests/badtest.tex10
-rw-r--r--Build/source/texk/musixtnt/musixtnt-2015-02-09/tests/fixtest.tex159
-rw-r--r--Build/source/texk/musixtnt/musixtnt-2015-02-09/tests/linttest.tex10
-rw-r--r--Build/source/texk/musixtnt/musixtnt-2015-02-09/utils.c103
-rw-r--r--Build/source/texk/musixtnt/musixtnt-2015-02-09/utils.h64
17 files changed, 2185 insertions, 0 deletions
diff --git a/Build/source/texk/musixtnt/musixtnt-2015-02-09/AUTHORS b/Build/source/texk/musixtnt/musixtnt-2015-02-09/AUTHORS
new file mode 100644
index 00000000000..2684f199c52
--- /dev/null
+++ b/Build/source/texk/musixtnt/musixtnt-2015-02-09/AUTHORS
@@ -0,0 +1,5 @@
+Bob Tennent
+School of Computing
+Queen's University
+Kingston, Canada
+rdt@cs.queensu.ca
diff --git a/Build/source/texk/musixtnt/musixtnt-2015-02-09/ChangeLog b/Build/source/texk/musixtnt/musixtnt-2015-02-09/ChangeLog
new file mode 100644
index 00000000000..ea156221ff2
--- /dev/null
+++ b/Build/source/texk/musixtnt/musixtnt-2015-02-09/ChangeLog
@@ -0,0 +1,55 @@
+2015-02-09 RDT
+
+ Check for EOF and missing EOL.
+
+2015-02-06 RDT
+
+ Minor patches from Peter B.
+ Added test files and test scripts from Peter B.
+
+2015-02-04 RDT
+
+ Re-named fixmsxpart to satisfy Karl Berry.
+
+ Initial messages go to stderr if there is only one file
+ argument but to stdout for -v or -h.
+
+ Moved common utilities from msxlint and fixmsxpart
+ to utils.c.
+
+2015-01-29 RDT
+
+ Re-organized beams to allow ovelapping beams.
+
+ General code clean-up.
+
+2015-01-23 RDT
+
+ Re-organized synthesize_notes.
+
+ Don't assume \vnotes is for an appoggiatura without
+ \tinynotesize.
+
+ Discard \sk and \hsk commands but keep
+ \qsk, \hqsk and \off{...}.
+
+ Comment out \eject commands.
+
+ Deal with \{z|c|l}char[note] commands (which may have
+ embedded commands).
+
+2015-01-16 RDT
+
+ Added '%' to comment out \mulooseness etc. lines.
+
+2015-01-06 RDT
+
+ Avoid analyzing \def lines.
+
+2015-01-03 RDT
+
+ Workaround confusion between \bar and \barno.
+
+2015-01-02 RDT
+
+ First release.
diff --git a/Build/source/texk/musixtnt/musixtnt-2015-02-09/Makefile.am b/Build/source/texk/musixtnt/musixtnt-2015-02-09/Makefile.am
new file mode 100644
index 00000000000..0bbc30a2af2
--- /dev/null
+++ b/Build/source/texk/musixtnt/musixtnt-2015-02-09/Makefile.am
@@ -0,0 +1,20 @@
+bin_PROGRAMS = fixmsxpart msxlint
+fixmsxpart_SOURCES = utils.h utils.c fixmsxpart.c
+msxlint_SOURCES = utils.h utils.c msxlint.c
+AM_CFLAGS = -O4 -ansi -Wall -Wextra -pedantic-errors
+dist_man_MANS = fixmsxpart.1 msxlint.1
+## Tests
+##
+TESTS = fixmsxpart.test msxlint.test
+
+EXTRA_DIST =
+EXTRA_DIST += $(TESTS)
+DISTCLEANFILES =
+
+## fixmsxpart.test
+EXTRA_DIST += tests/fixtest.out tests/fixtest.tex
+DISTCLEANFILES += fixtest.*
+## msxlint.test
+EXTRA_DIST += tests/badtest.tex tests/linttest.tex tests/linttest.out
+DISTCLEANFILES += linttest.*
+
diff --git a/Build/source/texk/musixtnt/musixtnt-2015-02-09/README b/Build/source/texk/musixtnt/musixtnt-2015-02-09/README
new file mode 100644
index 00000000000..5dd90b25230
--- /dev/null
+++ b/Build/source/texk/musixtnt/musixtnt-2015-02-09/README
@@ -0,0 +1,53 @@
+This archive contains a MusiXTeX extension library musixtnt
+and C source code, binaries for Windows (32 bit and 64 bit)
+and MacOSX, and documentation for two programs: fixmsxpart
+and msxlint.
+
+musixtnt.tex provides a macro \TransformNotes that
+makes possble transformations of the effect of notes
+commands such as \notes. In general, the effect of
+\TransformNotes{input}{output} is that notes commands in
+the source will expect their arguments to match the input
+pattern, but the notes will be typeset according to the
+output pattern. An example is extracting single-instrument
+parts from a multi-instrument score.
+
+fixmsxpart corrects note spacing in a single-part MusiXTeX
+source (possibly derived from a multi-instrument score and
+as a result having irregular note spacing).
+
+msxlint detects incorrectly formatted notes lines in a
+MusiXTeX source file. This should be used before using
+\TransformNotes.
+
+To install:
+
+Create texmf/tex/generic/musixtnt in a local or personal
+texmf tree and move musixtnt.tex into it.
+
+Create texmf/doc/generic/musixtnt and move there the files
+in the doc directory.
+
+Update the file-name database as required by your TeX
+installation.
+
+If your platform is UNIX-like, process the
+musixtnt-2014-02-04.tar.gz file as usual (tar zxvf ...,
+./configure, make, make install).
+
+If your platform is Windows, move the executables
+msxlint.exe and fixmsxpart.exe in either the 32bit or the
+64bit folders to a folder on the executable PATH.
+
+If your platform is Mac OS-X, install the executables
+in the macosx directory.
+
+musixtnt.tex, fixmsxpart.c, utils.c and msxlint.c are
+licensed under the GPL version 2.
+
+Please report bugs and experience (good or bad) using these
+programs to me.
+
+Bob Tennent
+rdt@cs.queensu.ca
+2015-02-05
diff --git a/Build/source/texk/musixtnt/musixtnt-2015-02-09/acinclude.m4 b/Build/source/texk/musixtnt/musixtnt-2015-02-09/acinclude.m4
new file mode 100644
index 00000000000..4a581894bc7
--- /dev/null
+++ b/Build/source/texk/musixtnt/musixtnt-2015-02-09/acinclude.m4
@@ -0,0 +1,85 @@
+
+dnl
+dnl read lib version from file (and trim trailing newline)
+dnl
+define([EL_RELEASE], [patsubst(esyscmd([. src/shlib_version; echo $major.$minor]), [
+])])
+
+dnl
+dnl read cvsexport timestamp from file (and trim trailing newline)
+dnl
+define([EL_TIMESTAMP], [patsubst(esyscmd([date +"%Y%m%d"]), [
+])])
+
+
+dnl
+dnl NetBSD use the -mdoc macro package for manpages, but e.g.
+dnl AIX and Solaris only support the -man package.
+dnl
+AC_DEFUN([EL_MANTYPE],
+[
+ MANTYPE=
+ TestPath="/usr/bin${PATH_SEPARATOR}/usr/ucb"
+ AC_PATH_PROGS(NROFF, nroff awf, /bin/false, $TestPath)
+ if ${NROFF} -mdoc ${srcdir}/doc/editrc.5.roff >/dev/null 2>&1; then
+ MANTYPE=mdoc
+ fi
+ AC_SUBST(MANTYPE)
+])
+
+
+dnl
+dnl Check if getpwnam_r and getpwuid_r are POSIX.1 compatible
+dnl POSIX draft version returns 'struct passwd *' (used on Solaris)
+dnl NOTE: getpwent_r is not POSIX so we always use getpwent
+dnl
+AC_DEFUN([EL_GETPW_R_POSIX],
+[
+ AC_MSG_CHECKING([whether getpwnam_r and getpwuid_r are posix like])
+ # The prototype for the POSIX version is:
+ # int getpwnam_r(char *, struct passwd *, char *, size_t, struct passwd **)
+ # int getpwuid_r(uid_t, struct passwd *, char *, size_t, struct passwd **);
+ AC_TRY_LINK([#include <stdlib.h>
+ #include <sys/types.h>
+ #include <pwd.h>],
+ [getpwnam_r(NULL, NULL, NULL, (size_t)0, NULL);
+ getpwuid_r((uid_t)0, NULL, NULL, (size_t)0, NULL);],
+ [AC_DEFINE([HAVE_GETPW_R_POSIX], 1, [Define to 1 if you have getpwnam_r and getpwuid_r that are POSIX.1 compatible.])
+ AC_MSG_RESULT(yes)],
+ [AC_MSG_RESULT(no)])
+])
+
+AC_DEFUN([EL_GETPW_R_DRAFT],
+[
+ AC_MSG_CHECKING([whether getpwnam_r and getpwuid_r are posix _draft_ like])
+ # The prototype for the POSIX draft version is:
+ # struct passwd *getpwuid_r(uid_t, struct passwd *, char *, int);
+ # struct passwd *getpwnam_r(char *, struct passwd *, char *, int);
+ AC_TRY_LINK([#include <stdlib.h>
+ #include <sys/types.h>
+ #include <pwd.h>],
+ [getpwnam_r(NULL, NULL, NULL, (size_t)0);
+ getpwuid_r((uid_t)0, NULL, NULL, (size_t)0);],
+ [AC_DEFINE([HAVE_GETPW_R_DRAFT], 1, [Define to 1 if you have getpwnam_r and getpwuid_r that are draft POSIX.1 versions.])
+ AC_MSG_RESULT(yes)],
+ [AC_MSG_RESULT(no)])
+])
+
+
+dnl
+dnl use option --enable-widec to turn on use of wide-character support
+dnl
+AC_DEFUN([EL_ENABLE_WIDEC],
+[
+ AC_MSG_CHECKING(if you want wide-character code)
+ AC_ARG_ENABLE(widec,
+ [ --enable-widec compile with wide-char/UTF-8 code],
+ [with_widec=$enableval],
+ [with_widec=no])
+ AC_MSG_RESULT($with_widec)
+ if test "$with_widec" = yes ; then
+ AC_DEFINE(WIDECHAR, 1, [Define to 1 if you want wide-character code])
+ fi
+ AM_CONDITIONAL([WIDECHAR], [test "$with_widec" = yes])
+])
+
diff --git a/Build/source/texk/musixtnt/musixtnt-2015-02-09/configure.ac b/Build/source/texk/musixtnt/musixtnt-2015-02-09/configure.ac
new file mode 100644
index 00000000000..2f23faa8f8f
--- /dev/null
+++ b/Build/source/texk/musixtnt/musixtnt-2015-02-09/configure.ac
@@ -0,0 +1,24 @@
+AC_PREREQ(2.63)
+AC_INIT([musixtnt],[2015-02-09],[rdt@cs.queensu.ca])
+AC_CONFIG_AUX_DIR([.])
+AM_INIT_AUTOMAKE
+AC_CONFIG_HEADERS([config.h])
+
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+
+# Checks for programs.
+AC_PROG_CC
+AM_PROG_CC_C_O
+
+# Checks for header files.
+AC_CHECK_HEADERS([stdlib.h string.h stdio.h time.h getopt.h])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_HEADER_STDBOOL
+AC_TYPE_SIZE_T
+
+# Checks for library functions.
+AC_CHECK_FUNCS([strstr])
+
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
diff --git a/Build/source/texk/musixtnt/musixtnt-2015-02-09/fixmsxpart.1 b/Build/source/texk/musixtnt/musixtnt-2015-02-09/fixmsxpart.1
new file mode 100644
index 00000000000..2a546fcea3d
--- /dev/null
+++ b/Build/source/texk/musixtnt/musixtnt-2015-02-09/fixmsxpart.1
@@ -0,0 +1,185 @@
+.\" This manpage is licensed under the GNU Public License
+.TH FIXMSXPART 1 2015-02-05 "" ""
+
+.SH NAME
+fixmsxpart \- corrects note spacing in a single-staff MusiXTeX part
+
+.SH SYNOPSIS
+.B fixmsxpart
+.RB [ \-v\ |\ \-\-version\ |\ \-h\ |\ \-\-help ]
+
+.B fixmsxpart
+.RB [ \-d\ | \ \-\-debug ]
+.IR infile [ \fB.tex\fB ]
+.RI [ outfile [ \fB.tex\fP ]]
+
+
+Converts a single-staff MusiXTeX part (possibly derived from a multi-instrument score and as a result having irregular note spacing) to a single-staff part with proper spacing determined by the notes themselves.
+
+If
+.IR outfile
+is not specifed, standard output is used.
+
+.SH USAGE
+
+.SS Generating a Single-Instrument Part
+
+To generate a single-instrument part from (a copy of) the MusiXTeX source for
+a multi-instrument score, add
+.nf
+
+ \\input musixtnt
+
+.fi
+to the preamble,
+set
+.nf
+
+ \\instrumentnumber1
+
+.fi
+and use the \\TransformNotes macro defined in musixtnt.tex to discard all but one part.
+For example, the following line placed
+after
+\\startpiece (but before any note commands) would be appropriate for
+a
+.IR four -instrument
+score (arguments #2, #3, #4, and #5, separated by three &s),
+and will result in a part for the
+.IR second
+of these (#3):
+
+.nf
+ \\TransformNotes{#2&#3&#4&#5}{#3}
+.fi
+
+Argument #1 is a scaling
+parameter and should not be modified.
+.B
+It is essential that every \\znotes, \\notes, \\Notes, \\NOtes, etc. command in the score match the macro pattern exactly;
+insufficient (or too many) note segments
+will result in lost text and possibly compilation failure; see
+.BR msxlint (1).
+It is assumed by \\TransformNotes that notes commands are terminated by \\en (rather than \\enotes).
+
+Some additional manual changes to the source will be necessary:
+.TP 3
++
+adjustments of \\setname1, \\setclef1, \\setsign1 , \\setmeter1 and \\setstaffs1 commands, as necessary;
+.TP 3
++
+ensuring that tempo and roadmap markings
+.RB ( D.C. ,
+.BR Fine ,
+etc.) are in the
+appropriate instrument segment;
+.PP
+Finally, if the modified score is compiled and viewed, it may be seen that horizontal
+spacing designed for
+.I multiple
+instruments often produces bad
+spacing for a
+.IR single
+instrument.
+This can be corrected manually (and very tediously) but it is
+what
+.B fixmsxpart
+was designed to fix (much more conveniently).
+
+.SS Correcting Horizontal Spacing Using fixmsxpart
+The
+\\notes \\Notes \\NOtes \\NOTes...
+commands in a
+part derived from a multi-instrument score are unreliable,
+and so
+.B fixmsxpart
+determines the spacing for ordinary notes by the note
+commands themselves; for example,
+.TP 3
++
+\\qa, \\qu, \\ql, \\qp result in
+\\NOtes;
+.TP 3
++
+\\ca, \\cu, \\cl, \\ds result in \\Notes;
+.PP
+and so on.
+Spacing commands \\sk and \\hsk in the input are
+discarded (but \\qsk, \\hqsk and explicit uses of \\off{...} are preserved).
+
+.B fixmsxpart
+determines the spacing for
+.IR beamed
+notes by the beam
+multiplicity: \\ib... results in \\Notes, \\ibb... results in
+\\notes, etc. Some beam-termination commands (\\tb...) are
+problematic because the immediately-following beam note
+\\qb... must be spaced according to the spacing
+.IR before
+the \\tb... command. This is handled by setting a
+variable
+.IR new_beaming
+when processing the \\tb... command
+and only updating
+.IR beaming
+to
+.IR new_beaming
+when processing
+the subsequent beam note. This isn't needed for the
+abbreviations \\tqb, \\tqh, \\ztqb and \\ztqh which combine beam-termination and
+specification of the
+final beam note.
+
+.IR Pointed
+notes are
+.IR not
+given extra space
+automatically. They should be given extra space manually
+in the score
+by using either a \\roff-like command on the subsequent
+note or the \\qsk or \\hqsk spacing commands.
+
+Additional features of
+.BR fixmsxpart
+transformation:
+.TP 3
++
+Successive whole-bar rests are
+accumulated into a multi-bar rest, with appropriate adjustment of the bar number.
+.TP 3
++
+\\alaligne
+and \\alapage commands are replaced by \\bar.
+.TP 3
++
+\\mulooseness, \\eject, \\linegoal, \\song{top | bottom}, \\group{top | bottom}
+and \\akkoladen
+commands are commented out.
+.TP 3
++
+\\instrumentnumber... commands become
+\\instrumentnumber1.
+.TP 3
++
+\\nostartrule is added to
+the preamble.
+.TP 3
++
+Simple slurs or ties initiated by \\slur or \\tie are normalized by
+setting the
+.IR n
+parameter to 1 on the
+assumption that the new note spacing is correct.
+
+.SH LIMITATIONS
+Only single-staff instrumental parts are supported. User-defined macros are not expanded.
+A few esoteric MusiXTeX commands
+and constructions are not supported.
+
+.SH SEE ALSO
+.BR msxlint (1)
+.PP
+musixdoc.pdf
+
+.SH AUTHOR
+This program and manual page were written by Bob Tennent <rdt@cs.queensu.ca>.
diff --git a/Build/source/texk/musixtnt/musixtnt-2015-02-09/fixmsxpart.c b/Build/source/texk/musixtnt/musixtnt-2015-02-09/fixmsxpart.c
new file mode 100644
index 00000000000..0420109cb9a
--- /dev/null
+++ b/Build/source/texk/musixtnt/musixtnt-2015-02-09/fixmsxpart.c
@@ -0,0 +1,889 @@
+char version[12] = "2015-02-09";
+
+/* Copyright (C) 2014-15 R. D. Tennent School of Computing,
+ * Queen's University, rdt@cs.queensu.ca
+ *
+ * This program is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * 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. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General
+ * Public License along with this program; if not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/* fixmsxpart - corrects note spacing in a single-staff
+ * musixtex part
+ */
+
+
+# include "utils.h"
+
+# define NNOTES "\\vnotes1.6\\elemskip"
+# define NNNOTES "\\vnotes1.28\\elemskip"
+
+PRIVATE char infilename[LINE_LEN];
+PRIVATE char *infilename_n = infilename;
+PRIVATE char outfilename[LINE_LEN];
+PRIVATE char *outfilename_n = outfilename;
+
+PRIVATE FILE *infile, *outfile;
+
+PRIVATE int debug = 0;
+PRIVATE char line[LINE_LEN]; /* line of input */
+PRIVATE int staff = 1; /* staff number */
+PRIVATE char *notes; /* notes or other material for staff part */
+PRIVATE int spacing = 0; /* 0 = not determined; 1 = whole or breve, 2 = half,
+ 4 = quarter, 8 = eigth, etc. */
+PRIVATE int beaming = 0; /* beam-note spacing */
+PRIVATE int new_beaming = 0; /* spacing to be used *after* the next beam note */
+PRIVATE int restbars = 0; /* number of whole-bar rests not yet output */
+
+PRIVATE void
+usage (FILE *f)
+{
+ fprintf (f, "Usage: fixmsxpart [-v | --version | -h | --help]\n");
+ fprintf (f, " fixmsxpart infile[.tex] [outfile[.tex]] \n");
+}
+
+
+PRIVATE char
+*analyze_notes (char **ln) {
+/*
+ skip initial TeX command, which may be unreliable;
+ then skip staff-1 ampersands or vertical bars;
+ then truncate tail and return a pointer to the
+ beginning of the staff commands.
+ ln is moved to the token after \en
+*/
+ int i; char *s; char *t; char *tt;
+ s = strpbrk (*ln+1, "|&\\\n"); /* skip initial command */
+ while (true)
+ { /* look for \en */
+ t = strstr(s, "\\en");
+ if (t != NULL) break;
+ else
+ /* replace EOL by a blank and append another line of input */
+ { char new_line[LINE_LEN];
+ if (fgets (new_line, LINE_LEN, infile) == NULL)
+ error("Unexpected EOF.");
+ if ((t = strchr (s, '\n')) == NULL )
+ error("Missing EOL.");
+ *t = ' ';
+ t++;
+ *t = '\0';
+ if (append (line, &t, new_line, LINE_LEN) >= LINE_LEN)
+ error ("Line too Long.");
+ }
+ }
+ for (i=1; i<staff; i++) /* skip staff-1 & or | */
+ {
+ s = strpbrk (s, "|&");
+ if (s == NULL) error ("Can't find & or |.");
+ s++;
+ }
+ t = strstr(s, "\\en");
+ if (t == NULL) error ("Can't find \\en.");
+ *ln = t+3;
+ tt = strpbrk (s, "|&");
+ if ( tt != NULL && tt < t) t = tt;
+ *t = '\0';
+ if (debug > 0)
+ fprintf (stderr, "After analyze_notes notes=%s\n", s);
+ return s;
+}
+
+
+PRIVATE void
+output_notes (char *t)
+{ /* outputs text from *notes to *t (except for
+ commands \sk \hsk \noteskip= \multnoteskip);
+ then updates notes.
+ */
+ char *s = notes;
+ if (debug > 0)
+ fprintf (stderr, "\nBefore output_notes: notes=%s\n", s);
+ while (s < t)
+ {
+ /* discard commands \sk, \hsk, \noteskip= ..., \multnoteskip */
+ if ( prefix("\\sk", s) ||
+ prefix("\\hsk", s) ||
+ prefix("\\noteskip", s) ||
+ prefix("\\multnoteskip", s ) )
+ {
+ s = strchr (s+1, '\\');
+ if (s == NULL) break;
+ }
+ else
+ {
+ char *tt;
+ tt = strchr (s+1, '\\');
+ if (tt == NULL) tt = t;
+ while (s < tt)
+ { if (*s != '*') /* equivalent to \sk */
+ putc (*s, outfile);
+ s++;
+ }
+ }
+ }
+ notes = t;
+ if (debug > 0)
+ fprintf (stderr, "\nAfter output_notes, notes=%s\n", notes);
+}
+
+PRIVATE void
+output_rests (bool output_bar)
+{ /* outputs multi-bar rest and, possibly, a deferred \bar command */
+ switch (restbars)
+ { case 0: return;
+ case 1:
+ fprintf ( outfile, "\\NOTEs\\sk\\en\n" );
+ fprintf ( outfile, "\\def\\atnextbar{\\znotes\\centerpause\\en}%%\n" );
+ break;
+ case 2:
+ fprintf ( outfile, "\\NOTesp\\sk\\en\n" );
+ fprintf ( outfile, "\\def\\atnextbar{\\znotes\\centerbar{\\zcharnote{9}{\\meterfont\\lrlap2}}\\centerbar{\\PAuse}\\en}%%\n" );
+ break;
+ case 3:
+ fprintf ( outfile, "\\NOTes\\hqsk\\sk\\en\n" );
+ fprintf ( outfile, "\\def\\atnextbar{\\znotes\\centerbar{\\zcharnote{9}{\\meterfont\\lrlap3}}\\centerbar{\\PAuse\\off{2.5\\elemskip}\\pause}\\en}%%\n" );
+ break;
+ case 4:
+ fprintf ( outfile, "\\NOtesp\\sk\\en\n" );
+ fprintf ( outfile, "\\def\\atnextbar{\\znotes\\centerbar{\\zcharnote{9}{\\meterfont\\lrlap4}}\\centerbar{\\PAUSe}\\en}%%\n" );
+ break;
+ case 5:
+ fprintf ( outfile, "\\NOTes\\hqsk\\sk\\en\n" );
+ fprintf ( outfile, "\\def\\atnextbar{\\znotes\\centerbar{\\zcharnote{9}{\\meterfont\\lrlap5}}\\centerbar{\\PAUSe\\off{2.5\\elemskip}\\pause}\\en}%%\n" );
+ break;
+ case 6:
+ fprintf ( outfile, "\\NOTes\\hqsk\\sk\\en\n" );
+ fprintf ( outfile, "\\def\\atnextbar{\\znotes\\centerbar{\\zcharnote{9}{\\meterfont\\lrlap6}}\\centerbar{\\PAUSe\\off{2.5\\elemskip}\\PAuse}\\en}%%\n" );
+ break;
+ case 7:
+ fprintf ( outfile, "\\NOTEs\\hqsk\\sk\\en\n" );
+ fprintf ( outfile, "\\def\\atnextbar{\\znotes\\centerbar{\\zcharnote{9}{\\meterfont\\lrlap7}}\\centerbar{\\PAUSe\\off{2.5\\elemskip}\\PAuse\\off{2.5\\elemskip}\\pause}\\en}%%\n" );
+ break;
+ case 8:
+ fprintf ( outfile, "\\NOTes\\hqsk\\sk\\en\n" );
+ fprintf ( outfile, "\\def\\atnextbar{\\znotes\\centerbar{\\zcharnote{9}{\\meterfont\\lrlap8}}\\centerbar{\\PAUSe\\off{2.5\\elemskip}\\PAUSe}\\en}%%\n" );
+ break;
+ case 9:
+ fprintf ( outfile, "\\NOTEs\\hqsk\\sk\\en\n" );
+ fprintf ( outfile, "\\def\\atnextbar{\\znotes\\centerbar{\\zcharnote{9}{\\meterfont\\lrlap9}}\\centerbar{\\PAUSe\\off{2.5\\elemskip}\\PAUSe\\off{2.5\\elemskip}\\pause}\\en}%%\n" );
+ break;
+ default:
+ fprintf ( outfile, "\\NOTEs\\hqsk\\Hpause4{0.83}\\en\n" );
+ fprintf ( outfile, "\\def\\atnextbar{\\znotes\\centerbar{\\zcharnote{9}{\\meterfont\\lrlap{%d}}}\\en}%%\n", restbars );
+ }
+ if (restbars > 1)
+ fprintf ( outfile, "\\advance\\barno%d%%\n", restbars-1 );
+ restbars = 0;
+ if (output_bar)
+ fprintf ( outfile, "\\bar\n");
+}
+
+PRIVATE char *spacing_note (char *s, int new_spacing)
+{ /* outputs from notes* to just after note at *s,
+ if necessary, preceded by a new notes command;
+ then updates notes.
+ */
+ char *t;
+ if (debug > 0)
+ fprintf (stderr, "\nspacing_note: spacing=%d new_spacing=%d s=%s\n", spacing, new_spacing, s);
+ if (spacing != new_spacing)
+ {
+ if (spacing != 0) fprintf (outfile,"\\en\n");
+ output_rests (true);
+ switch (new_spacing)
+ { /* start a new notes command */
+ case 128:fprintf (outfile,"%s", NNNOTES); break;
+ case 64: fprintf (outfile,"%s", NNNOTES); break;
+ case 32: fprintf (outfile,"%s", NNOTES); break;
+ case 16: fprintf (outfile,"\\notes"); break;
+ case 8: fprintf (outfile,"\\Notes"); break;
+ case 4: fprintf (outfile,"\\NOtes"); break;
+ case 2: fprintf (outfile,"\\NOTes"); break;
+ case 1: fprintf (outfile,"\\NOTEs"); break;
+ default: error ("Spacing value not recognized");
+ }
+ spacing = new_spacing;
+ }
+ t = strchr (s+1, '\\');
+ if (t == NULL) t = s + strlen(s);
+ output_notes (t);
+ if (debug > 0)
+ fprintf (stderr, "\nAfter spacing_note: spacing=%d notes=%s\n", spacing, notes);
+ return notes;
+}
+
+PRIVATE char *semiautomatic_beam (char *s)
+{
+ char *t;
+ if ( prefix ("\\Dqbb", s)
+ || prefix ("\\Tqbb", s)
+ || prefix ("\\Qqbb", s) )
+ beaming = 16;
+ else
+ if ( prefix ("\\Dqb", s)
+ || prefix ("\\Tqb", s)
+ || prefix ("\\Qqb", s) )
+ beaming = 8;
+ if (beaming > spacing)
+ {
+ if (spacing != 0) fprintf (outfile, "\\en\n");
+ output_rests (true);
+ switch (beaming)
+ {
+ case 16: fprintf (outfile,"\\notes"); break;
+ case 8: fprintf (outfile,"\\Notes"); break;
+ default: error ("Beaming value not recognized");
+ }
+ spacing = beaming;
+ }
+ t = strchr (s+1, '\\');
+ if (t == NULL) t = s + strlen(s);
+ output_notes (t);
+ return t;
+}
+
+PRIVATE char *beam_initiation (char *s)
+{ /* sets beaming, but doesn't output anything yet */
+ char *t;
+ if ( prefix ("\\ibbbbbb", s)
+ || prefix ("\\Ibbbbbb", s)
+ || prefix ("\\nbbbbbb", s) )
+ beaming = 256;
+ else if ( prefix ("\\ibbbbb", s)
+ || prefix ("\\Ibbbbb", s)
+ || prefix ("\\nbbbbb", s) )
+ beaming = 128;
+ else if ( prefix ("\\ibbbb", s)
+ || prefix ("\\Ibbbb", s)
+ || prefix ("\\nbbbb", s) )
+ beaming = 64;
+ else if ( prefix ("\\ibbb", s)
+ || prefix ("\\Ibbb", s)
+ || prefix ("\\nbbb", s) )
+ beaming = 32;
+ else if ( prefix ("\\ibb", s)
+ || prefix ("\\Ibb", s)
+ || prefix ("\\nbb", s) )
+ beaming = 16;
+ else if ( prefix ("\\ib", s)
+ || prefix ("\\Ib", s) )
+ beaming = 8;
+ t = strchr (s+1, '\\');
+ if (t == NULL) t = s + strlen(s);
+ return t;
+}
+
+PRIVATE char *beam_note (char *s) /* \qb... */
+{ char *t;
+ if (debug > 0)
+ fprintf (stderr, "\nIn beam_note: spacing=%d beaming=%d new_beaming=%d\n",
+ spacing, beaming, new_beaming);
+ if (beaming > spacing)
+ {
+ if (spacing != 0) fprintf (outfile, "\\en\n");
+ output_rests (true);
+ switch (beaming)
+ {
+ case 256: case 128: case 64:
+ fprintf (outfile,"%s", NNNOTES); break;
+ case 32: fprintf (outfile,"%s", NNOTES); break;
+ case 16: fprintf (outfile,"\\notes"); break;
+ case 8: fprintf (outfile,"\\Notes"); break;
+ default: error ("Beaming value not recognized");
+ }
+ spacing = beaming;
+ }
+ t = strchr (s+1, '\\');
+ if (t == NULL) t = s + strlen (s);
+ output_notes (t);
+ if (new_beaming != 0) /* set by preceding \tb... */
+ {
+ beaming = new_beaming; new_beaming = 0;
+ if (*notes != '\0' && beaming != spacing)
+ {
+ if (spacing != 0) fprintf (outfile,"\\en\n");
+ switch (beaming)
+ {
+ case 256: case 128: case 64:
+ fprintf (outfile,"%s", NNNOTES); break;
+ case 32: fprintf (outfile,"%s", NNOTES); break;
+ case 16: fprintf (outfile,"\\notes"); break;
+ case 8: fprintf (outfile,"\\Notes"); break;
+ default: error ("Beaming value not recognized");
+ }
+ spacing = beaming;
+ }
+ }
+ return t;
+}
+
+PRIVATE char *beam_termination (char *s) /* \tb... */
+{ char *t;
+ if (debug > 0)
+ fprintf (stderr, "\nIn beam_termination: spacing=%d beaming=%d new_beaming=%d\n",
+ spacing, beaming, new_beaming);
+ if (spacing == 0)
+ {
+ output_rests (true);
+ switch (beaming)
+ {
+ case 256: case 128: case 64:
+ fprintf (outfile,"%s", NNNOTES); break;
+ case 32: fprintf (outfile,"%s", NNOTES); break;
+ case 16: fprintf (outfile,"\\notes"); break;
+ case 8: fprintf (outfile,"\\Notes"); break;
+ default: error ("Beaming value not recognized");
+ }
+ spacing = beaming;
+ }
+ if ( prefix ("\\tbbbbbb", s) )
+ new_beaming = 128;
+ else if ( prefix ("\\tbbbbb", s) )
+ new_beaming = 64;
+ else if ( prefix ("\\tbbbb", s) )
+ new_beaming = 32;
+ else if ( prefix ("\\tbbb", s) )
+ new_beaming = 16;
+ else if ( prefix ("\\tbb", s) )
+ new_beaming = 8;
+ else if ( prefix ("\\tb", s) )
+ { new_beaming = 0; }
+
+ t = strchr (s+1, '\\');
+ if (t == NULL) t = s + strlen(s);
+ return t;
+}
+
+PRIVATE char *beam_completion (char *s) /* \tq... */
+{ char *t;
+ if (debug > 0)
+ fprintf (stderr, "\nIn beam_completion: spacing=%d beaming=%d new_beaming=%d\n",
+ spacing, beaming, new_beaming);
+ if (beaming > spacing)
+ {
+ if (spacing != 0) fprintf (outfile, "\\en\n");
+ output_rests (true);
+ switch (beaming)
+ {
+ case 256: case 128: case 64:
+ fprintf (outfile,"%s", NNNOTES); break;
+ case 32: fprintf (outfile,"%s", NNOTES); break;
+ case 16: fprintf (outfile,"\\notes"); break;
+ case 8: fprintf (outfile,"\\Notes"); break;
+ default: error ("Beaming value not recognized");
+ }
+ spacing = beaming;
+ }
+ t = strchr (s+1, '\\');
+ if (t == NULL) t = s + strlen(s);
+ output_notes (t);
+ new_beaming = 0; spacing = 8;
+ return t;
+}
+
+PRIVATE char *nonspacing_beam_termination (char *s) /* \ztq... */
+{ char *t;
+ if (spacing == 0)
+ {
+ output_rests (true);
+ fprintf (outfile,"\\znotes");
+ spacing = beaming;
+ }
+ t = strchr (s+1, '\\');
+ if (t == NULL) t = s + strlen(s);
+ output_notes (t);
+ new_beaming = 0;
+ return t;
+}
+
+PRIVATE char *tiny (char *s)
+/* \tinynotesize */
+{
+ char *t;
+ if (spacing > 32)
+ {
+ if (spacing != 0) fprintf (outfile,"\\en\n");
+ /* for appoggiatura */
+ fprintf (outfile, NNNOTES);
+ }
+ spacing = 32;
+ t = s + strlen(s);
+ output_notes (t);
+ return t;
+}
+
+PRIVATE char *simple (char *s)
+/* detect and correct simple slurs and ties over > 1 note */
+{ char *t;
+ t = strchr (s+1, '\\');
+ if (t == NULL) t = s + strlen(s);
+ if (*(t-1) != '1')
+ {
+ char msg[LINE_LEN];
+ sprintf (msg, "simple slur or tie with n == %c changed to 1.", *(t-1));
+ warning (msg);
+ *(t-1) = '1';
+ }
+ return t;
+}
+
+PRIVATE void
+synthesize_notes (void)
+/* generate well-spaced notes */
+{ char *s;
+ s = notes;
+ while (true)
+ {
+ if (debug > 0)
+ fprintf (stderr, "\nIn synthesize s=%s\n", s);
+ if (*s == '\0')
+ {
+ if (spacing == 0)
+ { if (*notes == '\0') return; /* to avoid \znotes\en */
+ fprintf (outfile,"\\znotes");
+ }
+ output_notes (s);
+ fprintf (outfile,"\\en");
+ spacing = 0;
+ return;
+ }
+
+ if ( prefix ("\\h", s)
+ && !prefix ("\\hs", s)
+ && !prefix ("\\hqsk", s)
+ && !prefix ("\\hroff", s)
+ && !prefix ("\\hloff", s) )
+ s = spacing_note (s, 2);
+
+ else if ( prefix ("\\hs", s)
+ && !prefix ("\\hsk", s) )
+ s = spacing_note (s, 32);
+
+ else if ( prefix ("\\q", s)
+ && !prefix ("\\qb", s)
+ && !prefix ("\\qs", s)
+ && !prefix ("\\qqsk", s) )
+ s = spacing_note (s, 4);
+
+ else if ( prefix ("\\qs", s)
+ && !prefix ("\\qsk", s) )
+ s = spacing_note (s, 16);
+
+ else if ( prefix("\\qb", s) )
+ s = beam_note (s);
+
+ else if ( prefix ("\\ccccc", s) )
+ s = spacing_note (s, 128);
+
+ else if ( prefix ("\\cccc", s) )
+ s = spacing_note (s, 64);
+
+ else if ( prefix ("\\ccc", s) )
+ s = spacing_note (s, 32);
+
+ else if ( prefix ("\\cc", s)
+ && !prefix ("\\ccharnote", s) )
+ s = spacing_note (s, 16);
+
+ else if ( prefix ("\\c", s)
+ && !prefix ("\\cna", s)
+ && !prefix ("\\csh", s)
+ && !prefix ("\\cfl", s)
+ && !prefix ("\\curve", s)
+ && !prefix ("\\ccharnote", s) )
+ s = spacing_note (s, 8);
+
+ else if ( prefix ("\\ds", s )
+ && !prefix ("\\dsh", s) )
+ s = spacing_note (s, 8);
+
+ else if ( prefix ("\\wh", s)
+ || prefix ("\\pa", s)
+ || prefix ("\\breve", s) )
+ s = spacing_note (s, 1);
+
+ else if ( prefix ("\\Hpause", s) )
+ s = spacing_note (s, 2);
+
+ else if ( prefix("\\ib",s)
+ || prefix("\\Ib",s)
+ || prefix("\\nb",s) )
+ s = beam_initiation (s);
+
+ else if ( prefix("\\Dq",s)
+ || prefix("\\Tq",s)
+ || prefix("\\Qq",s) )
+ s = semiautomatic_beam (s);
+
+ else if ( prefix("\\tb", s) )
+ s = beam_termination (s);
+
+ else if ( prefix("\\tq", s) )
+ s = beam_completion (s);
+
+ else if ( prefix("\\ztq", s) )
+ s = nonspacing_beam_termination (s);
+
+ else if ( prefix("\\tinynotesize", s))
+ s = tiny (s);
+
+ else if ( prefix("\\slur", s)
+ || prefix("\\tie", s)
+ || prefix("\\sslur", s)
+ || prefix("\\bslur", s) )
+ s = simple (s);
+
+ else if ( prefix("\\zchar", s)
+ || prefix("\\lchar", s)
+ || prefix("\\cchar", s) )
+ { char *t; /* need to skip two arguments */
+ s = strchr (s+1, '}'); /* first } */
+ s = strchr (s+1, '}'); /* second } */
+ t = strchr(s+1,'\\');
+ if (t == NULL) t = s + strlen(s);
+ s = t;
+ }
+
+ else /* non-spacing; skip to next command */
+ { char *t;
+ t = strchr(s+1,'\\');
+ if (t == NULL) t = s + strlen(s);
+ s = t;
+ }
+ }
+}
+
+PRIVATE void
+process_command (char **ln)
+{ char *s, *t;
+
+ if ( prefix("\\def\\vnotes#1\\elemskip", *ln) )
+ { /* determine staff */
+ s = strstr (*ln, "@vnotes") + 7;
+ t = strchr(s, '#'); /* may have commands before # */
+ if (sscanf (t, "#%d", &staff) != 1) error("sscanf for staff fails");
+ staff--;
+ fprintf (outfile,"\\def\\vnotes#1\\elemskip#2\\en{\\noteskip#1\\@l@mskip\\@vnotes");
+ while (s != t)
+ { putc(*s, outfile); s++; }
+ fprintf (outfile,"#2\\enotes}");
+ *ln = strchr (*ln, '}') ;
+ (*ln)++;
+ }
+
+ else if ( prefix("\\TransformNotes", *ln) )
+ { /* determine staff */
+ s = strchr (*ln, '}');
+ if (s == NULL) error ("Can't parse \\TransformNotes.");
+ s = strchr (s+1, '{');
+ if (s == NULL) error ("Can't parse \\TransformNotes.");
+ s++;
+ t = strchr(s, '#'); /* may have \transpose... before # */
+ if (sscanf (t, "#%d", &staff) != 1) error("sscanf for staff fails");
+ staff--;
+ fprintf (outfile,"\\TransformNotes{#2}{");
+ while (s != t)
+ { putc(*s, outfile); s++; }
+ fprintf (outfile,"#2}");
+ *ln = strchr (t, '}') ;
+ if (*ln == NULL) error ("Can't find '}' after \\TransformNotes.\n");
+ (*ln)++;
+ }
+
+ else if ( prefix("\\nnotes", *ln) || /* non-standard */
+ prefix("\\notes", *ln) ||
+ prefix("\\Notes", *ln) ||
+ prefix("\\NOtes", *ln) ||
+ prefix("\\NOTes", *ln) ||
+ prefix("\\NOTEs", *ln) ||
+ prefix("\\NOTES", *ln) )
+ { /* spaced notes */
+ char *save_notes;
+ notes = analyze_notes (ln);
+ save_notes = notes;
+ synthesize_notes ();
+ t = strpbrk (*ln, "%\\\n");
+ *ln = t;
+ if (notes == save_notes)
+ (*ln)++; /* avoids blank line if no notes */
+ }
+
+ else if ( prefix("\\vnotes", *ln) )
+ {
+ char *s; char *t;
+ s = *ln+7;
+ t = strchr ( s, '\\');
+ *ln = t; /* skip to \elemskip */
+ notes = analyze_notes (ln);
+ if ( strstr (notes, "\\tinynotesize") != NULL )
+ { /* appoggiatura note */
+ output_rests (true);
+ fprintf (outfile,"\\vnotes");
+ while (s!=t)
+ { putc(*s, outfile); s++; }
+ fprintf (outfile,"\\elemskip%s\\en", notes);
+ t = strpbrk (*ln, "%\\\n");
+ if (t == NULL) t = *ln + strlen (*ln);
+ *ln = t;
+ }
+ else
+ { char *save_notes;
+ save_notes = notes;
+ synthesize_notes ();
+ t = strpbrk (*ln, "%\\\n");
+ *ln = t;
+ if (notes == save_notes)
+ (*ln)++; /* avoids blank line if no notes */
+ }
+ }
+
+ else if ( prefix("\\znotes", *ln) )
+ { /* non-spacing material */
+ notes = analyze_notes (ln);
+ fprintf (outfile,"\\znotes%s\\en", notes);
+ t = strpbrk (*ln, "%\\\n");
+ if (t == NULL) t = *ln + strlen (*ln);
+ *ln = t;
+ }
+
+ else if ( prefix("\\def\\atnextbar{\\znotes", *ln))
+ { /* whole-bar or multi-bar rest? */
+ *ln = *ln + 15;
+ notes = analyze_notes(ln);
+ if (strstr (notes, "\\centerpause") != NULL )
+ { restbars++; /* defer output until after a */
+ /* possible multi-bar rest */
+ }
+ else
+ {
+ if (*notes != '\0')
+ { fprintf (outfile,"\\def\\atnextbar{\\znotes%s\\en}", notes);}
+ }
+ t = strchr (*ln, '}');
+ if (t == NULL) error ("Can't find }.");
+ *ln = t+1;
+ t = strchr (*ln, '\\');
+ if (t == NULL ) t = *ln + strlen(*ln);
+ *ln = t;
+ }
+
+ else if ( (prefix("\\bar", *ln) && !prefix("\\barno", *ln) )
+ || prefix("\\doublebar", *ln)
+ || prefix("\\ala", *ln) )
+ {
+ if ( restbars > 0 )
+ { /* defer output till next \Notes bar */
+ t = strpbrk (*ln+1, "%\\");
+ if (t == NULL) t = *ln + strlen (*ln);
+ }
+ else
+ {
+ if ( prefix("\\doublebar", *ln) )
+ fprintf (outfile, "\\doublebar");
+ else
+ fprintf (outfile, "\\bar");
+ t = strpbrk (*ln+1, "%\\\n");
+ if (t == NULL) t = *ln + strlen (*ln);
+ }
+ *ln = t;
+ }
+
+ else if ( prefix("\\Endpiece", *ln)
+ || prefix("\\endpiece", *ln) )
+ {
+ output_rests (false);
+ fprintf (outfile,"%s", *ln);
+ *ln = *ln + strlen (*ln);
+ }
+
+ else if ( prefix("\\instrumentnumber", *ln) )
+ { fprintf (outfile, "\\instrumentnumber1\n");
+ t = strpbrk (*ln+1, "%\\");
+ if (t == NULL)
+ { *ln = *ln + strlen (*ln); fprintf (outfile, "\n"); return; }
+ *ln = t;
+ }
+
+ else if ( prefix("\\startpiece", *ln) )
+ { fprintf (outfile, "%s", "\\setstaffs11\n\\nostartrule\n\\startpiece");
+ t = strpbrk (*ln+1, "%\\\n");
+ if (t == NULL) t = *ln + strlen (*ln);
+ *ln = t;
+ }
+
+ else if ( prefix("\\mulooseness", *ln)
+ || prefix("\\eject", *ln)
+ || prefix("\\linegoal", *ln)
+ || prefix("\\song", *ln)
+ || prefix("\\group", *ln)
+ || prefix("\\akkoladen", *ln) )
+ { fputc ('%', outfile);
+ t = strpbrk (*ln+1, "%\\\n");
+ if (t == NULL)
+ { fprintf (outfile, "%s", *ln); return; }
+ while (*ln < t) { fputc (**ln, outfile); (*ln)++; }
+ fputc ('\n', outfile);
+ }
+
+ else if ( prefix("\\def", *ln) )
+ { char msg[LINE_LEN];
+ sprintf (msg, "Macro definition ignored: %s", *ln);
+ fprintf (stderr, "Warning: %s", msg);
+ t = *ln + strlen(*ln);
+ while (*ln < t)
+ { fputc (**ln, outfile);
+ (*ln)++;
+ }
+ }
+
+ else /* everything else */
+ { t = strpbrk (*ln+1, "%\\");
+ if (t == NULL || *t == '%') t = *ln + strlen (*ln);
+ while (*ln < t)
+ { fputc (**ln, outfile);
+ (*ln)++;
+ }
+ }
+}
+
+PRIVATE void
+process_line (void)
+{
+ char *ln;
+ ln = &line[0];
+ while ( *ln != '\0')
+ {
+ while (*ln == ' ') { ln++; fputc (' ', outfile); }
+ if (*ln == '%') {
+ fprintf (outfile, "%s", ln);
+ return;
+ }
+ process_command (&ln);
+ } /* *ln == '\0' */
+}
+
+PRIVATE void
+process_score (void)
+/* process .tex file */
+{
+ int c;
+ while ( (c = getc (infile)) != EOF )
+ {
+ ungetc (c, infile);
+ if ( fgets(line, LINE_LEN, infile) == NULL) error("IO error");
+ if (strlen (line) == LINE_LEN-1) error("Line too long.");
+ process_line ();
+ } /* c == EOF */
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ int c;
+ char today[12];
+ time_t mytime;
+# define NOPTS 4
+ struct option longopts[NOPTS] =
+ { { "help", 0, NULL, 'h'},
+ { "version", 0, NULL, 'v'},
+ { "debug", 0, NULL, 'd'},
+ { NULL, 0, NULL, 0}
+ };
+
+ time (&mytime);
+ strftime (today, 11, "%Y-%m-%d", localtime (&mytime) );
+ c = getopt_long (argc, argv, "hvd", longopts, NULL);
+ while (c != -1)
+ {
+ switch (c)
+ {
+ case 'h':
+ fprintf (stdout, "This is fixmsxpart, version %s.\n", version);
+ usage (stdout);
+ fprintf (stdout, "Please report bugs to rdt@cs.queensu.ca.\n" );
+ exit (0);
+ case 'v':
+ fprintf (stdout, "This is fixmsxpart, version %s.\n", version);
+ exit (0);
+ case 'd':
+ debug++; break;
+ case '?':
+ exit (EXIT_FAILURE);
+ default:
+ fprintf (stderr,"Function getopt returned character code 0%o.\n",
+ (unsigned int) c);
+ exit (EXIT_FAILURE);
+ }
+ c = getopt_long (argc, argv, "hvd", longopts, NULL);
+ }
+ fprintf (stderr, "This is fixmsxpart, version %s.\n", version);
+ fprintf (stderr, "Copyright (C) 2014-15 R. D. Tennent\n" );
+ fprintf (stderr, "School of Computing, Queen's University, rdt@cs.queensu.ca\n" );
+ fprintf (stderr, "License GNU GPL version 2 or later <http://gnu.org/licences/gpl.html>.\n" );
+ fprintf (stderr, "There is NO WARRANTY, to the extent permitted by law.\n\n" );
+
+ infilename[0] = '\0';
+ infilename_n = infilename;
+ if ( (optind < argc) && (optind+2 >= argc))
+ {
+ append (infilename, &infilename_n, argv[optind], sizeof (infilename));
+ if (!suffix (".tex", infilename))
+ append (infilename, &infilename_n, ".tex", sizeof (infilename));
+ }
+ else
+ { usage (stderr);
+ exit (EXIT_FAILURE);
+ }
+ optind++;
+ outfilename[0] = '\0';
+ outfilename_n = outfilename;
+ if (optind < argc) /* user-provided outfilename */
+ {
+ append (outfilename, &outfilename_n, argv[optind], sizeof (outfilename));
+ if (!suffix (".tex", outfilename))
+ append (outfilename, &outfilename_n, ".tex", sizeof (outfilename));
+ }
+ infile = fopen (infilename, "r");
+ if (infile == NULL)
+ {
+ fprintf (stderr,"Can't open %s\n", infilename);
+ exit (EXIT_FAILURE);
+ }
+ fprintf (stderr, "Reading from %s.", infilename);
+ if (*outfilename == '\0')
+ {
+ outfile = stdout;
+ fprintf (stderr, " Writing to stdout.\n");
+ }
+ else
+ {
+ outfile = fopen (outfilename, "w");
+ if (outfile == NULL)
+ {
+ fprintf (stderr,"Can't open %s\n", outfilename);
+ exit (EXIT_FAILURE);
+ }
+ fprintf (stderr, " Writing to %s.\n", outfilename);
+ }
+ fprintf (stderr,"\n");
+
+ fprintf (outfile, "%% Generated on %s by fixmsxpart (%s).\n", today, version);
+ process_score ();
+
+ return 0;
+}
diff --git a/Build/source/texk/musixtnt/musixtnt-2015-02-09/fixmsxpart.test b/Build/source/texk/musixtnt/musixtnt-2015-02-09/fixmsxpart.test
new file mode 100755
index 00000000000..0f9dc8a0936
--- /dev/null
+++ b/Build/source/texk/musixtnt/musixtnt-2015-02-09/fixmsxpart.test
@@ -0,0 +1,37 @@
+#! /bin/sh
+
+# Copyright (C) 2015 Peter Breitenlohner <tex-live@tug.org>
+# You may freely use, modify and/or distribute this file.
+
+echo && echo "*** fixmsxpart --help"
+./fixmsxpart --help || exit 1
+
+echo && echo "*** fixmsxpart --version"
+./fixmsxpart --version || exit 1
+
+echo && echo "*** fixmsxpart -dd (missing infile)"
+./fixmsxpart -dd && exit 1
+
+echo && echo "*** fixmsxpart too many args"
+./fixmsxpart too many args && exit 1
+
+: ${testsrc:=$srcdir/tests}
+
+echo && echo "*** generate fixtest.exp with version and date"
+yyyymmdd=`date +%F`
+version=`./fixmsxpart -v | sed 's/^This .* version \(.*\).$/\1/'`
+{ echo "% Generated on $yyyymmdd by fixmsxpart ($version)."
+ cat $testsrc/fixtest.out; } >fixtest.exp
+
+echo && echo "*** fixmsxpart tests/fixtest fixtest"
+./fixmsxpart $testsrc/fixtest fixtest || exit 1
+
+echo && echo "*** diff fixtest.exp fixtest.tex"
+diff fixtest.exp fixtest.tex || exit 1
+
+echo && echo "*** fixmsxpart tests/fixtest >fixtest.out"
+./fixmsxpart $testsrc/fixtest >fixtest.out || exit 1
+
+echo && echo "*** diff fixtest.exp fixtest.out"
+diff fixtest.exp fixtest.out || exit 1
+
diff --git a/Build/source/texk/musixtnt/musixtnt-2015-02-09/msxlint.1 b/Build/source/texk/musixtnt/musixtnt-2015-02-09/msxlint.1
new file mode 100644
index 00000000000..d0a3f695ae7
--- /dev/null
+++ b/Build/source/texk/musixtnt/musixtnt-2015-02-09/msxlint.1
@@ -0,0 +1,36 @@
+.\" This manpage is licensed under the GNU Public License
+.TH MSXLINT 1 2015-02-05 "" ""
+
+.SH NAME
+msxlint \- detects incorrectly formatted notes lines in a MusiXTeX source file.
+
+.SH SYNOPSIS
+.B msxlint
+.RB [ \-v\ |\ \-\-version\ |\ \-h\ |\ \-\-help ]
+
+.B msxlint
+.RB [ \-d\ | \ \-\-debug ]...
+.RI [ infile [ \fB.tex\fP ]...]
+
+If no
+.IR infiles
+are specifed, standard input is used.
+
+.SH USAGE
+
+The format that notes commands are expected to match is
+determined by \\instrumentnumber and \\setstaffs commands, or
+uses of the \\TransformNotes macro defined in musixtnt.tex (see musixdoc.pdf), or re-definitions of the \\vnotes macro.
+Output consists of messages about format errors,
+with listings of the ill-formatted lines.
+
+.SH LIMITATIONS
+User-defined macros are not processed or expanded. Notes commands (\\notes, \\Notes, etc.)
+can have line breaks, but other commands must fit on one line.
+.SH SEE ALSO
+.BR fixmsxpart (1)
+.PP
+musixdoc.pdf
+
+.SH AUTHOR
+This program and manual page were written by Bob Tennent <rdt@cs.queensu.ca>.
diff --git a/Build/source/texk/musixtnt/musixtnt-2015-02-09/msxlint.c b/Build/source/texk/musixtnt/musixtnt-2015-02-09/msxlint.c
new file mode 100644
index 00000000000..47a8bede0c4
--- /dev/null
+++ b/Build/source/texk/musixtnt/musixtnt-2015-02-09/msxlint.c
@@ -0,0 +1,422 @@
+char version[12] = "2015-02-09";
+
+/* Copyright (C) 2014-15 R. D. Tennent School of Computing,
+ * Queen's University, rdt@cs.queensu.ca
+ *
+ * This program is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * 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. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General
+ * Public License along with this program; if not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/* msxlint - detects incorrectly formatted notes lines
+ * in a MusiXTeX source file.
+ *
+ * Usage: msxlint [-v | --version | -h | --help]
+ * msxlint [-d | --debug] { infile[.tex] } ...
+ *
+ */
+
+
+# include "utils.h"
+
+PRIVATE int debug = 0;
+PRIVATE char infilename[LINE_LEN];
+PRIVATE char *infilename_n = infilename;
+
+PRIVATE FILE *infile;
+
+PRIVATE char line[LINE_LEN]; /* line of input */
+PRIVATE int lineno; /* line number */
+PRIVATE int ninstr; /* number of instruments */
+PRIVATE int staffs[12]; /* staffs[i] is the number of staffs
+ for instrument i */
+PRIVATE char terminator[8]; /* "\en" or "\enotes" or "" (either) */
+PRIVATE int nerrors; /* number of error messages */
+# define NERRORSMAX 10
+
+PRIVATE void
+checkc (char *s, char c)
+{ if (*s != c)
+ printf ("Expected %c but found %c in line %d:\n%s\n", c, *s, lineno, line);
+}
+
+PRIVATE void
+checkn (char *s)
+{ if (strpbrk (s, "0123456789") != s)
+ printf ("Expected digit but found %c in line %d:\n%s\n", *s, lineno, line);
+}
+
+PRIVATE void
+usage (void)
+{
+ puts ("Usage: msxlint [-v | --version | -h | --help]");
+ puts (" msxlint [-d | --debug] ... { infile[.tex] } ...");
+}
+
+PRIVATE void
+analyze_notes ( char **ln) {
+ int i,j;
+ int newlines = 0;
+ char *s; char *t;
+ s = strpbrk (*ln+1, "|&\\\n"); /* skip initial command */
+ while (true)
+ { /* look for \en */
+ t = strstr(s, "\\en");
+ if (t != NULL) break;
+ else
+ /* replace EOL by a blank and append another line of input */
+ { char new_line[LINE_LEN];
+ if (debug > 2) printf (" Reading additional line of input:\n");
+ if ( fgets (new_line, LINE_LEN, infile) == NULL)
+ error("Unexpected EOF.");
+ if ( (t = strchr (s, '\n')) == NULL )
+ error("Missing EOL.");
+ *t = ' ';
+ t++;
+ *t = '\0';
+ if (append (line, &t, new_line, LINE_LEN) >= LINE_LEN)
+ error ("Line too Long.");
+ if (debug > 2) printf (" %s\n", t+1);
+ newlines++;
+ }
+ }
+ for (i=1; i <= ninstr; i++)
+ {
+ for (j=1; j < staffs[i]; j++)
+ { s = strpbrk (s, "|&");
+ if (s == NULL || *s == '&' || s > t)
+ {
+ printf ("Too few staffs for instrument %d in notes on line %d:\n%s", i, lineno, line);
+ nerrors++;
+ *ln = t+3;
+ return;
+ }
+ checkc (s, '|'); s++;
+ }
+ if (i == ninstr) break;
+ s = strpbrk (s, "&|");
+ if (s == NULL || s > t)
+ {
+ printf ("Too few instruments in notes on line %d:\n%s", lineno, line);
+ nerrors++;
+ *ln = t+3;
+ return;
+ }
+ if (*s == '|')
+ {
+ printf ("Too many staffs for instrument %d in notes on line %d:\n%s", i, lineno, line);
+ nerrors++;
+ *ln = t+3;
+ return;
+ }
+ checkc (s, '&'); s++;
+ }
+ s = strpbrk (s, "|&");
+ if (s != NULL && s < t)
+ {
+ printf ("Too many fields in notes on line %d:\n%s", lineno, line);
+ nerrors++;
+ *ln = t+3;
+ return;
+ }
+ s = t; /* \en */
+ if (terminator[0] != '\0')
+ { if (!prefix (terminator, s) )
+ {
+ printf ("Expected %s at end of notes on line %d:\n%s", terminator, lineno, line);
+ nerrors++;
+ t = strchr(s, '\\');
+ if (t == NULL) t = *ln + strlen (*ln);
+ *ln = t;
+ return;
+ }
+ if ( terminator[3] == '\0' && prefix ("otes", s+3) )
+ {
+ printf ("Expected %s at end of notes on line %d:\n%s", terminator, lineno, line);
+ nerrors++;
+ t = strchr(s, '\\');
+ if (t == NULL) t = *ln + strlen (*ln);
+ *ln = t;
+ return;
+ }
+ }
+ lineno = lineno + newlines;
+ t = strchr(s+1, '\\');
+ if (t == NULL) t = *ln + strlen (*ln);
+ *ln = t;
+ return;
+}
+
+PRIVATE void
+process_command (char **ln)
+{ char *s, *t;
+ if ( prefix("\\instrumentnumber", *ln) )
+ {
+ if (debug > 1) printf ("%s\n", " Processing \\instrumentnumber");
+ s = strpbrk (*ln, "123456789");
+ if ( s == NULL ) error ("\\instrumentnumber command unreadable.");
+ ninstr = atoi (s);
+ t = strpbrk (*ln+1, "\\");
+ if (t == NULL)
+ { *ln = *ln + strlen (*ln); return; }
+ *ln = t;
+ }
+
+ if ( prefix("\\def\\nbinstrument", *ln) )
+ {
+ if (debug > 1) printf ("%s\n", " Processing \\def\\nbinstrument");
+ s = strpbrk (*ln, "123456789");
+ if ( s == NULL ) error ("\\def\\nbinstrument command unreadable.");
+ ninstr = atoi (s);
+ t = strpbrk (*ln+1, "\\");
+ if (t == NULL)
+ { *ln = *ln + strlen (*ln); return; }
+ *ln = t;
+ }
+
+ else if ( prefix("\\setstaffs", *ln) )
+ {
+ int n, p;
+ if (debug > 1) printf ("%s\n", " Processing \\setstaffs");
+ s = strpbrk (*ln, "123456789");
+ if ( s == NULL ) error ("\\setstaffs command unreadable.");
+ n = (int)(*s) - (int)('0'); /* instrument number */
+ s = strpbrk (s+1, "123456789");
+ if ( s == NULL ) error ("\\setstaffs command unreadable.");
+ p = (int)(*s) - (int)('0'); /* number of staffs */
+ staffs[n] = p;
+ t = strpbrk (*ln+1, "\\");
+ if (t == NULL)
+ { *ln = *ln + strlen (*ln); return; }
+ *ln = t;
+ }
+
+ else if ( prefix("\\def\\vnotes#1\\elemskip", *ln) )
+ {
+ if (debug > 1) printf ("%s\n", " Processing \\def\\vnotes");
+ s = *ln + 22; /* first parameter */
+ ninstr = 0;
+ while (true)
+ { ninstr++;
+ staffs[ninstr] = 1;
+ checkc (s, '#'); s++;
+ checkn (s); s++;
+ while (*s == '|')
+ { staffs[ninstr]++;
+ checkc (s, '|'); s++;
+ checkc (s, '#'); s++;
+ checkn (s); s++;
+ }
+ if (*s != '&') break;
+ checkc (s, '&'); s++;
+ }
+ t = &terminator[0];
+ while (*s != '{')
+ { *t = *s; s++; t++; }
+ *t = '\0';
+ *ln = strchr (*ln, '}') ;
+ (*ln)++;
+ }
+
+ else if ( prefix("\\TransformNotes", *ln) )
+ {
+ if (debug > 1) printf ("%s\n", " Processing \\TransformNotes");
+ s = *ln + 16; /* first parameter */
+ ninstr = 0;
+ while (true)
+ { ninstr++;
+ staffs[ninstr] = 1;
+ checkc (s, '#'); s++;
+ checkn (s); s++;
+ while (*s == '|')
+ { staffs[ninstr]++;
+ checkc (s, '|'); s++;
+ checkc (s, '#'); s++;
+ checkn (s); s++;
+ }
+ if (*s != '&') break;
+ checkc (s, '&'); s++;
+ }
+ t = &terminator[0];
+ terminator[0] = '\0';
+ append ( t, &t, "\\en", sizeof (terminator) );
+ do s++; while (*s != '{');
+ *ln = strchr (s, '}') ;
+ if (*ln == NULL) error ("Can't find '}' after \\TransformNotes.");
+ (*ln)++;
+ }
+
+ else if ( prefix("\\notes", *ln) ||
+ prefix("\\Notes", *ln) ||
+ prefix("\\NOtes", *ln) ||
+ prefix("\\NOTes", *ln) ||
+ prefix("\\NOTEs", *ln) ||
+ prefix("\\nnotes", *ln) ||
+ prefix("\\vnotes", *ln) ||
+ prefix("\\znotes", *ln)
+ )
+ {
+ if (debug > 1) printf ("%s\n", " Processing notes");
+ analyze_notes (ln);
+ t = strpbrk (*ln, "\\\n");
+ if (t == NULL)
+ { *ln = *ln + strlen (*ln); return; }
+ *ln = t;
+ }
+
+ else if ( prefix("\\def\\atnextbar", *ln))
+ {
+ if (debug > 1) printf ("%s\n", " Processing \\def\\atnextbar");
+ s = strstr (*ln, "\\znotes");
+ if (s != NULL)
+ {
+ *ln = s;
+ analyze_notes (ln);
+ }
+ t = strpbrk (*ln, "\\");
+ if (t == NULL)
+ { *ln = *ln + strlen (*ln); return; }
+ *ln = t;
+ }
+
+ else if ( prefix("\\def", *ln) )
+ *ln = *ln + strlen (*ln);
+
+ else /* anything else */
+ {
+ if (debug > 1) printf (" Processing ");
+ t = strpbrk (*ln+1, "\\\n");
+ if (t == NULL) t = *ln + strlen (*ln);
+ if (debug > 1)
+ { char *s = *ln; do {putchar (*s); s++;} while (s != t); puts ("");}
+ *ln = t;
+ }
+}
+
+PRIVATE void
+process_line (void)
+{
+ char *ln;
+ ln = &line[0];
+ while ( *ln != '\0')
+ {
+ while (*ln == ' ') { ln++;}
+ if (*ln == '%' || *ln == '\n') return;
+ process_command (&ln);
+ } /* *ln == '\0' */
+}
+
+PRIVATE void
+process_score (void)
+/* process .tex file */
+{
+ int c; int i;
+ lineno = 0;
+ ninstr = 1;
+ nerrors = 0;
+ staffs[0] = 0;
+ for (i = 1; i<12; i++) staffs[i] = 1;
+ terminator[0] = '\0'; /* either \en or \enotes */
+ while ( (c = getc (infile)) != EOF )
+ {
+ ungetc (c, infile);
+ if (fgets(line, LINE_LEN, infile) == NULL) error("IO error");
+ if (strlen (line) == LINE_LEN-1) error("Line too long.");
+ lineno++;
+ if (debug > 0) printf ("Processing line %d.\n", lineno);
+ process_line ();
+ if (nerrors > NERRORSMAX) {
+ puts ("\nToo many errors; processing of this file aborted.");
+ return;
+ }
+ } /* c == EOF */
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ int c;
+ char today[12];
+ time_t mytime;
+# define NOPTS 4
+ struct option longopts[NOPTS] =
+ { { "help", 0, NULL, 'h'},
+ { "version", 0, NULL, 'v'},
+ { "debug", 0, NULL, 'd'},
+ { NULL, 0, NULL, 0}
+ };
+
+ time (&mytime);
+ strftime (today, 11, "%Y-%m-%d", localtime (&mytime) );
+ printf ("This is msxlint, version %s.\n", version);
+ c = getopt_long (argc, argv, "hvd", longopts, NULL);
+ while (c != -1)
+ {
+ switch (c)
+ {
+ case 'h':
+ usage ();
+ puts ( "Please report bugs to rdt@cs.queensu.ca." );
+ exit (0);
+ case 'v':
+ exit (0);
+ case 'd':
+ debug++;
+ break;
+ case '?':
+ exit (EXIT_FAILURE);
+ default:
+ fprintf (stderr,"Function getopt returned character code 0%o.\n",
+ (unsigned int) c);
+ exit (EXIT_FAILURE);
+ }
+ c = getopt_long (argc, argv, "hvd", longopts, NULL);
+ }
+ puts ( "Copyright (C) 2014-15 R. D. Tennent" );
+ puts ( "School of Computing, Queen's University, rdt@cs.queensu.ca" );
+ puts ( "License GNU GPL version 2 or later <http://gnu.org/licences/gpl.html>." );
+ puts ( "There is NO WARRANTY, to the extent permitted by law." );
+
+ if (optind == argc)
+ {
+ infile = stdin;
+ printf ("\nProcessing stdin.\n\n");
+ process_score ();
+ }
+ else
+ do
+ {
+ infilename[0] = '\0';
+ infilename_n = infilename;
+ append (infilename, &infilename_n, argv[optind], sizeof (infilename));
+ if (!suffix (".tex", infilename))
+ append (infilename, &infilename_n, ".tex", sizeof (infilename));
+ infile = fopen (infilename, "r");
+ if (infile == NULL)
+ {
+ fprintf (stderr,"Can't open %s\n", infilename);
+ optind++;
+ continue;
+ }
+ printf ("\nProcessing %s.\n\n", infilename);
+ process_score ();
+ optind++;
+ }
+ while (optind < argc);
+
+ return 0;
+}
diff --git a/Build/source/texk/musixtnt/musixtnt-2015-02-09/msxlint.test b/Build/source/texk/musixtnt/musixtnt-2015-02-09/msxlint.test
new file mode 100755
index 00000000000..efdf3620005
--- /dev/null
+++ b/Build/source/texk/musixtnt/musixtnt-2015-02-09/msxlint.test
@@ -0,0 +1,28 @@
+#! /bin/sh
+
+# Copyright (C) 2015 Peter Breitenlohner <tex-live@tug.org>
+# You may freely use, modify and/or distribute this file.
+
+echo && echo "*** msxlint --help"
+./msxlint --help || exit 1
+
+echo && echo "*** msxlint --version"
+./msxlint --version || exit 1
+
+: ${testsrc:=$srcdir/tests}
+
+echo && echo "*** msxlint -d tests/badtest"
+./msxlint -d $testsrc/badtest && exit 1
+
+echo && echo "*** msxlint tests/linttest >linttest.out1"
+./msxlint $testsrc/linttest | sed '/^This/,/^Processing/d' >linttest.out1 || exit 1
+
+echo && echo "*** diff tests/linttest.out linttest.out1"
+diff $testsrc/linttest.out linttest.out1 || exit 1
+
+echo && echo "*** cat tests/linttest.tex | msxlint >linttest.out2"
+cat $testsrc/linttest.tex | ./msxlint | sed '/^This/,/^Processing/d' >linttest.out2 || exit 1
+
+echo && echo "*** diff tests/linttest.out linttest.out2"
+diff $testsrc/linttest.out linttest.out2 || exit 1
+
diff --git a/Build/source/texk/musixtnt/musixtnt-2015-02-09/tests/badtest.tex b/Build/source/texk/musixtnt/musixtnt-2015-02-09/tests/badtest.tex
new file mode 100644
index 00000000000..ed85d76374e
--- /dev/null
+++ b/Build/source/texk/musixtnt/musixtnt-2015-02-09/tests/badtest.tex
@@ -0,0 +1,10 @@
+\input musixtex
+\instrumentnumber2
+\setclef1{\bass}
+\setstaffs12
+\startpiece\addspace\afterruleskip%
+\Notes\qa
+J|\qa
+l&\qa
+n\en
+\Notes\qa J|\qa l
diff --git a/Build/source/texk/musixtnt/musixtnt-2015-02-09/tests/fixtest.tex b/Build/source/texk/musixtnt/musixtnt-2015-02-09/tests/fixtest.tex
new file mode 100644
index 00000000000..cf6d6b010b2
--- /dev/null
+++ b/Build/source/texk/musixtnt/musixtnt-2015-02-09/tests/fixtest.tex
@@ -0,0 +1,159 @@
+\input musixtex.tex
+\input musixsty.tex
+\input musixps
+\input musixtnt
+\nohalfties
+\def\pstiehgt{0.5}
+\def\psslurhgt{0.5}
+\vsize9.75in
+\voffset-0.5in
+\hsize7.0in
+\hoffset-0.25in
+\smallmusicsize
+\bigaccid
+\advance\parindent by 10pt
+\def\raisebarno{5\internote}%
+\nobarnumbers
+\relativeaccid
+\geometricskipscale
+\instrumentnumber1
+\setclef1\bass\setbassclefsymbol1\bassoct
+\setclef4\treble\settrebleclefsymbol4\trebleoct
+\generalsignature{+1}
+\generalmeter\meterC
+\setname1{B}
+\setname2{T}
+\setname3{A}
+\setname4{S}
+\fulltitle{Quodlibet}
+\subtitle{Variation 30 of the Goldberg Variations for Clavier}
+\title{Quodlibet}
+\author{J. S. Bach (1685--1750)}
+\shortauthor{J. S. Bach}
+\othermention{Arranged for Recorders by R. D. Tennent}
+\maketitle
+\startbarno=0
+\nobarnumbers
+\startpiece\addspace\afterruleskip%
+\TransformNotes{#2&#3&#4&#5}{#2}%
+\systemnumbers%
+\Notes\ds&\cu d&\ds&\ds\en
+\bar%1
+\Notes\hl N&\ibu1g2\qb1{ghi}\tqh1j&&\hpause\en
+\Notes\hl M&\ibl1k{-2}\qb1k&&\en
+\notes&\nbbl1\qb1j\tqb1i&&\qp\en
+\Notes&\ibu1h0\qb1h&&\ds\en
+\notes&\nbbu1\qb1g\tqh1h&&\cu d\en
+\def\atnextbar{\znotes&&\centerpause&\en}%
+\bar%2
+\Notes\hl L&\ibu1i{-2}\qb1i\tqh1h&\ql n&\ibu3g2\qb3{gh}\en
+\Notes&\itied1g\qu g&\ql n&\qb3i\tqh3j\en
+\Notes\ql{.K}&\ttie1\qu g&\ql o&\ibl3k{-2}\qb3k\en
+\notes&&&\nbbl3\qb3j\tqb3i\en
+\Notes&\ibu1f0\shake{n}\qb1f&\cl o&\cu h\en
+\notes\cu J&\nbbu1\qb1e\tqh1f&\ds&\ds\en
+\bar%3
+\Notes\hu I&\qu g&\ibl2n{-1}\qb2{no}&\ql k\en
+\Notes&\ds\cl k&\qb2{n}\tqb2{=m}&\ql k\en
+\Notes\hu J&\ibu1j{-2}\qb1{ji}&\ibl2j{0}\qb2{lk}&\ql l\en
+\Notes&\qb1h\tqh1g&\qb2j\tqb2p&\ql l\en
+\bar%4
+\Notes\hl K&\itied1f\shake{n}\qu f&\ibl2o{-1}\qb2{on}&\ibl3k{-1}\qb3{kl}\en
+\notes&\ttie1\ibbu1e{-2}\qb1f\tbbu1\qb1e&\qb2o&\qb3k\en
+%\vnotes1.5\elemskip&\nbbbu1\qb1e\tbbu1\qb1f&&\en
+\Notes&\itied1d\tqh1d&\tqb2m&\tqb3j\en
+\Notes\qu G&\ttie1\qu d&\ibl2n{-2}\qb2n\tqb2m&\ibu3h{-1}\shake{p}\qb3i\tqh3h\en
+\Notes\ds&\qp&\ibl2n{-5}\qb2n&\qu g\en
+\notes\ibbl0b{-1}\qb0b\tqb0a&&\tqb2k&\en
+\bar%5
+\Notes\ibl0M0\qb0N&\ql n&\ibl2n2\qb2n&\hpause\en
+\notes\nbbl0\qb0M\tqb0N&&\qb2o&\en
+\Notes\ibl0K0\qb0L&\ql n&\qb2p&\en
+\notes\nbbl0\qb0K\tqb0L&&\tqb2q&\en
+\Notes\ql{.M}&\ql o&\ibl2r{-2}\qb2r&\qp\en
+\notes&&\nbbl2\qb2q\tqb2p&\en
+\Notes\sk\cu I&\ql o&\ibl2o6\qb2o\itieu2r\tqb2r&\ds\cl k\en
+\bar%6
+\Notes\ql{.L}&\ibl1n{-1}\qb1{no}&\ttie2\ibl2r{-2}\qb2r\tqb2q&\ibl3n{-2}\qb3{nm}\en
+\Notes&\qb1n&\ql p&\qb3l\en
+\notes\ibbl0M2\qb0M\tqb0N&\tqb1m&&\tqb3k\en
+\Notes\itieu0a\ql a&\ibl1l{-2}\qb1l&\ql{.o}&\shake{n}\ibl3i0\qb3{^j}\en
+\notes&\tqb1k&&\nbbl3\qb3i\tqb3j\en
+\notes\ttie0\ibbl0a{-2}\qb0{aN}&\cl{^j}&&\cu h\en
+\notes\qb0M\tqb0L&\ds&\ibbl2i2\qb2i\qsk\tqb2{^j}&\ds\en
+\bar%7
+\Notes\ql M&\ibu1g0\qb1{fg}&\ibl2k0\qb2{kl}&\qu h\en
+\Notes\ql K&\qb1h\tqh1f&\qb2m\tqb2k&\qu h\en
+\Notes\ql N&\ibu1g{-2}\qb1{gf}&\ibl2i4\qb2{ik}&\ql i\en
+\Notes\qu G&\qb1e\tqh1d&\qb2n\tqb2m&\ql i\en
+\bar%8
+\Notes\qu{.H}&\ibu1c4\qb1{^cd}&\ibl2l{-1}\qb2{.l}\roff{\itieu2k\tbbl2\tqb2k}\qsk&\ibu3i{-1}\qb3{hi}\en
+\notes&\qb1e&\ttie2\ibbl2j0\qb2k\hqsk\tbbl2\qb2{^j}&\qb3h\en
+\Notes\cu{^J}&\itied1h\tqh1h&\itieu2l\tqb2l&\tqh3g\en
+\notes\ql K&\ttie1\ibu1h{-2}\qb1h&\ttie2\ibbl2l{-1}\qb2{lk}&\ibu3f{-1}\qb3f\en
+\notes&\tqh1g&\qb2l\tqb2j&\tqh3e\en
+\Notes\cl K&\cu f&\cl k&\cu d\en
+\advance\barno by -1%
+\leftrightrepeat
+\Notes\ds&\cl m&\ds&\cl o\en
+\bar%9
+\Notes\ql d\sk\ql c&\ibl1k0\qb1{kmk}\tqb1{m}&\ql o\sk\ql o&\ibl3m0\qb3{mom}\tqb3o\en
+\Notes\ql b&\ibl1k0\qb1n&\ql p&\ibl3k2\qb3k\en
+\notes&\qb1k&&\nbbl3\qb3l\tqb3m\en
+\Notes\ql N&\qb1k\tqb1n&\ql p&\ibl3n{-4}\qb3n\tqb3l\en
+\bar%10
+\Notes\ibl0b{-1}\qb0{cbc}\tqb0a&\cl l\ds\qp&\ibl2o{-1}\qb2{opo}\tqb2n&\ibl3o{-2}\qb3{onm}\tqb3l\en
+\Notes\ql{.b}&\ql m&\ibl2m{-2}\qb2m&\ibl3j0\shake n\qb3{^k}\en
+\notes&&\tqb2l&\nbbl3\qb3{^j}\tqb3k\en
+\Notes\sk\cl a&\ql m&\cl{^k}\ds&\ibl3i8\qb3i\tqb3{p}\en
+\bar%11
+\Notes\ql{N}\sk\ql{N}&\ibl1l0\qb1{nln}\tqb1l&\ql p\sk\ql p&\ibl3m0\qb3{lpl}\tqb3{p}\en
+\notes\ql{.a}&\ibl1m{-1}\qb1{m*n}&\ql q&\ibbl3k2\qb3{^klm}\tqb3n\en
+\Notes&\qb1m&\ql q&\ibl3o{-2}\qb3o\en
+\notes\cl{^a}&\tqb1l&&\nbbl3\qb3n\qsk\tqb3{m}\en
+\bar%12
+\Notes\ql b&\ibl1k2\qb1{^k}&\ibl2o{-1}\qb2p&\ibl3n{-2}\qb3n\en
+\notes&\nbbl1\qb1l\tqb1m&\qb2q&\nbbl3\qb3m\tqb3l\qsk\en
+\notes\qu I&\itied1i\qu i&\qb2p&\ibbl3k0\qb3{^kl}\en
+\notes&&\tqb2o&\qb3m\tqb3k\en
+\Notes\ql{.L}&\ttie1\ibu1i0\qb1i&\ibl2n0\qb2n&\itieu3l\hl l\en
+\notes&\nbbu1\qb1h\tqh1i&\nbbl2\qb2m\tqb2n&\en
+\Notes&\ibu1g2\qb1g&\cl l&\en
+\notes\cl{=K}&\nbbu1\qb1h\tqh1i&\ds&\en
+\bar%13
+\notes\qu J&\ibl1j2\qb1j\sk\qb1k&\hpause&\ttie3\ibbl3k1\slur lku1\qb3l\qb3k\slur mlu1\qb3m\tqb3l\en
+\notes\ql c&\qb1l\sk\tqb1m&&\ibbl3m1\isluru3n\qb3n\tbbl3\tslur3m\qb3m\tqb3o\en
+\notes\ql{.b}&\ibl1n{-1}\qb1n\sk\nbbl1\qb1m\tqb1l&\ql n&\ql{.k}\en
+\Notes&\cl k&\ibl2i{-5}\qb2n&\en
+\notes\ibbu0J{-2}\qb0J\tqh0I&\ds&\tqb2g&\ibbl3j2\qb3j\tqb3k\en
+\bar%14
+\Notes\qu{.H}&\ds&\ibl2j1\qb2{.j}&\ibl3l2\qb3l\en
+\notes&\cu h&\sk\tbbl2\tqb2k&\nbbl3\qb3m\tqb3n\en
+\Notes&\ibu1e0\qb1e&\ibl2j{-2}\qb2j&\ibl3o{-2}\qb3o\en
+\notes\ibbu0I2\qb0I\tqh0J&\nbbu1\qb1d\tqh1e&\tqb2{i}&\tqb3n\en
+\notes\ql{.K}&\ibu1g1\qb1f&\ibu2h1\qb2h&\ibbl3m{-2}\shake{o}\qb3m\en
+\notes&&&\tbbl3\qb3l\en
+\Notes&\itied1g\tqh1g&\tqh2i&\tqb3k\en
+\Notes&\ttie1\ibu1g{-1}\qb1g&\ibl2j2\qb2j&\ibu3i{-6}\qb3j\en
+\notes\ibbu0J2\qb0J\tqh0K&\tqh1f&\tqb2k&\tqh3d\en
+\bar%15
+\Notes\ibu0I0\qb0G&\qu d&\ibu2i0\qb2i&\ibl3i0\qb3i\en
+\notes\qb0H&&\nbbu2\qb2h\tqh2i&\qb3j\en
+\Notes\qb0I&\qu d&\cu g&\qb3k\en
+\Notes\tqh0G&&\ds&\tqb3i\en
+\Notes\qu{.J}&\qu e&\ds&\ibu3j{-2}\qb3j\en
+\notes&&\ibbl2l{-2}\qb2l\tqb2k&\qb3i\en
+\Notes&\qu e&\ibl2j4\qb2j&\qb3h\en
+\Notes\cu{^J}&&\tqb2l&\tqh3g\en
+\bar%16
+\notes\ql K&\ibu1g{1}\qb1d&\ibbl2h1\qb2{hk}&\ibu3f2\qb3f\en
+\notes&\qb1e&\qb2j\tqb2i&\tqh3g\en
+\notes\ql K&\qb1d&\ibbl2j0\qb2j\tbbl2\qb2h&\ibu3h{-4}\qb3h\en
+\Notes&\tqh1j&\itieu2k\tqb2k&\tqh3f\en
+\Notes\ql N&\ibu1i{-2}\qb1i&\ttie2\ibl2j0\qb2k&\qu g\en
+\notes&\tqh1h&\nbbl2\qb2j\tqb2k&\en
+\Notes\cu G&\cu g&\cl i&\cu g\en
+\setrightrepeat
+\endpiece%
+\eject
+\end
diff --git a/Build/source/texk/musixtnt/musixtnt-2015-02-09/tests/linttest.tex b/Build/source/texk/musixtnt/musixtnt-2015-02-09/tests/linttest.tex
new file mode 100644
index 00000000000..588582b4e89
--- /dev/null
+++ b/Build/source/texk/musixtnt/musixtnt-2015-02-09/tests/linttest.tex
@@ -0,0 +1,10 @@
+\input musixtex
+\instrumentnumber2
+\setclef1{\bass}
+\setstaffs12
+\startpiece\addspace\afterruleskip%
+\Notes\qa J|\qa l&\qa n\en
+\Notes\qa J|\qa l\en
+\Notes\qa J&\qa n\en
+\Notes\qa J|\qa l&\qa n&\qa q\en
+\zstoppiece\end
diff --git a/Build/source/texk/musixtnt/musixtnt-2015-02-09/utils.c b/Build/source/texk/musixtnt/musixtnt-2015-02-09/utils.c
new file mode 100644
index 00000000000..808f43ac3a8
--- /dev/null
+++ b/Build/source/texk/musixtnt/musixtnt-2015-02-09/utils.c
@@ -0,0 +1,103 @@
+/* Copyright (C) 2014-15 R. D. Tennent School of Computing,
+ * Queen's University, rdt@cs.queensu.ca
+ *
+ * This program is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * 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. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General
+ * Public License along with this program; if not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/* utils.c - utilities for fixmsxpart.c and msxlint.c
+ */
+
+# include "utils.h"
+
+void
+warning (const char msg[]) /* output warning message msg to stderr */
+{
+ fprintf (stderr, "Warning: %s\n", msg);
+ return;
+}
+
+void
+error (const char msg[]) /* abort with stderr message msg */
+{
+ fprintf (stderr, "Error: %s\n", msg);
+ exit (EXIT_FAILURE);
+}
+
+bool
+prefix (const char *cs, const char *ct)
+/*
+ is string cs[] a prefix of ct[]?
+*/
+{
+ const char *pcs = cs;
+ const char *pct = ct;
+ while (*pcs != '\0')
+ {
+ if (*pcs != *pct) return false;
+ pcs++; pct++;
+ }
+ return true;
+}
+
+bool
+suffix (const char *cs, const char *ct)
+/* is string cs[] a suffix of ct[]? */
+{
+ const char *pcs = cs;
+ const char *pct = ct + strlen (ct) - strlen (cs);
+ while (*pcs != '\0')
+ {
+ if (*pct != *pcs) return false;
+ pcs++; pct++;
+ }
+ return true;
+}
+
+size_t
+append (char *dst, char **offset, const char *src, size_t n)
+/* Copies src to *offset and updates *offset accordingly (if possible).
+ * Assumes *offset is dst if offset == NULL.
+ * Execution aborts if **offset != '\0'. The src string must be null-terminated.
+ * Returns (original offset - dst) + strlen(src); if >= n, the string was truncated.
+ */
+{
+ const char *s = src;
+ char *d;
+ char *off_orig = ( offset != NULL ? *offset : dst );
+ d = off_orig;
+ if (*d != '\0')
+ {
+ char msg[LINE_LEN + 24] = {'\0'};
+ char *msg_n = msg;
+ append (msg, &msg_n, "\nNull character expected at offset specified for string ", sizeof (msg));
+ append (msg, &msg_n, src, sizeof (msg));
+ error (msg);
+ }
+ n = n - 1 - (off_orig - dst); /* number of available slots (leaving room for \0) */
+ while (n > 0 && *s != '\0')
+ {
+ *d = *s; /* copy non-null character */
+ d++; s++; n--;
+ }
+ *d = '\0'; /* null-terminate */
+ if (offset != NULL)
+ *offset = d; /* update *offset (if possible) */
+ while (*s != '\0') /* traverse rest of src */
+ s++;
+ return (off_orig - dst) + (s - src); /* length of the untruncated string */
+}
diff --git a/Build/source/texk/musixtnt/musixtnt-2015-02-09/utils.h b/Build/source/texk/musixtnt/musixtnt-2015-02-09/utils.h
new file mode 100644
index 00000000000..fc25559ee52
--- /dev/null
+++ b/Build/source/texk/musixtnt/musixtnt-2015-02-09/utils.h
@@ -0,0 +1,64 @@
+
+/*
+ utils.h -- header file for fixmsxpart.c and msxlint.c
+
+ Copyright (c) 2005-15 R. D. Tennent
+ School of Computing, Queen's University, rdt@cs.queensu.ca
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+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. See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#ifdef HAVE_CONFIG_H /* for TeXLive */
+#include <config.h>
+#endif
+
+# define PRIVATE static
+# include <stdlib.h>
+# include <string.h>
+# include <stdio.h>
+# ifdef KPATHSEA
+# include <kpathsea/getopt.h>
+# else
+# include <getopt.h>
+# endif
+# include <time.h>
+
+# define LINE_LEN 1024
+
+# ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+# else
+# ifndef HAVE__BOOL
+# define _Bool signed char
+# endif
+# define bool _Bool
+# define true 1
+# define false 0
+# endif
+
+
+extern size_t append (char *dst, char **offset, const char *src, size_t n);
+/* Copies src to *offset and updates *offset accordingly (if possible).
+ * Assumes *offset is dst if offset == NULL.
+ * The src string must be null-terminated.
+ * Execution aborts unless **offset == '\0'.
+ * Returns (original offset - dst) + strlen(src); if >= n, the string was truncated.
+ */
+
+extern bool prefix (const char *cs, const char *ct); /* is string cs[] a prefix of ct[]? */
+extern bool suffix (const char *cs, const char *ct); /* is string cs[] a suffix of ct[]? */
+
+extern void error (const char msg[]); /* abort with stderr message msg */
+extern void warning (const char msg[]); /* output warning message msg to stderr */