3 Copyright 2000, 2015 Akira Kakuto.
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License
16 along with this library; if not, see <http://www.gnu.org/licenses/>.
19 #include <kpathsea/kpathsea.h>
25 test_file(char c
, char * name
)
28 * c= 'z', 'f', 'd', 'r'
34 if (name
== NULL
) return 1;
35 else if (*name
== '\0') return 1;
36 else if (_access(name
, 0) != 0) return 1;
37 else if ((fp
= (FILE *)fopen(name
, "r")) == NULL
) return 1;
38 else if (_filelength(_fileno(fp
)) == 0L) {
48 if (name
== NULL
) return 0;
49 else if (*name
== '\0') return 0;
50 else if (_access(name
, 0) != 0) return 0;
54 if (is_dir(name
)) return 1;
58 if (_access(name
, 4) == 0) return 1;
61 /* never reaches here */
68 fprintf(stderr
, "Usage : mktexmf FONT.\n\n");
69 fprintf(stderr
, "Makes the Metafont source file for FONT,"
70 " if possible. For example,\n");
71 fprintf(stderr
, "`ecr12' or `cmr11'.\n");
75 * Split a .mf name into root part and point size part.
76 * Root and point size are optional (may be NULL).
80 split_mf_name(string name
, string
*base
, string
*root
, string
*ptsize
)
83 /* name = basename $1 .mf */
84 p
= strrchr (name
, '.');
86 if (stricmp (p
, ".mf") == 0) *p
= '\0';
92 /* rootname = `echo $name | sed 's/[0-9]*$//'` */
93 for (q
= p
+ strlen(p
); q
> p
&& isdigit(q
[-1]); q
--);
94 /* ptsize = `echo $name | sed 's/^$rootname//'` */
108 for (j
= 0; j
< 4; j
++)
114 main (int argc
, char **argv
)
116 string rootname
, pointsize
;
117 const_string realsize
;
119 string sauterroot
, rootfile
;
120 string destdir
= NULL
;
130 kpse_set_program_name (argv
[0], NULL
);
131 progname
= kpse_program_name
;
138 if (strncmp(argv
[1], "-v",2) == 0 || strncmp(argv
[1], "--v",3) == 0) {
139 fprintf ( stderr
, "%s, (C version 1.1 --ak 2006-2015)\n", progname
);
143 if (strncmp(argv
[1], "-h",2) == 0 || strncmp(argv
[1], "--h",3) == 0) {
144 fprintf ( stderr
, "%s, Usage: %s FontBaseName\n", progname
, progname
);
148 for (i
=0; i
< 4; i
++) {
149 arg
[i
] = (char *)malloc(SBUF
);
152 if(strlen(argv
[1]) > SBUF
- 1) {
153 fprintf(stderr
, "\nToo long a font name.\n");
157 strcpy (font
, argv
[1]);
159 split_mf_name(font
, &name
, &rootname
, &pointsize
);
162 fprintf(stderr
, "name = %s, rootname = %s, pointsize = %s\n",
163 name
, rootname
, pointsize
);
166 sauterroot
= kpse_find_file(concat3("b-", rootname
, ".mf"),
167 kpse_mf_format
, false);
169 if (sauterroot
&& *sauterroot
) {
170 rootfile
= sauterroot
;
171 rootname
= concat("b-", rootname
);
172 strcpy (arg
[0], "Dummy");
173 strcpy (arg
[1], "source");
174 strcpy (arg
[2], sauterroot
);
175 if (!(ptr
= getdestdir (3, arg
))) {
176 fprintf(stderr
, "Cannot get destination directory name.\n");
182 else if (strlen(name
) == 8
183 && FILESTRNCASEEQ(name
, "csso12", 6)
184 && (name
[6] >= '0' && name
[6] <= '5')
185 && isdigit(name
[7])) {
186 rootfile
= xstrdup("");
188 else if (FILESTRNCASEEQ(rootname
, "cs", 2)
189 || FILESTRNCASEEQ(rootname
, "lcsss", 5)
190 || FILESTRNCASEEQ(rootname
, "icscsc", 6)
191 || FILESTRNCASEEQ(rootname
, "icstt", 5)
192 || FILESTRNCASEEQ(rootname
, "ilcsss", 6)
194 rootfile
= kpse_find_file("cscode.mf",
195 kpse_mf_format
, false);
197 else if (strlen(rootname
) >= 3
198 && ((FILESTRNCASEEQ(rootname
, "wn", 2)
199 && strchr("bBcCdDfFiIrRsStTuUvV", rootname
[2]))
200 || (FILESTRNCASEEQ(rootname
, "rx", 2)
201 && strchr("bBcCdDfFiIoOrRsStTuUvVxX", rootname
[2])
202 && strlen(rootname
) >= 4
203 && strchr("bBcCfFhHiIlLmMoOsStTxX", rootname
[3]))
204 || ((rootname
[0] == 'l' || rootname
[0] == 'L')
205 && strchr("aAbBcCdDhHlL", rootname
[1])
206 && strchr("bBcCdDfFiIoOrRsStTuUvVxX", rootname
[2])))) {
208 strncpy(lhprefix
, name
, 2);
210 strcat(lhprefix
, "codes.mf");
211 rootfile
= kpse_find_file(lhprefix
, kpse_mf_format
, false);
215 rootfile
= kpse_find_file(tem
= concat(rootname
, ".mf"),
216 kpse_mf_format
, false);
220 if (test_file('z', rootfile
)) {
221 fprintf (stderr
, "%s: empty or non-existent rootfile!\n", progname
);
225 if (!test_file('f', rootfile
)) {
226 fprintf (stderr
, "%s: rootfile %s does not exist!\n", progname
, rootfile
);
232 if (rootfile
&& *rootfile
) {
233 strcpy (arg
[0], "Dummy");
234 strcpy (arg
[1], "source");
235 strcpy (arg
[2], rootfile
);
236 if (!(ptr
= getdestdir (3, arg
))) {
237 fprintf(stderr
, "Cannot get destination directory name.\n");
245 if (!test_file('d', destdir
)) {
250 ptsz_len
= strlen(pointsize
);
252 fprintf(stderr
, "%s: no pointsize.\n", progname
);
255 } else if (ptsz_len
== 2) {
256 if (pointsize
[0] == '1' && pointsize
[1] == '1')
257 realsize
= "10.95"; /* \magstephalf */
258 else if (pointsize
[0] == '1' && pointsize
[1] == '4')
259 realsize
= "14.4"; /* \magstep2 */
260 else if (pointsize
[0] == '1' && pointsize
[1] == '7')
261 realsize
= "17.28"; /* \magstep3 */
262 else if (pointsize
[0] == '2' && pointsize
[1] == '0')
263 realsize
= "20.74"; /* \magstep4 */
264 else if (pointsize
[0] == '2' && pointsize
[1] == '5')
265 realsize
= "24.88"; /* \magstep5 */
266 else if (pointsize
[0] == '3' && pointsize
[1] == '0')
267 realsize
= "29.86"; /* \magstep6 */
268 else if (pointsize
[0] == '3' && pointsize
[1] == '6')
269 realsize
= "35.83"; /* \magstep7 */
271 realsize
= pointsize
;
273 /* The new convention is to have three or four letters for the
274 font name and four digits for the pointsize. The number is
275 pointsize * 100. We effectively divide by 100 by inserting a
276 dot before the last two digits. */
277 else if (ptsz_len
== 4 || ptsz_len
== 5) {
278 /* realsize=`echo "$pointsize" | sed 's/\(..\)$/.\1/'` */
279 string tempsize
= (string
)xmalloc(ptsz_len
+ 2);
280 strcpy(tempsize
, pointsize
);
281 /* The script doesn't check for last chars being digits, but we do! */
282 if (isdigit(tempsize
[ptsz_len
-1])
283 && isdigit(tempsize
[ptsz_len
-2])) {
284 tempsize
[ptsz_len
+1] = '\0';
285 tempsize
[ptsz_len
] = tempsize
[ptsz_len
-1];
286 tempsize
[ptsz_len
-1] = tempsize
[ptsz_len
-2];
287 tempsize
[ptsz_len
-2] = '.';
291 } else realsize
= pointsize
;
293 /* mfname is the full name */
294 strcpy (mfname
, destdir
);
295 i
= (int)strlen (mfname
);
296 if (mfname
[i
-1] != '/') {
301 strcat (mfname
, name
);
302 strcat (mfname
, ".mf");
304 if (test_file('r', mfname
)) {
305 fprintf(stderr
, "%s: %s already exists.\n", progname
, mfname
);
306 fprintf(stdout
, "%s\n", mfname
);
307 if (destdir
) free (destdir
);
312 if ((f
= fopen(mfname
, "wb")) == NULL
) {
313 fprintf(stderr
, "%s: can't write into the file %s/%s.\n",
314 progname
, destdir
, name
);
315 if (destdir
) free (destdir
);
320 if (FILESTRNCASEEQ(name
, "ec", 2)
321 || FILESTRNCASEEQ(name
, "tc", 2)) {
322 fprintf(f
, "if unknown exbase: input exbase fi;\n");
323 fprintf(f
, "gensize:=%s;\ngenerate %s;\n", realsize
, rootname
);
325 else if (FILESTRNCASEEQ(name
, "dc", 2)) {
326 fprintf(f
, "if unknown dxbase: input dxbase fi;\n");
327 fprintf(f
, "gensize:=%s;\ngenerate %s;\n", realsize
, rootname
);
330 else if (FILESTRNCASEEQ(name
, "cs", 2)
331 || FILESTRNCASEEQ(name
, "lcsss", 5)
332 || FILESTRNCASEEQ(name
, "icscsc", 6)
333 || FILESTRNCASEEQ(name
, "icstt", 5)
334 || FILESTRNCASEEQ(name
, "ilcsss", 6)
336 fprintf(f
, "input cscode\nuse_driver;\n");
338 else if (strlen(name
) >= 3
339 && ((FILESTRNCASEEQ(name
, "wn", 2)
340 && strchr("bBcCdDfFiIrRsStTuUvV", name
[2]))
341 || (FILESTRNCASEEQ(name
, "rx", 2)
342 && strchr("bBcCdDfFiIoOrRsStTuUvVxX", name
[2])
344 && strchr("bBcCfFhHiIlLmMoOsStTxX", name
[3]))
345 || ((name
[0] == 'l' || name
[0] == 'L')
346 && strchr("aAbBcCdDhHlL", name
[1])
347 && strchr("bBcCdDfFiIoOrRsStTuUvVxX", name
[2])))) {
348 fprintf(f
, "input fikparm;\n");
350 else if (strlen(name
) >= 4 && strchr("gG", name
[0])
351 && strchr("lLmMoOrRsStT", name
[1])
352 && strchr("bBiIjJmMtTwWxX", name
[2])
353 && strchr("cCiIlLnNoOrRuU", name
[3])) {
354 /* A small superset of the names of the cbgreek fonts:
355 pattern `g[lmorst][bijmtwx][cilnou]*'.
356 This is only slightly more general than the exact set of patterns.
358 fprintf(f
, "gensize:=%s;\ninput %s;\n", realsize
, rootname
);
361 /* FIXME: this was in the previous versions */
362 /* fprintf(f, "if unknown %s: input %s fi;\n", base, base); */
363 fprintf(f
, "design_size := %s;\ninput %s;\n",
368 fprintf(stdout
, "%s\n", mfname
);
369 fprintf(stderr
, "%s: %s: successfully generated.\n", progname
, mfname
);
371 if (destdir
) free (destdir
);