8 #define HYPATLEN (NHYPHS * 16) /* hyphenation pattern length */
10 /* the hyphenation dictionary (.hw) */
12 static char hwword
[HYPATLEN
]; /* buffer for .hw words */
13 static char hwhyph
[HYPATLEN
]; /* buffer for .hw hyphenations */
14 static int hwword_len
; /* used hwword[] length */
15 /* word lists (per starting characters) for dictionary entries */
16 static int hwhead
[256]; /* the head of hw_*[] lists */
17 static int hwnext
[NHYPHS
]; /* the next word with the same initial */
18 static int hwidx
[NHYPHS
]; /* the offset of this word in hwword[] */
19 static int hwlen
[NHYPHS
]; /* the length of the word */
20 static int hw_n
= 1; /* number of words in hw_*[] lists */
22 /* functions for the hyphenation dictionary */
24 static void hw_add(char *word
)
27 char *d
= hwword
+ hwword_len
;
29 if (hw_n
== LEN(hwidx
) || hwword_len
+ 128 > sizeof(hwword
))
34 hwhyph
[d
- hwword
] = 1;
39 hwidx
[i
] = hwword_len
;
40 hwword_len
= d
- hwword
;
41 hwlen
[i
] = hwword_len
- hwidx
[i
] - 1;
42 hwnext
[i
] = hwhead
[(unsigned char) word
[0]];
43 hwhead
[(unsigned char) word
[0]] = i
;
46 /* copy lower-cased s to d */
47 static void hw_strcpy(char *d
, char *s
)
58 static char *hw_lookup(char *s
)
63 /* finding a dictionary entry that matches a prefix of the input */
64 i
= hwhead
[(unsigned char) word
[0]];
66 if (!strncmp(word
, hwword
+ hwidx
[i
], hwlen
[i
]))
67 return hwhyph
+ hwidx
[i
];
73 void tr_hw(char **args
)
76 for (i
= 1; i
< NARGS
&& args
[i
]; i
++)
80 /* the tex hyphenation algorithm */
82 static int hyinit
; /* hyphenation data initialized */
83 static char hypats
[HYPATLEN
]; /* the patterns */
84 static char hynums
[HYPATLEN
]; /* numbers in the patterns */
85 static int hypats_len
;
86 /* lists (one per pair of starting characters) for storing patterns */
87 static int hyhead
[256 * 256]; /* the head of hy_*[] lists */
88 static int hynext
[NHYPHS
]; /* the next pattern with the same initial */
89 static int hyoff
[NHYPHS
]; /* the offset of this pattern in hypats[] */
90 static int hy_n
= 1; /* number of words in hy_*[] lists */
92 #define HYC_MAP(c) ((c) == '.' ? 0 : (c))
94 /* index of the string starting with a and b in hyhash[] */
95 static int hy_idx(char *s
)
97 return (HYC_MAP((unsigned char) s
[1]) << 8) |
98 HYC_MAP((unsigned char) s
[0]);
101 /* make s lower-case and replace its non-alphabetic characters with . */
102 static void hy_strcpy(char *d
, char *s
)
106 while ((c
= (unsigned char) *s
++))
107 *d
++ = c
& 0x80 ? c
: (isalpha(c
) ? tolower(c
) : '.');
112 /* find the patterns matching s and update hyphenation values in n */
113 static void hy_find(char *s
, char *n
)
118 int idx
= hyhead
[hy_idx(s
)];
120 p
= hypats
+ hyoff
[idx
];
121 np
= hynums
+ (p
- hypats
);
123 if (!strncmp(s
+ 2, p
+ 2, plen
- 2))
124 for (j
= 0; j
< plen
; j
++)
131 /* mark the hyphenation points of word in hyph */
132 static void hy_dohyph(char *hyph
, char *word
, int flg
)
134 char n
[ILNLEN
] = {0};
136 int c
[ILNLEN
]; /* start of the i-th character in w */
141 for (i
= 0; i
< wlen
- 1; i
+= utf8len((unsigned int) w
[i
]))
143 for (i
= 0; i
< nc
- 1; i
++)
144 hy_find(w
+ c
[i
], n
+ c
[i
]);
145 memset(hyph
, 0, wlen
* sizeof(hyph
[0]));
146 for (i
= 3; i
< nc
- 2; i
++)
147 if (n
[i
] % 2 && w
[c
[i
- 1]] != '.' && w
[c
[i
- 2]] != '.' && w
[c
[i
+ 1]] != '.')
148 hyph
[c
[i
- 1]] = (~flg
& HY_FINAL2
|| w
[c
[i
+ 2]] != '.') &&
149 (~flg
& HY_FIRST2
|| w
[c
[i
- 3]] != '.');
152 /* insert pattern s into hypats[] and hynums[] */
153 static void hy_ins(char *s
)
155 char *p
= hypats
+ hypats_len
;
156 char *n
= hynums
+ hypats_len
;
158 if (hy_n
>= NHYPHS
|| hypats_len
+ 64 >= sizeof(hypats
))
162 if (*s
>= '0' && *s
<= '9')
168 hyoff
[idx
] = hypats_len
;
169 hynext
[idx
] = hyhead
[hy_idx(p
)];
170 hyhead
[hy_idx(p
)] = idx
;
174 static void hyph_readpatterns(char *s
)
180 while (*s
&& !isspace((unsigned char) *s
))
184 while (*s
&& isspace((unsigned char) *s
))
189 static void hyph_readexceptions(char *s
)
195 while (*s
&& !isspace((unsigned char) *s
))
199 while (*s
&& isspace((unsigned char) *s
))
204 void hyphenate(char *hyph
, char *word
, int flg
)
209 hyph_readpatterns(en_patterns
);
210 hyph_readexceptions(en_exceptions
);
214 memcpy(hyph
, r
, strlen(word
) + 1);
216 hy_dohyph(hyph
, word
, flg
);
219 void tr_hpfa(char **args
)
223 /* reading patterns */
226 filp
= fopen(args
[1], "r");
227 while (fscanf(filp
, "%s", tok
) == 1)
231 /* reading exceptions */
233 filp
= fopen(args
[1], "r");
234 while (fscanf(filp
, "%s", tok
) == 1)
240 void tr_hpf(char **args
)
242 /* reseting the patterns */
245 memset(hyhead
, 0, sizeof(hyhead
));
246 memset(hynext
, 0, sizeof(hynext
));
247 /* reseting the dictionary */
250 memset(hwhead
, 0, sizeof(hwhead
));
251 memset(hwnext
, 0, sizeof(hwnext
));