8 #define HYPATLEN (NHYPHS * 16) /* hyphenation pattern length */
10 static void hcode_strcpy(char *d
, char *s
, int *map
, int dots
);
12 /* the hyphenation dictionary (.hw) */
14 static char hwword
[HYPATLEN
]; /* buffer for .hw words */
15 static char hwhyph
[HYPATLEN
]; /* buffer for .hw hyphenations */
16 static int hwword_len
; /* used hwword[] length */
17 static struct dict hwdict
; /* map words to their index in hwoff[] */
18 static int hwoff
[NHYPHS
]; /* the offset of words in hwword[] */
19 static int hw_n
; /* the number of dictionary words */
21 /* insert word s into hwword[] and hwhyph[] */
22 static void hw_add(char *s
)
24 char *p
= hwword
+ hwword_len
;
25 char *n
= hwhyph
+ hwword_len
;
26 int len
= strlen(s
) + 1;
28 if (hw_n
== NHYPHS
|| hwword_len
+ len
> sizeof(hwword
))
31 while ((c
= (unsigned char) *s
++)) {
38 hwoff
[hw_n
] = hwword_len
;
39 dict_put(&hwdict
, hwword
+ hwoff
[hw_n
], hw_n
);
44 static int hw_lookup(char *word
, char *hyph
)
46 char word2
[WORDLEN
] = {0};
48 int map
[WORDLEN
] = {0};
50 hcode_strcpy(word2
, word
, map
, 0);
51 i
= dict_prefix(&hwdict
, word2
, &idx
);
54 hyph2
= hwhyph
+ hwoff
[i
];
55 for (j
= 0; word2
[j
]; j
++)
57 hyph
[map
[j
]] = hyph2
[j
];
61 void tr_hw(char **args
)
64 for (i
= 1; i
< NARGS
&& args
[i
]; i
++)
68 /* the tex hyphenation algorithm */
70 static int hyinit
; /* hyphenation data initialized */
71 static char hypats
[HYPATLEN
]; /* hyphenation patterns */
72 static char hynums
[HYPATLEN
]; /* hyphenation pattern numbers */
73 static int hypats_len
; /* used hypats[] and hynums[] length */
74 static struct dict hydict
; /* map patterns to their index in hyoff[] */
75 static int hyoff
[NHYPHS
]; /* the offset of this pattern in hypats[] */
76 static int hy_n
; /* the number of patterns */
78 /* find the patterns matching s and update hyphenation values in n */
79 static void hy_find(char *s
, char *n
)
85 while ((i
= dict_prefix(&hydict
, s
, &idx
)) >= 0) {
86 p
= hypats
+ hyoff
[i
];
87 np
= hynums
+ (p
- hypats
);
89 for (j
= 0; j
< plen
; j
++)
95 /* mark the hyphenation points of word in hyph */
96 static void hy_dohyph(char *hyph
, char *word
, int flg
)
98 char n
[WORDLEN
] = {0};
99 char w
[WORDLEN
] = {0};
100 int c
[WORDLEN
]; /* start of the i-th character in w */
101 int wmap
[WORDLEN
] = {0}; /* word[wmap[i]] is w[i] */
104 hcode_strcpy(w
, word
, wmap
, 1);
106 for (i
= 0; i
< wlen
- 1; i
+= utf8len((unsigned char) w
[i
]))
108 for (i
= 0; i
< nc
- 1; i
++)
109 hy_find(w
+ c
[i
], n
+ c
[i
]);
110 memset(hyph
, 0, wlen
* sizeof(hyph
[0]));
111 for (i
= 3; i
< nc
- 2; i
++)
112 if (n
[c
[i
]] % 2 && w
[c
[i
- 1]] != '.' &&
113 w
[c
[i
- 2]] != '.' && w
[c
[i
+ 1]] != '.' &&
114 (~flg
& HY_FINAL2
|| w
[c
[i
+ 2]] != '.') &&
115 (~flg
& HY_FIRST2
|| w
[c
[i
- 3]] != '.'))
116 hyph
[wmap
[c
[i
]]] = 1;
119 /* insert pattern s into hypats[] and hynums[] */
120 static void hy_add(char *s
)
122 char *p
= hypats
+ hypats_len
;
123 char *n
= hynums
+ hypats_len
;
124 int len
= strlen(s
) + 1;
126 if (hy_n
>= NHYPHS
|| hypats_len
+ len
>= sizeof(hypats
))
129 while ((c
= (unsigned char) *s
++)) {
130 if (c
>= '0' && c
<= '9')
136 hyoff
[hy_n
] = hypats_len
;
137 dict_put(&hydict
, hypats
+ hyoff
[hy_n
], hy_n
);
143 static struct dict hcodedict
;
144 static char hcodesrc
[NHCODES
][GNLEN
];
145 static char hcodedst
[NHCODES
][GNLEN
];
148 /* replace the character in s after .hcode mapping; returns s's new length */
149 static int hcode_mapchar(char *s
)
151 int i
= dict_get(&hcodedict
, s
);
153 strcpy(s
, hcodedst
[i
]);
154 else if (isalpha((unsigned char) *s
))
159 /* copy s to d after .hcode mappings; s[map[j]] corresponds to d[j] */
160 static void hcode_strcpy(char *d
, char *s
, int *map
, int dots
)
162 int di
= 0, si
= 0, len
;
165 while (di
< WORDLEN
- GNLEN
&& s
[si
]) {
166 len
= utf8len((unsigned char) s
[si
]);
168 memcpy(d
+ di
, s
+ si
, len
);
170 di
+= hcode_mapchar(d
+ di
);
177 static void hcode_add(char *c1
, char *c2
)
179 int i
= dict_get(&hcodedict
, c1
);
181 strcpy(hcodedst
[i
], c2
);
182 } else if (hcode_n
< NHCODES
) {
183 strcpy(hcodesrc
[hcode_n
], c1
);
184 strcpy(hcodedst
[hcode_n
], c2
);
185 dict_put(&hcodedict
, hcodesrc
[hcode_n
], hcode_n
);
190 void tr_hcode(char **args
)
192 char c1
[GNLEN
], c2
[GNLEN
];
194 while (s
&& utf8read(&s
, c1
) && utf8read(&s
, c2
))
198 static void hyph_readpatterns(char *s
)
204 while (*s
&& !isspace((unsigned char) *s
))
208 while (*s
&& isspace((unsigned char) *s
))
213 static void hyph_readexceptions(char *s
)
219 while (*s
&& !isspace((unsigned char) *s
))
223 while (*s
&& isspace((unsigned char) *s
))
228 void hyphenate(char *hyph
, char *word
, int flg
)
232 hyph_readpatterns(en_patterns
);
233 hyph_readexceptions(en_exceptions
);
235 if (hw_lookup(word
, hyph
))
236 hy_dohyph(hyph
, word
, flg
);
239 void tr_hpfa(char **args
)
241 char tok
[ILNLEN
], c1
[ILNLEN
], c2
[ILNLEN
];
244 /* load english hyphenation patterns with no arguments */
246 hyph_readpatterns(en_patterns
);
247 hyph_readexceptions(en_exceptions
);
249 /* reading patterns */
250 if (args
[1] && (filp
= fopen(args
[1], "r"))) {
251 while (fscanf(filp
, "%s", tok
) == 1)
252 if (strlen(tok
) < WORDLEN
)
256 /* reading exceptions */
257 if (args
[2] && (filp
= fopen(args
[2], "r"))) {
258 while (fscanf(filp
, "%s", tok
) == 1)
259 if (strlen(tok
) < WORDLEN
)
263 /* reading hcode mappings */
264 if (args
[3] && (filp
= fopen(args
[3], "r"))) {
265 while (fscanf(filp
, "%s", tok
) == 1) {
267 if (utf8read(&s
, c1
) && utf8read(&s
, c2
) && !*s
)
268 hcode_add(c2
, c1
); /* inverting */
276 dict_init(&hwdict
, NHYPHS
, -1, 0, 1);
277 dict_init(&hydict
, NHYPHS
, -1, 0, 1);
278 dict_init(&hcodedict
, NHYPHS
, -1, 0, 1);
281 void tr_hpf(char **args
)
283 /* reseting the patterns */
287 /* reseting the dictionary */
291 /* reseting hcode mappings */
293 dict_done(&hcodedict
);