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 static void hw_add(char *word
)
24 char *d
= hwword
+ hwword_len
;
26 if (hw_n
== LEN(hwoff
) || hwword_len
+ 128 > sizeof(hwword
))
31 hwhyph
[d
- hwword
] = 1;
36 hwoff
[i
] = hwword_len
;
37 hwword_len
= d
- hwword
;
38 dict_put(&hwdict
, hwword
+ hwoff
[i
], i
);
41 static int hw_lookup(char *word
, char *hyph
)
43 char word2
[WORDLEN
] = {0};
45 int map
[WORDLEN
] = {0};
47 hcode_strcpy(word2
, word
, map
, 0);
48 i
= dict_prefix(&hwdict
, word2
, &idx
);
51 hyph2
= hwhyph
+ hwoff
[i
];
52 for (j
= 0; word2
[j
]; j
++)
54 hyph
[map
[j
]] = hyph2
[j
];
58 void tr_hw(char **args
)
61 for (i
= 1; i
< NARGS
&& args
[i
]; i
++)
65 /* the tex hyphenation algorithm */
67 static int hyinit
; /* hyphenation data initialized */
68 static char hypats
[HYPATLEN
]; /* hyphenation patterns */
69 static char hynums
[HYPATLEN
]; /* hyphenation pattern numbers */
70 static int hypats_len
; /* used hypats[] and hynums[] length */
71 static struct dict hydict
; /* map patterns to their index in hyoff[] */
72 static int hyoff
[NHYPHS
]; /* the offset of this pattern in hypats[] */
73 static int hy_n
; /* the number of patterns */
75 /* find the patterns matching s and update hyphenation values in n */
76 static void hy_find(char *s
, char *n
)
82 while ((i
= dict_prefix(&hydict
, s
, &idx
)) >= 0) {
83 p
= hypats
+ hyoff
[i
];
84 np
= hynums
+ (p
- hypats
);
86 for (j
= 0; j
< plen
; j
++)
92 /* mark the hyphenation points of word in hyph */
93 static void hy_dohyph(char *hyph
, char *word
, int flg
)
95 char n
[WORDLEN
] = {0};
96 char w
[WORDLEN
] = {0};
97 int c
[WORDLEN
]; /* start of the i-th character in w */
98 int wmap
[WORDLEN
] = {0}; /* word[wmap[i]] is w[i] */
101 hcode_strcpy(w
, word
, wmap
, 1);
103 for (i
= 0; i
< wlen
- 1; i
+= utf8len((unsigned int) w
[i
]))
105 for (i
= 0; i
< nc
- 1; i
++)
106 hy_find(w
+ c
[i
], n
+ c
[i
]);
107 memset(hyph
, 0, wlen
* sizeof(hyph
[0]));
108 for (i
= 3; i
< nc
- 2; i
++)
109 if (n
[i
] % 2 && w
[c
[i
- 1]] != '.' && w
[c
[i
- 2]] != '.' && w
[c
[i
+ 1]] != '.')
110 hyph
[wmap
[c
[i
]]] = (~flg
& HY_FINAL2
|| w
[c
[i
+ 2]] != '.') &&
111 (~flg
& HY_FIRST2
|| w
[c
[i
- 3]] != '.');
114 /* insert pattern s into hypats[] and hynums[] */
115 static void hy_add(char *s
)
117 char *p
= hypats
+ hypats_len
;
118 char *n
= hynums
+ hypats_len
;
120 if (hy_n
>= NHYPHS
|| hypats_len
+ 64 >= sizeof(hypats
))
124 if (*s
>= '0' && *s
<= '9')
130 hyoff
[idx
] = hypats_len
;
131 dict_put(&hydict
, hypats
+ hyoff
[idx
], idx
);
136 static struct dict hcodedict
;
137 static char hcodesrc
[NHCODES
][GNLEN
];
138 static char hcodedst
[NHCODES
][GNLEN
];
141 /* replace the character in s after .hcode mapping; returns s's new length */
142 static int hcode_mapchar(char *s
)
144 int i
= dict_get(&hcodedict
, s
);
146 strcpy(s
, hcodedst
[i
]);
147 else if (isalpha((unsigned char) *s
))
152 /* copy s to d after .hcode mappings; s[map[j]] corresponds to d[j] */
153 static void hcode_strcpy(char *d
, char *s
, int *map
, int dots
)
155 int di
= 0, si
= 0, len
;
159 len
= utf8len((unsigned char) s
[si
]);
161 memcpy(d
+ di
, s
+ si
, len
);
163 di
+= hcode_mapchar(d
+ di
);
170 void tr_hcode(char **args
)
172 char c1
[GNLEN
], c2
[GNLEN
];
175 while (s
&& charread(&s
, c1
) >= 0 && charread(&s
, c2
) >= 0) {
176 i
= dict_get(&hcodedict
, c1
);
178 strcpy(hcodedst
[i
], c2
);
179 } else if (hcode_n
< NHCODES
) {
180 strcpy(hcodesrc
[hcode_n
], c1
);
181 strcpy(hcodedst
[hcode_n
], c2
);
182 dict_put(&hcodedict
, hcodesrc
[hcode_n
], hcode_n
);
188 static void hyph_readpatterns(char *s
)
194 while (*s
&& !isspace((unsigned char) *s
))
198 while (*s
&& isspace((unsigned char) *s
))
203 static void hyph_readexceptions(char *s
)
209 while (*s
&& !isspace((unsigned char) *s
))
213 while (*s
&& isspace((unsigned char) *s
))
218 void hyphenate(char *hyph
, char *word
, int flg
)
222 hyph_readpatterns(en_patterns
);
223 hyph_readexceptions(en_exceptions
);
225 if (hw_lookup(word
, hyph
))
226 hy_dohyph(hyph
, word
, flg
);
229 void tr_hpfa(char **args
)
234 /* load english hyphenation patterns with no arguments */
236 hyph_readpatterns(en_patterns
);
237 hyph_readexceptions(en_exceptions
);
239 /* reading patterns */
241 filp
= fopen(args
[1], "r");
242 while (fscanf(filp
, "%s", tok
) == 1)
243 if (strlen(tok
) < WORDLEN
)
247 /* reading exceptions */
249 filp
= fopen(args
[1], "r");
250 while (fscanf(filp
, "%s", tok
) == 1)
251 if (strlen(tok
) < WORDLEN
)
259 dict_init(&hwdict
, NHYPHS
, -1, 0, 1);
260 dict_init(&hydict
, NHYPHS
, -1, 0, 1);
261 dict_init(&hcodedict
, NHYPHS
, -1, 0, 1);
264 void tr_hpf(char **args
)
266 /* reseting the patterns */
270 /* reseting the dictionary */