1 /* $NetBSD: deroff.c,v 1.11 2013/10/18 20:47:06 christos Exp $ */
3 /* taken from: OpenBSD: deroff.c,v 1.6 2004/06/02 14:58:46 tom Exp */
6 * Copyright (c) 1988, 1993
7 * The Regents of the University of California. All rights reserved.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * Copyright (C) Caldera International Inc. 2001-2002.
35 * All rights reserved.
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
40 * 1. Redistributions of source code and documentation must retain the above
41 * copyright notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution.
45 * 3. All advertising materials mentioning features or use of this software
46 * must display the following acknowledgement:
47 * This product includes software developed or owned by Caldera
49 * 4. Neither the name of Caldera International, Inc. nor the names of other
50 * contributors may be used to endorse or promote products derived from
51 * this software without specific prior written permission.
53 * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
54 * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
55 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
56 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
57 * IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE FOR ANY DIRECT,
58 * INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
59 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
60 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
62 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
63 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
64 * POSSIBILITY OF SUCH DAMAGE.
67 #include <sys/cdefs.h>
68 __RCSID("$NetBSD: deroff.c,v 1.11 2013/10/18 20:47:06 christos Exp $");
79 * Deroff command -- strip troff, eqn, and Tbl sequences from
80 * a file. Has two flags argument, -w, to cause output one word per line
81 * rather than in the original format.
82 * -mm (or -ms) causes the corresponding macro's to be interpreted
83 * so that just sentences are output
84 * -ml also gets rid of lists.
85 * Deroff follows .so and .nx commands, removes contents of macro
86 * definitions, equations (both .EQ ... .EN and $...$),
87 * Tbl command sequences, and Troff backslash constructions.
89 * All input is through the Cget macro;
90 * the most recently read character is in c.
92 * Modified by Robert Henry to process -me and -man macros.
95 #define Cget ( (c=getc(infile)) == EOF ? eof() : ((c==ldelim)&&(filesp==files) ? skeqn() : c) )
96 #define C1get ( (c=getc(infile)) == EOF ? eof() : c)
101 #else /* not DEBUG */
104 #endif /* not DEBUG */
106 #define SKIP while (C != '\n')
107 #define SKIP_TO_COM SKIP; SKIP; pc=c; while (C != '.' || pc != '\n' || C > 'Z')pc=c
111 #define MS 0 /* -ms */
112 #define MM 1 /* -mm */
113 #define ME 2 /* -me */
114 #define MA 3 /* -man */
117 static char *mactab
[] = { "-ms", "-mm", "-me", "-ma" };
134 static int msflag
; /* processing a source written using a mac package */
135 static int mac
; /* which package */
140 static int keepblock
; /* keep blocks of text; normally false when msflag */
142 static char chars
[128]; /* SPECIAL, PUNCT, APOS, DIGIT, or LETTER */
144 static char line
[LINE_MAX
];
152 static char fname
[PATH_MAX
];
153 static FILE *files
[MAXFILES
];
154 static FILE **filesp
;
163 * Macro table definitions
165 typedef int pacmac
; /* compressed macro name */
166 static int argconcat
= 0; /* concat arguments together (-me only) */
168 #define tomac(c1, c2) ((((c1) & 0xFF) << 8) | ((c2) & 0xFF))
169 #define frommac(src, c1, c2) (((c1)=((src)>>8)&0xFF),((c2) =(src)&0xFF), __USE(c1), __USE(c2))
177 static const struct mactab troffmactab
[];
178 static const struct mactab ppmactab
[];
179 static const struct mactab msmactab
[];
180 static const struct mactab mmmactab
[];
181 static const struct mactab memactab
[];
182 static const struct mactab manmactab
[];
185 * Macro table initialization
187 #define M(cond, c1, c2, func) {cond, tomac(c1, c2), func}
190 * Flags for matching conditions other than
194 #define FNEST 1 /* no nested files */
195 #define NOMAC 2 /* no macro */
196 #define MAC 3 /* macro */
197 #define PARAG 4 /* in a paragraph */
198 #define MSF 5 /* msflag is on */
199 #define NBLK 6 /* set if no blocks to be kept */
202 * Return codes from macro minions, determine where to jump,
203 * how to repeat/reprocess text
205 #define COMX 1 /* goto comx */
206 #define COM 2 /* goto com */
208 static int skeqn(void);
209 static int eof(void);
211 static int _C1(void);
214 static int EQ(pacmac
);
215 static int domacro(pacmac
);
216 static int PS(pacmac
);
217 static int skip(pacmac
);
218 static int intbl(pacmac
);
219 static int outtbl(pacmac
);
220 static int so(pacmac
);
221 static int nx(pacmac
);
222 static int skiptocom(pacmac
);
223 static int PP(pacmac
);
224 static int AU(pacmac
);
225 static int SH(pacmac
);
226 static int UX(pacmac
);
227 static int MMHU(pacmac
);
228 static int mesnblock(pacmac
);
229 static int mssnblock(pacmac
);
230 static int nf(pacmac
);
231 static int ce(pacmac
);
232 static int meip(pacmac
);
233 static int mepp(pacmac
);
234 static int mesh(pacmac
);
235 static int mefont(pacmac
);
236 static int manfont(pacmac
);
237 static int manpp(pacmac
);
238 static int macsort(const void *, const void *);
239 static int sizetab(const struct mactab
*);
240 static void getfname(void);
241 static void textline(char *, int);
242 static void work(void) __dead
;
243 static void regline(void (*)(char *, int), int);
244 static void macro(void);
245 static void tbl(void);
246 static void stbl(void);
247 static void eqn(void);
248 static void backsl(void);
249 static void sce(void);
250 static void refer(int);
251 static void inpic(void);
252 static void msputmac(char *, int);
253 static void msputwords(int);
254 static void meputmac(char *, int);
255 static void meputwords(int);
256 static void noblock(char, char);
257 static void defcomline(pacmac
);
258 static void comline(void);
259 static void buildtab(const struct mactab
**, int *);
260 static FILE *opn(char *);
261 static struct mactab
*macfill(struct mactab
*, const struct mactab
*);
262 static void usage(void) __dead
;
265 main(int ac
, char **av
)
283 while ((ch
= getopt(ac
, av
, "ikpwm:")) != -1) {
314 if (errflg
== 0 && optarg
[1] != '\0')
337 printf("msflag = %d, mac = %s, keepblock = %d, disp = %d\n",
338 msflag
, mactab
[mac
], keepblock
, disp
);
343 infile
= opn(argv
[0]);
350 for (i
= 'a'; i
<= 'z' ; ++i
)
352 for (i
= 'A'; i
<= 'Z'; ++i
)
354 for (i
= '0'; i
<= '9'; ++i
)
371 while ((c
= getc(infile
)) != rdelim
) {
375 while ((c
= getc(infile
)) != '"') {
377 (c
== '\\' && (c
= getc(infile
)) == EOF
))
392 if ((fd
= fopen(p
, "r")) == NULL
)
393 err(1, "fopen %s", p
);
407 infile
= opn(argv
[0]);
423 static struct chain
*namechain
= NULL
;
428 for (p
= fname
; p
- fname
< (ptrdiff_t)sizeof(fname
) &&
430 c
!= ' ' && c
!= '\t' && c
!= '\\'; ++p
)
436 /* see if this name has already been used */
437 for (q
= namechain
; q
; q
= q
->nextp
)
438 if (strcmp(fname
, q
->datap
) == 0) {
443 q
= (struct chain
*) malloc(sizeof(struct chain
));
446 q
->nextp
= namechain
;
447 q
->datap
= strdup(fname
);
448 if (q
->datap
== NULL
)
455 textline(char *str
, int constant
)
472 printf("Starting work with `%c'\n", c
);
473 #endif /* FULLDEBUG */
474 if (c
== '.' || c
== '\'')
477 regline(textline
, TWO
);
482 regline(void (*pfunc
)(char *, int), int constant
)
487 while (lp
- line
< (ptrdiff_t)sizeof(line
)) {
494 if (intable
&& c
== 'T') {
496 if (c
== '{' || c
== '}') {
507 (*pfunc
)(line
, constant
);
517 } while (C
!='.' || C
!='.' || C
=='.'); /* look for .. */
543 if (c
!= 'T' || C
!= 'E') {
546 while (C
!= '.' || pc
!= '\n' || C
!= 'T' || C
!= 'E')
563 if (C1
== '.' || c
== '\'') {
564 while (C1
== ' ' || c
== '\t')
566 if (c
== 'E' && C1
== 'N') {
568 if (msflag
&& dflg
) {
578 } else if (c
== 'd') {
580 if (C1
== 'e' && C1
== 'l')
581 if (C1
== 'i' && C1
== 'm') {
585 if ((c1
= c
) == '\n' ||
587 (c1
== 'o' && c2
== 'f' && C1
=='f')) {
600 if (chars
[c
] == PUNCT
)
608 /* skip over a complete backslash construction */
624 while (C
>= '0' && c
<= '9')
655 C
; /* discard argument number */
666 if ((bdelim
= C
) == '\n')
668 while (C
!= '\n' && c
!= bdelim
)
689 for (ap
= a
; C
!= '\n'; ap
++) {
701 for (i
= 0; i
< n
;) {
715 } else if (c
== 'P' || C
== 'P') {
719 } else if (c
!= '\n')
745 if (c2
!= -1 && chars
[c2
] == PUNCT
)
764 if (C
== '.' && c1
== '\n') {
786 else if (c
== '\"') {
798 else if (c
== '\n' && p1
!= line
) {
828 * Put out a macro line, using ms and mm conventions.
831 msputmac(char *s
, int constant
)
844 while (*s
== ' ' || *s
== '\t')
846 for (t
= s
; *t
!= ' ' && *t
!= '\t' && *t
!= '\0' ; ++t
)
850 if (t
> s
+ constant
&& chars
[(unsigned char)s
[0]] == LETTER
&&
851 chars
[(unsigned char)s
[1]] == LETTER
) {
859 } else if (found
&& chars
[(unsigned char)s
[0]] == PUNCT
&&
868 if (msflag
&& chars
[last
] == PUNCT
) {
875 * put out words (for the -w option) with ms and mm conventions
878 msputwords(int macline
)
885 * skip initial specials ampersands and apostrophes
887 while (chars
[(unsigned char)*p1
] < DIGIT
)
891 for (p
= p1
; (i
= chars
[(unsigned char)*p
]) != SPECIAL
; ++p
)
895 if (nlet
> 1 && chars
[(unsigned char)p1
[0]] == LETTER
) {
897 * delete trailing ampersands and apostrophes
899 while ((i
= chars
[(unsigned char)p
[-1]]) == PUNCT
||
912 * put out a macro using the me conventions
914 #define SKIPBLANK(cp) while (*cp == ' ' || *cp == '\t') { cp++; }
915 #define SKIPNONBLANK(cp) while (*cp !=' ' && *cp !='\cp' && *cp !='\0') { cp++; }
918 meputmac(char *cp
, int constant
)
932 for (argno
= 0; *cp
; argno
++) {
934 inquote
= (*cp
== '"');
937 for (np
= cp
; *np
; np
++) {
951 if (inquote
&& np
[1] == '"') {
952 memmove(np
, np
+ 1, strlen(np
));
956 *np
= ' '; /* bye bye " */
966 * cp points at the first char in the arg
967 * np points one beyond the last char in the arg
969 if ((argconcat
== 0) || (argconcat
!= argno
))
974 printf("[%d,%d: ", argno
, np
- cp
);
975 for (p
= cp
; p
< np
; p
++) {
980 #endif /* FULLDEBUG */
982 * Determine if the argument merits being printed
984 * constant is the cut off point below which something
987 if (((np
- cp
) > constant
) &&
988 (inquote
|| (chars
[(unsigned char)cp
[0]] == LETTER
))) {
989 for (; cp
< np
; cp
++)
993 } else if (found
&& (np
- cp
== 1) &&
994 chars
[(unsigned char)*cp
] == PUNCT
) {
1001 if (msflag
&& chars
[last
] == PUNCT
)
1007 * put out words (for the -w option) with ms and mm conventions
1010 meputwords(int macline
)
1013 msputwords(macline
);
1018 * Skip over a nested set of macros
1020 * Possible arguments to noblock are:
1022 * fi end of unfilled text
1026 * for ms and mm only:
1029 * NE undocumented match to NS (for mm?)
1030 * LE mm only: matches RL or *L (for lists)
1036 noblock(char a1
, char a2
)
1051 if ((c1
= C
) == '\n')
1053 if ((c2
= C
) == '\n')
1055 if (c1
== a1
&& c2
== a2
) {
1065 } else if (a1
== 'L' && c2
== 'L') {
1070 * equations (EQ) nested within a display
1072 else if (c1
== 'E' && c2
== 'Q') {
1073 if ((mac
== ME
&& a1
== ')')
1074 || (mac
!= ME
&& a1
== 'D')) {
1080 * turning on filling is done by the paragraphing
1083 else if (a1
== 'f') { /* .fi */
1084 if ((mac
== ME
&& (c2
== 'h' || c2
== 'p'))
1085 || (mac
!= ME
&& (c1
== 'P' || c2
== 'P'))) {
1106 domacro(pacmac unused
)
1118 for (C
; c
== ' ' || c
== '\t'; C
)
1121 if (c
== '<') { /* ".PS < file" -- don't expect a .PE */
1143 intbl(pacmac unused
)
1155 outtbl(pacmac unused
)
1170 if (++filesp
- &files
[0] > MAXFILES
)
1171 err(1, "too many nested files (max %d)",
1173 infile
= *filesp
= opn(fname
);
1186 if (fname
[0] == '\0')
1188 if (infile
!= stdin
)
1190 infile
= *filesp
= opn(fname
);
1197 skiptocom(pacmac unused
)
1209 frommac(c12
, c1
, c2
);
1210 printf(".%c%c", c1
, c2
);
1233 frommac(c12
, c1
, c2
);
1236 printf(".%c%c", c1
, c2
);
1274 frommac(c12
, c1
, c2
);
1276 printf(".%c%c", c1
, c2
);
1287 mesnblock(pacmac c12
)
1291 frommac(c12
, c1
, c2
);
1297 mssnblock(pacmac c12
)
1301 frommac(c12
, c1
, c2
);
1330 else if (wordflag
) /* save the tag */
1331 regline(meputmac
, ONE
);
1338 * only called for -me .pp or .sh, when parag is on
1344 PP(c12
); /* eats the line */
1349 * Start of a section heading; output the section name if doing words
1365 * process a font setting
1392 defcomline(pacmac c12
)
1396 frommac(c12
, c1
, c2
);
1397 if (msflag
&& mac
== MM
&& c2
== 'L') {
1398 if (disp
|| c1
== 'R') {
1405 else if (c1
== '.' && c2
== '.') {
1415 * Process the arguments to the macro
1421 if (c1
<= 'Z' && msflag
)
1422 regline(msputmac
, ONE
);
1424 regline(msputmac
, TWO
);
1427 regline(meputmac
, ONE
);
1442 static int tabsize
= 0;
1443 static const struct mactab
*mactab
= NULL
;
1444 const struct mactab
*mp
;
1447 buildtab(&mactab
, &tabsize
);
1449 while (C
== ' ' || c
== '\t')
1452 if ((c1
= c
) == '\n')
1455 if (c1
== '.' && c2
!= '.')
1457 if (msflag
&& c1
== '[') {
1461 if (parag
&& mac
==MM
&& c1
== 'P' && c2
== '\n') {
1468 * Single letter macro
1470 if (mac
== ME
&& (c2
== ' ' || c2
== '\t') )
1472 c12
= tomac(c1
, c2
);
1474 * binary search through the table of macros
1479 mid
= (ub
+ lb
) / 2;
1481 if (mp
->macname
< c12
)
1483 else if (mp
->macname
> c12
)
1488 printf("preliminary hit macro %c%c ", c1
, c2
);
1489 #endif /* FULLDEBUG */
1490 switch (mp
->condition
) {
1495 hit
= (filesp
== files
);
1516 #endif /* FULLDEBUG */
1517 switch ((*(mp
->func
))(c12
)) {
1528 #endif /* FULLDEBUG */
1536 macsort(const void *p1
, const void *p2
)
1538 const struct mactab
*t1
= p1
;
1539 const struct mactab
*t2
= p2
;
1541 return t1
->macname
- t2
->macname
;
1545 sizetab(const struct mactab
*mp
)
1551 for (; mp
->macname
; mp
++, i
++)
1557 static struct mactab
*
1558 macfill(struct mactab
*dst
, const struct mactab
*src
)
1562 while (src
->macname
)
1571 extern char *__progname
;
1573 fprintf(stderr
, "usage: %s [-ikpw ] [ -m a | e | l | m | s] [file ...]\n", __progname
);
1578 buildtab(const struct mactab
**r_back
, int *r_size
)
1581 const struct mactab
*p1
, *p2
;
1582 struct mactab
*back
, *p
;
1584 size
= sizetab(troffmactab
) + sizetab(ppmactab
);
1605 size
+= sizetab(p1
);
1606 size
+= sizetab(p2
);
1607 back
= calloc(size
+ 2, sizeof(struct mactab
));
1611 p
= macfill(back
, troffmactab
);
1612 p
= macfill(p
, ppmactab
);
1616 qsort(back
, size
, sizeof(struct mactab
), macsort
);
1624 static const struct mactab troffmactab
[] = {
1625 M(NONE
, '\\','"', skip
), /* comment */
1626 M(NOMAC
, 'd','e', domacro
), /* define */
1627 M(NOMAC
, 'i','g', domacro
), /* ignore till .. */
1628 M(NOMAC
, 'a','m', domacro
), /* append macro */
1629 M(NBLK
, 'n','f', nf
), /* filled */
1630 M(NBLK
, 'c','e', ce
), /* centered */
1632 M(NONE
, 's','o', so
), /* source a file */
1633 M(NONE
, 'n','x', nx
), /* go to next file */
1635 M(NONE
, 't','m', skip
), /* print string on tty */
1636 M(NONE
, 'h','w', skip
), /* exception hyphen words */
1641 * Preprocessor output
1643 static const struct mactab ppmactab
[] = {
1644 M(FNEST
, 'E','Q', EQ
), /* equation starting */
1645 M(FNEST
, 'T','S', intbl
), /* table starting */
1646 M(FNEST
, 'T','C', intbl
), /* alternative table? */
1647 M(FNEST
, 'T','&', intbl
), /* table reformatting */
1648 M(NONE
, 'T','E', outtbl
),/* table ending */
1649 M(NONE
, 'P','S', PS
), /* picture starting */
1654 * Particular to ms and mm
1656 static const struct mactab msmactab
[] = {
1657 M(NONE
, 'T','L', skiptocom
), /* title follows */
1658 M(NONE
, 'F','S', skiptocom
), /* start footnote */
1659 M(NONE
, 'O','K', skiptocom
), /* Other kws */
1661 M(NONE
, 'N','R', skip
), /* undocumented */
1662 M(NONE
, 'N','D', skip
), /* use supplied date */
1664 M(PARAG
, 'P','P', PP
), /* begin parag */
1665 M(PARAG
, 'I','P', PP
), /* begin indent parag, tag x */
1666 M(PARAG
, 'L','P', PP
), /* left blocked parag */
1668 M(NONE
, 'A','U', AU
), /* author */
1669 M(NONE
, 'A','I', AU
), /* authors institution */
1671 M(NONE
, 'S','H', SH
), /* section heading */
1672 M(NONE
, 'S','N', SH
), /* undocumented */
1673 M(NONE
, 'U','X', UX
), /* unix */
1675 M(NBLK
, 'D','S', mssnblock
), /* start display text */
1676 M(NBLK
, 'K','S', mssnblock
), /* start keep */
1677 M(NBLK
, 'K','F', mssnblock
), /* start float keep */
1681 static const struct mactab mmmactab
[] = {
1682 M(NONE
, 'H',' ', MMHU
), /* -mm ? */
1683 M(NONE
, 'H','U', MMHU
), /* -mm ? */
1684 M(PARAG
, 'P',' ', PP
), /* paragraph for -mm */
1685 M(NBLK
, 'N','S', mssnblock
), /* undocumented */
1689 static const struct mactab memactab
[] = {
1690 M(PARAG
, 'p','p', mepp
),
1691 M(PARAG
, 'l','p', mepp
),
1692 M(PARAG
, 'n','p', mepp
),
1693 M(NONE
, 'i','p', meip
),
1695 M(NONE
, 's','h', mesh
),
1696 M(NONE
, 'u','h', mesh
),
1698 M(NBLK
, '(','l', mesnblock
),
1699 M(NBLK
, '(','q', mesnblock
),
1700 M(NBLK
, '(','b', mesnblock
),
1701 M(NBLK
, '(','z', mesnblock
),
1702 M(NBLK
, '(','c', mesnblock
),
1704 M(NBLK
, '(','d', mesnblock
),
1705 M(NBLK
, '(','f', mesnblock
),
1706 M(NBLK
, '(','x', mesnblock
),
1708 M(NONE
, 'r',' ', mefont
),
1709 M(NONE
, 'i',' ', mefont
),
1710 M(NONE
, 'b',' ', mefont
),
1711 M(NONE
, 'u',' ', mefont
),
1712 M(NONE
, 'q',' ', mefont
),
1713 M(NONE
, 'r','b', mefont
),
1714 M(NONE
, 'b','i', mefont
),
1715 M(NONE
, 'b','x', mefont
),
1719 static const struct mactab manmactab
[] = {
1720 M(PARAG
, 'B','I', manfont
),
1721 M(PARAG
, 'B','R', manfont
),
1722 M(PARAG
, 'I','B', manfont
),
1723 M(PARAG
, 'I','R', manfont
),
1724 M(PARAG
, 'R','B', manfont
),
1725 M(PARAG
, 'R','I', manfont
),
1727 M(PARAG
, 'P','P', manpp
),
1728 M(PARAG
, 'L','P', manpp
),
1729 M(PARAG
, 'H','P', manpp
),