ref: fa9769a25be700f1aecaeb688f1dd57c9366b87e
parent: a5c5a55a1576bd756d101d529ffd48eaf7d7f975
author: Ali Gholami Rudi <ali@rudi.ir>
date: Sat Sep 21 16:05:18 EDT 2013
hyph: drop non-alpha characters for HY_FIRST2 and HY_FINAL2 This prevents "finally..." from being hyphenated as "final-ly...".
--- a/hyph.c
+++ b/hyph.c
@@ -21,7 +21,7 @@
static void hyph_initpatterns(void);
static void hyph_initexceptions(void);
-static void hyfind(char *hyph, char *word);
+static void hyfind(char *hyph, char *word, int flg);
static void hyexcept_add(char *s)
{
@@ -66,7 +66,7 @@
return NULL;
}
-void hyphenate(char *hyph, char *word)
+void hyphenate(char *hyph, char *word, int flg)
{
char *r;
if (!hyinit) {
@@ -78,7 +78,7 @@
if (r)
memcpy(hyph, r, strlen(word) + 1);
else
- hyfind(hyph, word);
+ hyfind(hyph, word, flg);
}
void tr_hw(char **args)
@@ -98,7 +98,7 @@
return (HYC_MAP(a) << 5) | HYC_MAP(b);
}
-static void hyfind(char *hyph, char *word)
+static void hyfind(char *hyph, char *word, int flg)
{
char n[ILNLEN] = {0};
char w[ILNLEN];
@@ -124,8 +124,11 @@
break;
}
}
- for (i = 1; i < wlen - 1; i++)
- hyph[i - 1] = i > 2 && i < wlen - 3 && n[i] % 2;
+ memset(hyph, 0, wlen * sizeof(hyph[0]));
+ for (i = 3; i < wlen - 2; i++)
+ if (n[i] % 2 && w[i - 1] != '.' && w[i - 2] != '.' && w[i + 1] != '.')
+ hyph[i - 1] = (~flg & HY_FINAL2 || w[i + 2] != '.') &&
+ (~flg & HY_FIRST2 || w[i - 3] != '.');
}
static void hyins(char *s)
--- a/roff.h
+++ b/roff.h
@@ -244,7 +244,7 @@
#define HY_FIRST2 0x08 /* do not hyphenate the first two characters */
#define HY_ANY 0x10 /* break at any possible position */
-void hyphenate(char *hyphs, char *word);
+void hyphenate(char *hyphs, char *word, int flg);
/* adjustment */
#define AD_L 0
--- a/wb.c
+++ b/wb.c
@@ -399,35 +399,36 @@
static char *hyphpos(char *s, int w, struct wb *w1, int flg)
{
- char *map[ILNLEN] = {NULL}; /* mapping from word to s */
- int fits[ILNLEN] = {0}; /* fits[i] if word[0..i]- fits w */
- char word[ILNLEN];
- char hyph[ILNLEN];
+ char word[ILNLEN]; /* word to pass to hyphenate() */
+ char hyph[ILNLEN]; /* hyphenation points returned from hyphenate() */
+ char *iw[ILNLEN]; /* beginning of i-th char in word */
+ char *is[ILNLEN]; /* beginning of i-th char in s */
+ int fits[ILNLEN]; /* fits[i] is 1, if the first i chars fit w */
+ int n = 0; /* the number of characters in word */
char d[ILNLEN];
char *prev_s = s;
char *r = NULL;
char *wp = word, *we = word + sizeof(word);
- int beg, end;
int i, c;
skipreqs(&s, w1);
- while ((c = escread(&s, d)) >= 0 && wp + strlen(d) + 1 < we) {
+ while ((c = escread(&s, d)) >= 0 && (c > 0 || strlen(d) + 1 < we - wp)) {
+ fits[n] = wb_wid(w1) + wb_dashwid(w1) <= w;
wb_putc(w1, c, d);
if (c == 0) {
+ iw[n] = wp;
+ is[n] = prev_s;
strcpy(wp, d);
- map[wp - word] = prev_s;
wp = strchr(wp, '\0');
- fits[wp - word] = wb_wid(w1) + wb_dashwid(w1) <= w;
+ n++;
}
prev_s = s;
}
- if (strlen(word) < 4)
+ if (n < 4)
return NULL;
- hyphenate(hyph, word);
- beg = flg & HY_FIRST2 ? 3 : 2;
- end = strlen(word) - (flg & HY_FINAL2 ? 2 : 1);
- for (i = beg; i < end; i++)
- if (map[i] && hyph[i] && (fits[i] || ((flg & HY_ANY) && !r)))
- r = map[i];
+ hyphenate(hyph, word, flg);
+ for (i = 2; i < n - 1; i++)
+ if (hyph[iw[i] - word] && (fits[i] || ((flg & HY_ANY) && !r)))
+ r = is[i];
return r;
}