diff options
author | Karl Berry <karl@freefriends.org> | 2021-02-25 19:22:25 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2021-02-25 19:22:25 +0000 |
commit | ad547a6b5986815fda458221149728d9d9ab1d87 (patch) | |
tree | 16296910eb3eca724371474ea9aea3994dc69614 /Build/source/utils/autosp/autosp-src/tex2aspc.c | |
parent | 947b43de3dd21d58ccc2ffadefc4441ea1c2a813 (diff) |
restore Build,TODO from r57911
git-svn-id: svn://tug.org/texlive/trunk@57915 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/utils/autosp/autosp-src/tex2aspc.c')
-rw-r--r-- | Build/source/utils/autosp/autosp-src/tex2aspc.c | 358 |
1 files changed, 358 insertions, 0 deletions
diff --git a/Build/source/utils/autosp/autosp-src/tex2aspc.c b/Build/source/utils/autosp/autosp-src/tex2aspc.c new file mode 100644 index 00000000000..d5ba3ff6a86 --- /dev/null +++ b/Build/source/utils/autosp/autosp-src/tex2aspc.c @@ -0,0 +1,358 @@ +char version[12] = "2019-01-08"; + +/* Copyright (C) 2017-19 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. + */ + +/* tex2aspc - converts conventional MusiXTeX code to autosp-compatible format */ + +/* Usage: tex2aspc infile[.tex] [outfile[.aspc]] + * tex2aspc [-v | --version | -h | --help] + */ + + +# include "utils.h" + +#ifdef HAVE_CONFIG_H /* for TeXLive */ +#include <config.h> +#endif + +# ifdef KPATHSEA +# include <kpathsea/getopt.h> +# else +# include <getopt.h> +# endif + +# 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 + +# define PRIVATE static + +# define SHORT_LEN 256 +# define MAX_STAFFS 9 + + +PRIVATE char infilename[SHORT_LEN]; +PRIVATE char *infilename_n = infilename; +PRIVATE char outfilename[SHORT_LEN]; +PRIVATE char *outfilename_n = outfilename; +PRIVATE FILE *infile, *outfile; + +PRIVATE char line[LINE_LEN]; /* line of input */ + +PRIVATE int ninstr = 1; /* number of instruments */ +PRIVATE int staffs[MAX_STAFFS] = {0,1}; /* number of staffs for ith instrument*/ +PRIVATE int nstaffs = 1; /* number of staffs */ +PRIVATE char terminator[MAX_STAFFS]; /* one of '&' "|', '$' */ + +PRIVATE char notes[MAX_STAFFS][LINE_LEN]; + /* accumulate commands to be output */ +PRIVATE char *n_notes[MAX_STAFFS]; +PRIVATE bool outputs = false; /* are there commands to be output? */ + + + +PRIVATE void +usage () +{ + printf ("Usage: tex2aspc [-v | --version | -h | --help]\n"); + printf (" tex2aspc infile[.tex] [outfile[.aspc]]\n"); +} + + +PRIVATE +void analyze_notes (char **ln) +/* append material from *ln to \en to notes[*] and initialize terminator[*]. */ +{ + int i; char *s; char *t; + int newlines = 0; + s = *ln+1; /* skip "/" */ + while (isalpha(*s)) {s++;} /* skip rest of the initial command */ + while (true) + { /* look for \en */ + t = strstr(s, "\\en"); + if (t != NULL) break; + /* replace EOL by a blank and append another line of input */ + { char new_line[LINE_LEN]; + char *nl; + if (fgets (new_line, LINE_LEN, infile) == NULL) + error ("Unexpected EOF."); + if (strlen (new_line) == LINE_LEN-1) + error ("Line too long."); + nl = new_line; + while (*nl == ' ') nl++; /* avoid spaces */ + t = strpbrk (s, "\n%"); + if (t == NULL) error ("Missing EOL."); + if (*t == '\n') + { *t = ' '; t++;} + *t = '\0'; + if (append (line, &t, nl, LINE_LEN) >= LINE_LEN) + error ("Line too long."); + newlines++; + } + } + /* t -> "\en" */ + if ( prefix("\\enotes", t) ) *ln = t+7; + else *ln = t+3; + *t = '$'; /* replace '\' by '$' (a distinctive terminating character) */ + for (i=1; i <= nstaffs; i++) + { char *tt; + while (*s == ' ') s++; /* skip spaces */ + tt = strpbrk (s, "|&$"); + if (tt == NULL) error ("can't parse note-spacing command."); + while (s < tt) + { *n_notes[i] = *s; + n_notes[i]++; s++; + } + *n_notes[i] = '\0'; + terminator[i] = *s; + if (*s != '$') s++; + } + lineno = lineno + newlines; +} + +PRIVATE +void process_command (char **ln) +{ char *s; + if ( prefix("\\def\\nbinstrument", *ln) || + prefix("\\instrumentnumber", *ln) ) + { + s = strpbrk (*ln, "123456789"); + if ( s == NULL ) error ("instrument number command unreadable."); + ninstr = atoi (s); + while (*ln <= s) { putc (**ln, outfile); (*ln)++;} + } + + else if ( prefix("\\setstaffs", *ln) ) + { /* for now, just record in staffs[i] */ + int n, p; + 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; + while (*ln <= s) { putc (**ln, outfile); (*ln)++;} + } + + else if ( prefix("\\startpiece", *ln) || + prefix("\\startextract", *ln) ) + { int i, j; + nstaffs = 1; + for (j=2; j <= staffs[1]; j++) + nstaffs++; + for (i=2; i <= ninstr; i++) + { nstaffs++; + for (j=2; j <= staffs[i]; j++) + nstaffs++; + } + fputs (*ln, outfile); + *ln =*ln + strlen(*ln); + } + + else if ( prefix("\\nnnotes", *ln) || + prefix("\\nnotes", *ln) || + prefix("\\notes", *ln) || + prefix("\\Notes", *ln) || + prefix("\\NOtes", *ln) || + prefix("\\NOTes", *ln) || + prefix("\\NOTEs", *ln) ) + { char *s; + analyze_notes (ln); + outputs = true; + s = strchr (*ln, '\n'); + if (s == NULL) s = *ln + strlen (*ln); + *ln = s+1; + } + + else + { /* if there is output, generate it and re-initialize n_notes[*] */ + if (outputs) + { int i; + fputs ("\\anotes\n", outfile); + for (i=1; i <= nstaffs; i++) + { + fputs (" ", outfile); + fputs (notes[i], outfile); + if (terminator[i] == '$') + fputs ("\\en", outfile); + else + fputc (terminator[i], outfile); + fputc ('\n', outfile); + n_notes[i] = notes[i]; + *n_notes[i] = '\0'; + } + outputs = false; + } + fputs (*ln, outfile); + *ln =*ln + strlen(*ln); + } + +} + +PRIVATE +void process_line () +{ + char *ln; + ln = &line[0]; + while ( *ln != '\0') + { + while (*ln == ' ') { ln++; fputc (' ', outfile); } + if (*ln == '%') { + fprintf (outfile, "%s", ln); + return; + } + process_command (&ln); + } +} + + +PRIVATE +void process_score () +{ + int c; int i; + lineno = 0; + for (i=1; i < MAX_STAFFS; i++) + { + staffs[i] = 1; + n_notes[i] = notes[i]; + *n_notes[i] = '\0'; + } + c = getc (infile); + + while ( c != EOF ) + { + ungetc (c, infile); + if ( fgets(line, LINE_LEN, infile) == NULL) + error ("Unexpected EOF."); + if (strlen (line) == LINE_LEN-1) + error ("Line too long."); + lineno++; + process_line (); + c = getc (infile); + } /* c == EOF */ +} + +int main (int argc, char *argv[]) +{ + int c; + char today[12]; + time_t mytime; +# define NOPTS 3 + struct option longopts[NOPTS] = + { { "help", 0, NULL, 'h'}, + { "version", 0, NULL, 'v'}, + { NULL, 0, NULL, 0} + }; + + time (&mytime); + strftime (today, 11, "%Y-%m-%d", localtime (&mytime) ); + printf ("This is tex2aspc, version %s.\n", version); + printf ("Copyright (C) 2017 R. D. Tennent\n" ); + printf ("School of Computing, Queen's University, rdt@cs.queensu.ca\n" ); + printf ("License GNU GPL version 2 or later <http://gnu.org/licences/gpl.html>.\n" ); + printf ("There is NO WARRANTY, to the extent permitted by law.\n\n" ); + + c = getopt_long (argc, argv, "hv", longopts, NULL); + while (c != -1) + { + switch (c) + { + case 'h': + usage (); + printf ("Please report bugs to rdt@cs.queensu.ca.\n" ); + exit (0); + case 'v': + exit (0); + case '?': + exit (EXIT_FAILURE); + default: + printf ("Function getopt returned character code 0%o.\n", + (unsigned int) c); + exit (EXIT_FAILURE); + } + c = getopt_long (argc, argv, "hv", longopts, NULL); + } + + infilename[0] = '\0'; + infilename_n = infilename; + if (optind < argc) + append (infilename, &infilename_n, argv[optind], sizeof (infilename)); + else + { usage(); + exit (EXIT_FAILURE); + } + infile = fopen (infilename, "r"); + if (infile == NULL) + { + if (suffix (".tex", infilename) ) + { printf ("Can't open %s\n", infilename); + exit (EXIT_FAILURE); + } + else + { append (infilename, &infilename_n, ".tex", sizeof (infilename)); + infile = fopen (infilename, "r"); + if (infile == NULL) + { printf ("Can't open %s\n", infilename); + exit (EXIT_FAILURE); + } + } + } + printf ("Reading from %s.", infilename); + + optind++; + outfilename[0] = '\0'; + outfilename_n = outfilename; + if (optind < argc) /* user-provided outfilename */ + { + append (outfilename, &outfilename_n, argv[optind], sizeof (outfilename)); + if (!suffix (".aspc", outfilename)) + append (outfilename, &outfilename_n, ".aspc", sizeof (outfilename)); + } + else + { /* output to infile.aspc */ + append (outfilename, &outfilename_n, infilename, sizeof (outfilename)); + outfilename_n -= 4; + *outfilename_n = '\0'; + append (outfilename, &outfilename_n, ".aspc", sizeof (outfilename)); + } + + outfile = fopen (outfilename, "w"); + if (outfile == NULL) + { printf ("Can't open %s\n", outfilename); + exit (EXIT_FAILURE); + } + printf (" Writing to %s.", outfilename); + + printf ("\n\n"); + + fprintf (outfile, "%% Generated by tex2aspc (%s).\n", version); + process_score (); + + return 0; +} |