summaryrefslogtreecommitdiff
path: root/dviware/catdvi/pse2unic.c
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /dviware/catdvi/pse2unic.c
Initial commit
Diffstat (limited to 'dviware/catdvi/pse2unic.c')
-rw-r--r--dviware/catdvi/pse2unic.c428
1 files changed, 428 insertions, 0 deletions
diff --git a/dviware/catdvi/pse2unic.c b/dviware/catdvi/pse2unic.c
new file mode 100644
index 0000000000..05d6691e8a
--- /dev/null
+++ b/dviware/catdvi/pse2unic.c
@@ -0,0 +1,428 @@
+/* catdvi - get text from DVI files
+ Copyright (C) 1999, 2000 Antti-Juhani Kaijanaho <gaia@iki.fi>
+ Copyright (C) 2001-2002 Bjoern Brill <brill@fs.math.uni-frankfurt.de>
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "util.h"
+
+#define TOK_MAXLEN 256
+#define TBL_LEN 256
+
+static int lineno = 1;
+static int lpp; /* table rows per page in the report */
+
+typedef unsigned long uint32;
+
+struct adobe2unicode_t {
+ char const * adobe;
+ uint32 unicode;
+};
+#include "adobetbl.h"
+
+/* For each encoding, we want to present a sample font with the respective
+ * encoding in the report. Therefore, we have to know:
+ * - what we have to put into the preamble to use the sample font
+ * - a LaTeX command to activate the sample font
+ * - an appropriate number of lines per page for the report (some fonts tend
+ * to be large).
+ * We have reasonable defaults for unlisted encodings.
+ */
+static struct enc_sample_t {
+ char * enc_name;
+ char * preamble_cmd;
+ char * latex_cmd;
+ int lpp;
+} enc_samples[] = {
+ {"OT1Encoding", "", "\\usefont{OT1}{cmr}{m}{n}", 32},
+ {"OT1woflEncoding", "", "\\usefont{OT1}{cmr}{m}{sc}", 32},
+ {"CorkEncoding", "", "\\usefont{T1}{cmr}{m}{n}", 32},
+ {"TeXMathItalicEncoding", "", "\\usefont{OML}{cmm}{m}{it}", 32},
+ {"TeXMathSymbolEncoding", "", "\\usefont{OMS}{cmsy}{m}{n}", 32},
+ {"TeXMathExtensionEncoding", "", "\\usefont{OMX}{cmex}{m}{n}", 16},
+ {"TeXTypewriterTextEncoding", "", "\\usefont{OT1}{cmtt}{m}{n}", 32},
+ {
+ "EurosymEncoding",
+ "\\usepackage{eurosym}",
+ "\\usefont{U}{eurosym}{m}{n}",
+ 32
+ },
+ {
+ "TextCompanionEncoding",
+ "\\usepackage{textcomp}",
+ "\\usefont{TS1}{cmr}{m}{n}",
+ 32
+ },
+ {
+ "Marvosym1998Encoding",
+ "\\usepackage{marvosym}",
+ "\\usefont{OT1}{mvs}{m}{n}",
+ 32
+ },
+ {
+ "Marvosym2000Encoding",
+ "\\usepackage{marvosym}",
+ "\\usefont{OT1}{mvs}{m}{n}",
+ 32
+ },
+ {
+ "LaTeXSymbolsEncoding",
+ "\\usepackage{latexsym}",
+ "\\usefont{U}{lasy}{m}{n}",
+ 32
+ },
+ {
+ "BlackboardEncoding",
+ "\\usepackage{bbm}",
+ "\\usefont{U}{bbm}{m}{n}",
+ 32
+ },
+ {
+ "EulerFrakturEncoding",
+ "\\usepackage{amssymb}",
+ "\\usefont{U}{euf}{m}{n}",
+ 32
+ },
+ {
+ "AMSSymbolsAEncoding",
+ "\\usepackage{amssymb}",
+ "\\usefont{U}{msa}{m}{n}",
+ 32
+ },
+ {
+ "AMSSymbolsBEncoding",
+ "\\usepackage{amssymb}",
+ "\\usefont{U}{msb}{m}{n}",
+ 32
+ },
+ {
+ "EulerExtensionEncoding",
+ "\\usepackage{amssymb}",
+ "\\usefont{U}{euex}{m}{n}",
+ 32
+ },
+ /* END OF TABLE */
+ {NULL, NULL, NULL, 32}
+};
+
+/* Make extensive mixture of fputs and fprintf slightly more readable */
+#define froputs(f, s) fputs(s, f)
+
+
+static char enc_name[TOK_MAXLEN]; /* name of the current encoding */
+
+static int my_getc(FILE * fp)
+{
+ int c;
+
+ c = getc(fp);
+
+ if (c == '\n') lineno++;
+
+ return c;
+}
+
+static void my_ungetc(int c, FILE * fp)
+{
+ if (c == '\n') lineno--;
+
+ ungetc(c, fp);
+}
+
+/* Read a token from a PS ENC file */
+static unsigned char const * get_token(FILE * fp, char const * fname)
+{
+ int c;
+ unsigned char ch;
+ static unsigned char tok[TOK_MAXLEN];
+ size_t i = 0;
+
+ /* Ignore leading whitespace & comments. */
+ do {
+ c = my_getc(fp); ch = c;
+ if (c == EOF) return (unsigned char const *) "";
+
+ /* Ignore comment. */
+ if (ch == '%') {
+ do {
+ c = my_getc(fp); ch = c;
+ if (c == EOF) return (unsigned char const *) "";
+ } while (ch != '\n');
+ }
+
+ } while (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n');
+
+ my_ungetc(c, fp);
+
+ while (1) {
+ c = my_getc(fp); ch = c;
+
+ if (ch == ' ' || ch == '\t' || ch == '\r'
+ || ch == '\n' || c == EOF) {
+ tok[i] = 0;
+ return tok;
+ }
+
+ if (i == TOK_MAXLEN) {
+ panic("token too long while reading %s\n", fname);
+ }
+
+ tok[i++] = c;
+ }
+ NOTREACHED;
+}
+
+static int a2u_cmp(void const * av, void const * bv)
+{
+ struct adobe2unicode_t const * a = av;
+ struct adobe2unicode_t const * b = bv;
+
+ return strcmp(a->adobe, b->adobe);
+}
+
+/* Warn about some easily made mistakes in adobetbl.h */
+static void check_adobetbl(void)
+{
+ struct adobe2unicode_t * p, * last;
+ int cmp;
+
+ last = adobe2unicode + lengthof(adobe2unicode) - 1;
+ for(p = adobe2unicode; p < last; ++p) {
+
+ cmp = a2u_cmp(p, p+1);
+ if(cmp == 0) {
+ warning("duplicate entry `%s' in adobetbl.h\n", p->adobe);
+ }
+ else if(cmp > 0) {
+ warning(
+ "adobetbl.h not sorted: `%s' before `%s'\n",
+ p->adobe,
+ (p+1)->adobe
+ );
+ }
+
+ }
+}
+
+
+/* Look a name up in the translation table. */
+static uint32 lookup(unsigned char const * name, char const * fname)
+{
+ struct adobe2unicode_t key;
+ struct adobe2unicode_t * datum;
+
+ key.adobe = (char const *) name;
+
+ datum = bsearch(&key, adobe2unicode,
+ sizeof(adobe2unicode) / sizeof(adobe2unicode[0]),
+ sizeof(adobe2unicode[0]),
+ a2u_cmp);
+
+ if (datum == 0) {
+ warning("%s:%i: Unknown Adobe glyph name `%s'\n",
+ fname, lineno, name);
+ return 0;
+ }
+
+ return datum->unicode;
+}
+
+/* Write the conversion report header */
+static void report_header(FILE * rp)
+{
+ time_t now;
+ struct enc_sample_t * p;
+ char * cmd;
+
+ time(&now);
+
+ /* find the LaTeX command for the right sample font */
+ for(p = enc_samples; p->enc_name != NULL; ++p) {
+ if(strcmp(p->enc_name, enc_name) == 0) break;
+ }
+ cmd = p->latex_cmd;
+ lpp = p->lpp;
+
+ froputs(rp, "% AUTOMATICALLY GENERATED - DO NOT EDIT.\n");
+ froputs(rp, "\n");
+ froputs(rp, "\\documentclass{article}\n");
+ froputs(rp, "\n");
+ froputs(rp, "\\title{\n");
+ froputs(rp, " \\texttt{catdvi}'s Mapping of the\n");
+ fprintf(rp, " `%s' Font~Encoding to Unicode\n", enc_name);
+ froputs(rp, "}\n");
+ froputs(rp, "\\author{\\texttt{pse2unic}}\n");
+ fprintf(rp, "\\date{%s}\n", ctime(&now));
+ froputs(rp, "\n");
+ if(p->preamble_cmd != NULL) fprintf(rp, "%s\n", p->preamble_cmd);
+ froputs(rp, "\n");
+ if(cmd != NULL) fprintf(
+ rp,
+ "\\newcommand{\\sample}[1]{{%s\\symbol{#1}}}\n",
+ cmd
+ );
+ else froputs(rp, "\\newcommand{\\sample}[1]{N/A}\n");
+ froputs(rp, "\n");
+ froputs(rp, "\\begin{document}\n");
+ froputs(rp, "\n");
+ froputs(rp, "\\maketitle\n");
+ froputs(rp, "\n");
+}
+
+/* Print one conversion table line in the report */
+static void report_line(
+ FILE * rp,
+ int code,
+ unsigned char const * name,
+ uint32 unicode
+)
+{
+ if(code % lpp == 0) {
+ froputs(rp, "\\begin{tabular}{r|l|l|r}\n");
+ froputs(rp, "code point & sample shape & internal name & Unicode\\\\\n");
+ froputs(rp, "\\hline\n");
+ }
+
+ fprintf(
+ rp,
+ "\\texttt{%#04x} & \\sample{%d} & \\verb/%s/ & ",
+ code,
+ code,
+ name
+ );
+ if(unicode != 0) {
+ fprintf(rp, "\\texttt{U+%04lX}\\\\\n", unicode);
+ }
+ else {
+ froputs(rp, "N/A\\\\\n");
+ }
+ froputs(rp, "\\hline\n");
+
+ if((code % lpp == lpp - 1) || (code == TBL_LEN - 1)) {
+ froputs(rp, "\\end{tabular}\n");
+ froputs(rp, "\n\\newpage\n");
+ }
+}
+
+/* Dump the conversion report footer */
+static void report_footer(FILE * rp)
+{
+ froputs(rp, "\n");
+ froputs(rp, "\\end{document}\n");
+}
+
+/* Parse a PS ENC file named fname.
+ * Return a statically allocated table of
+ * TBL_LEN uint32's indexed by input octets.
+ * As a byproduct, write a (LaTeX format) report about the PS ENC file
+ * to a file named rname.
+ */
+static uint32 * parse_enc(char const * fname, char const * rname)
+{
+ FILE * fp, * rp;
+ unsigned char const * tok;
+ static uint32 tbl[TBL_LEN];
+ int i;
+ uint32 u;
+
+ fp = fopen(fname, "r");
+ if (fp == 0) panic("unable to open %s: %s\n", fname, strerror(errno));
+ rp = fopen(rname, "w");
+ if (rp == 0) panic("Unable to open `%s' for writing: %s.\n",
+ rname, strerror(errno));
+
+ lineno = 1;
+
+ tok = get_token(fp, fname);
+ if (tok[0] != '/') panic("expected a literal, got `%s'\n", tok);
+
+ strcpy(enc_name, (char const *) (tok+1));
+
+ tok = get_token(fp, fname);
+ if (! (tok[0] == '[' && tok[1] == 0)) {
+ panic("expected `[', got `%s'\n", tok);
+ }
+ report_header(rp);
+
+ for (i = 0; i < TBL_LEN; i++) {
+ tok = get_token(fp, fname);
+
+ if (tok[0] != '/') panic("expected a literal, got `%s'\n", tok);
+
+ u = lookup(tok+1, fname);
+ tbl[i] = u ? u : 0x003f; /* QUESTION MARK */
+ report_line(rp, i, tok+1, u);
+ }
+
+ tok = get_token(fp, fname);
+ if (! (tok[0] == ']' && tok[1] == 0)) {
+ panic("expected `]', got `%s'\n", tok);
+ }
+
+ report_footer(rp);
+ if (fclose(rp) != 0) panic("Unable to write `%s': %s.\n",
+ rname, strerror(errno));
+ fclose(fp);
+ return tbl;
+}
+
+int main(int argc, char * argv[])
+{
+ FILE * fp;
+ uint32 * tbl;
+ int i;
+ char * progname = argv[0];
+
+ msglevel = 10;
+
+ if (argc == 5 && strcmp(argv[1], "-w") == 0) {
+ suppress_warnings = 1;
+ --argc;
+ ++argv;
+ }
+
+ if (argc != 4) panic("Usage error!\n");
+
+ check_adobetbl();
+
+ tbl = parse_enc(argv[1], argv[3]);
+
+
+ fp = fopen(argv[2], "w");
+ if (fp == 0) panic("Unable to open `%s' for writing: %s.\n",
+ argv[2], strerror(errno));
+ fprintf(fp, "static sint32 %s[%i] = {\n", enc_name, TBL_LEN);
+ for (i = 0; i < TBL_LEN; i++) {
+ fprintf(fp, " 0x%04lx,\n", tbl[i]);
+ }
+ fputs("};\n", fp);
+
+ if (fclose(fp) != 0) panic("Unable to write `%s': %s.\n",
+ argv[2], strerror(errno));
+
+ if (suppress_warnings && num_warnings > 0) {
+ fprintf(stderr, "%s: suppressed %i warnings\n",
+ progname, num_warnings);
+ }
+
+ return 0;
+}