summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/luatexdir/lang
diff options
context:
space:
mode:
authorTaco Hoekwater <taco@elvenkind.com>2009-03-27 15:30:55 +0000
committerTaco Hoekwater <taco@elvenkind.com>2009-03-27 15:30:55 +0000
commit178de0871d690556af74f3768c11bc812b07f347 (patch)
treea939c31adc90d6207848effaec87dd78ec00e658 /Build/source/texk/web2c/luatexdir/lang
parent4865b23b5199697829e4e6633f2f697b4634c462 (diff)
Import of luatex 0.37.0 (autoreconf has not been run yet!)
git-svn-id: svn://tug.org/texlive/trunk@12529 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/lang')
-rw-r--r--Build/source/texk/web2c/luatexdir/lang/hyphen.c48
-rw-r--r--Build/source/texk/web2c/luatexdir/lang/texlang.c1498
2 files changed, 883 insertions, 663 deletions
diff --git a/Build/source/texk/web2c/luatexdir/lang/hyphen.c b/Build/source/texk/web2c/luatexdir/lang/hyphen.c
index 049210d3d71..56d745809ae 100644
--- a/Build/source/texk/web2c/luatexdir/lang/hyphen.c
+++ b/Build/source/texk/web2c/luatexdir/lang/hyphen.c
@@ -53,6 +53,9 @@
#include "hnjalloc.h"
#include "hyphen.h"
+static const char _svn_version[] =
+ "$Id: hyphen.c 1696 2008-12-28 21:02:34Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lang/texlang.c $";
+
/* SHOULD BE MOVED TO SEPARATE LIBRARY */
static unsigned char * hnj_strdup(
const unsigned char *s
@@ -283,7 +286,15 @@ static void hyppat_insert(
i = hnj_string_hash (key) % HASH_SIZE;
for (e = hashtab->entries[i]; e; e=e->next) {
if (strcmp((char*)e->key,(char*)key)==0) {
- if (e->u.hyppat) hnj_free(e->u.hyppat);
+ if (e->u.hyppat) {
+ if (hyppat && strcmp((char*)e->u.hyppat,(char*)hyppat)!=0) {
+ int s = maketexstring("Conflicting pattern ignored");
+ do_print_err(s);
+ error();
+ flush_str(s);
+ }
+ hnj_free(e->u.hyppat);
+ }
e->u.hyppat = hyppat;
hnj_free(key);
return;
@@ -418,7 +429,7 @@ static const unsigned char* next_pattern(
size_t* length,
const unsigned char **buf
) {
- const unsigned char *rover = *buf, *here;
+ const unsigned char *here, *rover = *buf;
while (*rover && isspace(*rover)) rover++;
here = rover;
while (*rover) {
@@ -598,10 +609,10 @@ void hnj_hyphen_load(
const unsigned char* format;
const unsigned char* begin = f;
+ unsigned char *pat;
+ char *org;
while((format = next_pattern(&l,&f))!=NULL) {
int i,j,e;
- unsigned char *pat;
- char *org;
/*
printf("%s\n",format);
char* repl = strnchr(format, '/',l);
@@ -630,10 +641,11 @@ void hnj_hyphen_load(
if (is_utf8_follow(format[i])) e++;
}
/* l-e => number of _characters_ not _bytes_*/
+ /* l-j => number of pattern bytes */
/* l-e-j => number of pattern characters*/
pat = (unsigned char*) malloc(1+l-j);
org = ( char*) malloc(2+l-e-j);
- /* remove hyphenation encoders (digits) from pat*/
+ /* remove hyphenation encoders (digits) from pat*/
org[0] = '0';
for (i=0,j=0,e=0; (unsigned)i<l; i++) {
unsigned char c = format[i];
@@ -659,15 +671,15 @@ void hnj_hyphen_load(
for (l=1; l<=wordsize; l++) {
if (is_utf8_follow(word[l])) continue; /* Do not clip an utf8 sequence*/
for (j=1; j<=l; j++) {
- int i = l-j;
char *subpat_pat;
+ int i = l-j;
if (is_utf8_follow(word[i])) continue; /* Do not start halfway an utf8 sequence*/
if ((subpat_pat = hyppat_lookup(dict->patterns,word+i,j))!=NULL) {
char* newpat_pat;
if ((newpat_pat = hyppat_lookup(dict->merged,word,l))==NULL) {
+ char *neworg;
unsigned char *newword=(unsigned char*)malloc(l+1);
int e=0;
- char *neworg;
strncpy((char*)newword, (char*)word,l); newword[l]=0;
for (i=0; i<l; i++) if (is_utf8_follow(newword[i])) e++;
neworg = malloc(l+2-e);
@@ -700,7 +712,8 @@ void hnj_hyphen_load(
last_state = state_num;
ch = word[j];
if (ch>=0x80) {
- int i=1, m;
+ int m;
+ int i=1;
while (is_utf8_follow(word[j-i])) i++;
ch = word[j-i] & mask[i];
m = j-i;
@@ -757,14 +770,14 @@ void hnj_hyphen_hyphenate(
halfword right,
lang_variables *lan
) {
+ int char_num;
+ halfword here;
+ int state = 0;
/* +2 for dots at each end, +1 for points /outside/ characters*/
int ext_word_len = length+2;
int hyphen_len = ext_word_len+1;
/*char *hyphens = hnj_malloc((hyphen_len*2)+1); */ /* LATER */
char *hyphens = hnj_malloc(hyphen_len+1);
- int char_num;
- int state = 0;
- halfword here;
/* Add a '.' to beginning and end to facilitate matching*/
set_vlink(begin_point,first);
@@ -780,18 +793,21 @@ void hnj_hyphen_hyphenate(
hyphens[hyphen_len] = 0;
/* now, run the finite state machine */
- for (char_num=0, here=begin_point; here!=end_point; here=get_vlink(here)) {
-
- int ch = get_lc_code(get_character(here));
+ for (char_num=0, here=begin_point; here!=get_vlink(end_point); here=get_vlink(here)) {
+ int ch;
+ if (here == begin_point || here == end_point)
+ ch='.';
+ else
+ ch = get_lc_code(get_character(here));
while (state!=-1) {
/* printf("%*s%s%c",char_num-strlen(get_state_str(state)),"",get_state_str(state),(char)ch);*/
HyphenState *hstate = &dict->states[state];
int k;
for (k = 0; k < hstate->num_trans; k++) {
if (hstate->trans[k].uni_ch == ch) {
- char *match;
- state = hstate->trans[k].new_state;
+ char *match;
+ state = hstate->trans[k].new_state;
/* printf(" state %d\n",state);*/
match = dict->states[state].match;
if (match) {
diff --git a/Build/source/texk/web2c/luatexdir/lang/texlang.c b/Build/source/texk/web2c/luatexdir/lang/texlang.c
index 1f847f5c643..c37350f146f 100644
--- a/Build/source/texk/web2c/luatexdir/lang/texlang.c
+++ b/Build/source/texk/web2c/luatexdir/lang/texlang.c
@@ -1,24 +1,21 @@
-/*
-Copyright (c) 2007 Taco Hoekwater <taco@latex.org>
+/* texlang.c
+
+ Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
-This file is part of luatex.
+ This file is part of LuaTeX.
-luatex is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+ LuaTeX is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
-luatex is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ LuaTeX is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with luatex; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-This is texlang.c
-*/
+ You should have received a copy of the GNU General Public License along
+ with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
#include "luatex-api.h"
#include <ptexlib.h>
@@ -26,464 +23,648 @@ This is texlang.c
#include <string.h>
#include "nodes.h"
+#include "font/texfont.h"
#include "hyphen.h"
+static const char _svn_version[] =
+ "$Id: texlang.c 2064 2009-03-20 13:13:14Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lang/texlang.c $";
+
/* functions from the fontforge unicode library */
-extern unsigned int *utf82u_strcpy(unsigned int *ubuf,const char *utf8buf);
+#if 0
+extern unsigned int *utf82u_strcpy(unsigned int *ubuf, const char *utf8buf);
extern unsigned int u_strlen(unsigned int *ubuf);
-extern char *utf8_idpb(char *w,unsigned int i);
+extern char *utf8_idpb(char *w, unsigned int i);
+#else
+
+typedef unsigned int unichar_t;
+typedef unsigned char uint8;
+typedef unsigned int uint32;
+
+static unichar_t *utf82u_strcpy(unichar_t * ubuf, const char *utf8buf)
+{
+ int len = strlen(utf8buf) + 1;
+ unichar_t *upt = ubuf, *uend = ubuf + len - 1;
+ const uint8 *pt = (const uint8 *) utf8buf, *end = pt + strlen(utf8buf);
+ int w, w2;
+
+ while (pt < end && *pt != '\0' && upt < uend) {
+ if (*pt <= 127)
+ *upt = *pt++;
+ else if (*pt <= 0xdf) {
+ *upt = ((*pt & 0x1f) << 6) | (pt[1] & 0x3f);
+ pt += 2;
+ } else if (*pt <= 0xef) {
+ *upt = ((*pt & 0xf) << 12) | ((pt[1] & 0x3f) << 6) | (pt[2] & 0x3f);
+ pt += 3;
+ } else {
+ w = (((*pt & 0x7) << 2) | ((pt[1] & 0x30) >> 4)) - 1;
+ w = (w << 6) | ((pt[1] & 0xf) << 2) | ((pt[2] & 0x30) >> 4);
+ w2 = ((pt[2] & 0xf) << 6) | (pt[3] & 0x3f);
+ *upt = w * 0x400 + w2 + 0x10000;
+ pt += 4;
+ }
+ ++upt;
+ }
+ *upt = '\0';
+ return (ubuf);
+}
+
+static char *utf8_idpb(char *utf8_text, uint32 ch)
+{
+ /* Increment and deposit character */
+ if (ch >= 17 * 65536)
+ return (utf8_text);
+
+ if (ch <= 127)
+ *utf8_text++ = ch;
+ else if (ch <= 0x7ff) {
+ *utf8_text++ = 0xc0 | (ch >> 6);
+ *utf8_text++ = 0x80 | (ch & 0x3f);
+ } else if (ch <= 0xffff) {
+ *utf8_text++ = 0xe0 | (ch >> 12);
+ *utf8_text++ = 0x80 | ((ch >> 6) & 0x3f);
+ *utf8_text++ = 0x80 | (ch & 0x3f);
+ } else {
+ uint32 val = ch - 0x10000;
+ int u = ((val & 0xf0000) >> 16) + 1, z = (val & 0x0f000) >> 12, y =
+ (val & 0x00fc0) >> 6, x = val & 0x0003f;
+ *utf8_text++ = 0xf0 | (u >> 2);
+ *utf8_text++ = 0x80 | ((u & 3) << 4) | z;
+ *utf8_text++ = 0x80 | y;
+ *utf8_text++ = 0x80 | x;
+ }
+ return (utf8_text);
+}
+
+static int u_strlen(register unichar_t * str)
+{
+ register int len = 0;
+ while (*str++ != '\0')
+ ++len;
+ return (len);
+}
+
+#endif
#define noVERBOSE
-#define MAX_TEX_LANGUAGES 32767
+#define MAX_TEX_LANGUAGES 32768
-static struct tex_language *tex_languages[MAX_TEX_LANGUAGES] = {NULL};
+static struct tex_language *tex_languages[MAX_TEX_LANGUAGES] = { NULL };
static int next_lang_id = 0;
-struct tex_language *
-new_language (void) {
- struct tex_language* lang;
- if (next_lang_id<MAX_TEX_LANGUAGES) {
- lang = xmalloc(sizeof(struct tex_language));
- tex_languages[next_lang_id] = lang;
- lang->id = next_lang_id++;
- lang->exceptions = 0;
- lang->patterns = NULL;
- lang->pre_hyphen_char = '-';
- lang->post_hyphen_char = 0;
- return lang;
- } else {
- return NULL;
- }
+struct tex_language *new_language(int n)
+{
+ struct tex_language *lang;
+ unsigned l;
+ if (n >= 0) {
+ l = (unsigned) n;
+ if (l != (MAX_TEX_LANGUAGES - 1))
+ if (next_lang_id <= n)
+ next_lang_id = n + 1;
+ } else {
+ while (tex_languages[next_lang_id] != NULL)
+ next_lang_id++;
+ l = next_lang_id++;
+ }
+ if (l < (MAX_TEX_LANGUAGES - 1) && tex_languages[l] == NULL) {
+ lang = xmalloc(sizeof(struct tex_language));
+ tex_languages[l] = lang;
+ lang->id = l;
+ lang->exceptions = 0;
+ lang->patterns = NULL;
+ lang->pre_hyphen_char = '-';
+ lang->post_hyphen_char = 0;
+ lang->pre_exhyphen_char = 0;
+ lang->post_exhyphen_char = 0;
+ return lang;
+ } else {
+ return NULL;
+ }
}
-struct tex_language *
-get_language (int n) {
- if (n>=0 && n<MAX_TEX_LANGUAGES ) {
- if (tex_languages[n]!=NULL) {
- return tex_languages[n];
+struct tex_language *get_language(int n)
+{
+ if (n >= 0 && n < MAX_TEX_LANGUAGES) {
+ if (tex_languages[n] != NULL) {
+ return tex_languages[n];
+ } else {
+ return new_language(n);
+ }
} else {
- return new_language();
+ return NULL;
}
- } else {
- return NULL;
- }
}
-void
-set_pre_hyphen_char (integer n, integer v) {
- struct tex_language *l = get_language((int)n);
- if (l!=NULL)
- l->pre_hyphen_char = (int)v;
+void set_pre_hyphen_char(integer n, integer v)
+{
+ struct tex_language *l = get_language((int) n);
+ if (l != NULL)
+ l->pre_hyphen_char = (int) v;
}
-void
-set_post_hyphen_char (integer n, integer v) {
- struct tex_language *l = get_language((int)n);
- if (l!=NULL)
- l->post_hyphen_char = (int)v;
+void set_post_hyphen_char(integer n, integer v)
+{
+ struct tex_language *l = get_language((int) n);
+ if (l != NULL)
+ l->post_hyphen_char = (int) v;
}
-integer
-get_pre_hyphen_char (integer n) {
- struct tex_language *l = get_language((int)n);
- if (l==NULL) return -1;
- return (integer)l->pre_hyphen_char;
+
+void set_pre_exhyphen_char(integer n, integer v)
+{
+ struct tex_language *l = get_language((int) n);
+ if (l != NULL)
+ l->pre_exhyphen_char = (int) v;
}
-integer
-get_post_hyphen_char (integer n) {
- struct tex_language *l = get_language((int)n);
- if (l==NULL) return -1;
- return (integer)l->post_hyphen_char;
+void set_post_exhyphen_char(integer n, integer v)
+{
+ struct tex_language *l = get_language((int) n);
+ if (l != NULL)
+ l->post_exhyphen_char = (int) v;
}
-void
-load_patterns (struct tex_language *lang, unsigned char *buffer) {
- if (lang==NULL)
- return;
- if (lang->patterns==NULL) {
- lang->patterns = hnj_hyphen_new();
- }
- hnj_hyphen_load (lang->patterns,buffer);
+
+
+integer get_pre_hyphen_char(integer n)
+{
+ struct tex_language *l = get_language((int) n);
+ if (l == NULL)
+ return -1;
+ return (integer) l->pre_hyphen_char;
}
-void
-clear_patterns (struct tex_language *lang) {
- if (lang==NULL)
- return;
- if (lang->patterns!=NULL) {
- hnj_hyphen_clear(lang->patterns);
- }
+integer get_post_hyphen_char(integer n)
+{
+ struct tex_language *l = get_language((int) n);
+ if (l == NULL)
+ return -1;
+ return (integer) l->post_hyphen_char;
}
-void
-load_tex_patterns(int curlang, halfword head) {
- char *s = tokenlist_to_cstring (head,1, NULL);
- load_patterns(get_language(curlang),(unsigned char *)s);
+
+integer get_pre_exhyphen_char(integer n)
+{
+ struct tex_language *l = get_language((int) n);
+ if (l == NULL)
+ return -1;
+ return (integer) l->pre_exhyphen_char;
+}
+
+integer get_post_exhyphen_char(integer n)
+{
+ struct tex_language *l = get_language((int) n);
+ if (l == NULL)
+ return -1;
+ return (integer) l->post_exhyphen_char;
+}
+
+void load_patterns(struct tex_language *lang, unsigned char *buffer)
+{
+ if (lang == NULL)
+ return;
+ if (lang->patterns == NULL) {
+ lang->patterns = hnj_hyphen_new();
+ }
+ hnj_hyphen_load(lang->patterns, buffer);
+}
+
+void clear_patterns(struct tex_language *lang)
+{
+ if (lang == NULL)
+ return;
+ if (lang->patterns != NULL) {
+ hnj_hyphen_clear(lang->patterns);
+ }
+}
+
+void load_tex_patterns(int curlang, halfword head)
+{
+ char *s = tokenlist_to_cstring(head, 1, NULL);
+ load_patterns(get_language(curlang), (unsigned char *) s);
}
#define STORE_CHAR(x) { word[w] = x ; if (w<MAX_WORD_LEN) w++; }
-
+
/* todo change this! */
-char *
-clean_hyphenation (char *buffer, char **cleaned) {
- int items;
- unsigned char word [MAX_WORD_LEN+1];
- int w = 0;
- char *s = buffer;
- while (*s && !isspace(*s)) {
- if (*s == '-') { /* skip */
- } else if (*s == '=') {
- STORE_CHAR('-');
- } else if (*s == '{') {
- s++;
- items=0;
- while (*s && *s!='}') { s++; }
- if (*s=='}') { items++; s++; }
- while (*s && *s!='}') { s++; }
- if (*s=='}') { items++; s++; }
- if (*s=='{') { s++; }
- while (*s && *s!='}') {STORE_CHAR(*s); s++; }
- if (*s=='}') { items++; } else { s--; }
- if (items!=3) { /* syntax error */
- *cleaned = NULL;
- while (*s && !isspace(*s)) { s++; }
- return s;
- }
- } else {
- STORE_CHAR(*s);
+char *clean_hyphenation(char *buffer, char **cleaned)
+{
+ int items;
+ unsigned char word[MAX_WORD_LEN + 1];
+ int w = 0;
+ char *s = buffer;
+ while (*s && !isspace(*s)) {
+ if (*s == '-') { /* skip */
+ } else if (*s == '=') {
+ STORE_CHAR('-');
+ } else if (*s == '{') {
+ s++;
+ items = 0;
+ while (*s && *s != '}') {
+ s++;
+ }
+ if (*s == '}') {
+ items++;
+ s++;
+ }
+ while (*s && *s != '}') {
+ s++;
+ }
+ if (*s == '}') {
+ items++;
+ s++;
+ }
+ if (*s == '{') {
+ s++;
+ }
+ while (*s && *s != '}') {
+ STORE_CHAR(*s);
+ s++;
+ }
+ if (*s == '}') {
+ items++;
+ } else {
+ s--;
+ }
+ if (items != 3) { /* syntax error */
+ *cleaned = NULL;
+ while (*s && !isspace(*s)) {
+ s++;
+ }
+ return s;
+ }
+ } else {
+ STORE_CHAR(*s);
+ }
+ s++;
}
- s++;
- }
- word[w] = 0;
- *cleaned = xstrdup((char *)word);
- return s;
-}
-
-void
-load_hyphenation (struct tex_language *lang, unsigned char *buffer) {
- char *s, *value, *cleaned;
- lua_State *L = Luas[0];
- if (lang==NULL)
- return;
- if (lang->exceptions==0) {
- lua_newtable(L);
- lang->exceptions = luaL_ref(L,LUA_REGISTRYINDEX);
- }
- lua_rawgeti(L, LUA_REGISTRYINDEX, lang->exceptions);
- s = (char *)buffer;
- while (*s) {
- while (isspace(*s)) s++;
- if (*s) {
- value = s;
- s = clean_hyphenation(s, &cleaned);
- if (cleaned!=NULL) {
- if ((s-value)>0) {
- lua_pushstring(L,cleaned);
- lua_pushlstring(L,value,(s-value));
- lua_rawset(L,-3);
- }
- free(cleaned);
- } else {
+ word[w] = 0;
+ *cleaned = xstrdup((char *) word);
+ return s;
+}
+
+void load_hyphenation(struct tex_language *lang, unsigned char *buffer)
+{
+ char *s, *value, *cleaned;
+ lua_State *L = Luas;
+ if (lang == NULL)
+ return;
+ if (lang->exceptions == 0) {
+ lua_newtable(L);
+ lang->exceptions = luaL_ref(L, LUA_REGISTRYINDEX);
+ }
+ lua_rawgeti(L, LUA_REGISTRYINDEX, lang->exceptions);
+ s = (char *) buffer;
+ while (*s) {
+ while (isspace(*s))
+ s++;
+ if (*s) {
+ value = s;
+ s = clean_hyphenation(s, &cleaned);
+ if (cleaned != NULL) {
+ if ((s - value) > 0) {
+ lua_pushstring(L, cleaned);
+ lua_pushlstring(L, value, (s - value));
+ lua_rawset(L, -3);
+ }
+ free(cleaned);
+ } else {
#ifdef VERBOSE
- fprintf(stderr,"skipping invalid hyphenation exception: %s\n",value);
+ fprintf(stderr, "skipping invalid hyphenation exception: %s\n",
+ value);
#endif
- }
+ }
+ }
}
- }
}
-void
-clear_hyphenation (struct tex_language *lang) {
- if (lang==NULL)
- return;
- if (lang->exceptions!=0) {
- luaL_unref(Luas[0],LUA_REGISTRYINDEX,lang->exceptions);
- lang->exceptions = 0;
- }
+void clear_hyphenation(struct tex_language *lang)
+{
+ if (lang == NULL)
+ return;
+ if (lang->exceptions != 0) {
+ luaL_unref(Luas, LUA_REGISTRYINDEX, lang->exceptions);
+ lang->exceptions = 0;
+ }
}
-void
-load_tex_hyphenation(int curlang, halfword head) {
- char *s = tokenlist_to_cstring (head,1, NULL);
- load_hyphenation(get_language(curlang),(unsigned char *)s);
+void load_tex_hyphenation(int curlang, halfword head)
+{
+ char *s = tokenlist_to_cstring(head, 1, NULL);
+ load_hyphenation(get_language(curlang), (unsigned char *) s);
}
/* TODO: clean this up. The delete_attribute_ref() statements are not very
nice, but needed. Also, in the post-break, it would be nicer to get the
attribute list from vlink(n). No rush, as it is currently not used much. */
-halfword insert_discretionary ( halfword t, halfword pre, halfword post, halfword replace) {
- halfword g, n;
- n = new_node(disc_node,syllable_disc);
- try_couple_nodes(n,vlink(t));
- couple_nodes(t,n);
- for (g=pre;g!=null;g=vlink(g)) {
- font(g)=font(replace);
- if (node_attr(t)!=null) {
- delete_attribute_ref(node_attr(g));
- node_attr(g) = node_attr(t);
- attr_list_ref(node_attr(t)) += 1;
+halfword insert_discretionary(halfword t, halfword pre, halfword post,
+ halfword replace)
+{
+ halfword g, n;
+ int f;
+ n = new_node(disc_node, syllable_disc);
+ try_couple_nodes(n, vlink(t));
+ couple_nodes(t, n);
+ if (replace != null)
+ f = font(replace);
+ else
+ f = get_cur_font(); /* for compound words following explicit hyphens */
+ for (g = pre; g != null; g = vlink(g)) {
+ font(g) = f;
+ if (node_attr(t) != null) {
+ delete_attribute_ref(node_attr(g));
+ node_attr(g) = node_attr(t);
+ attr_list_ref(node_attr(t)) += 1;
+ }
}
- }
- for (g=post;g!=null;g =vlink(g)) {
- font(g)=font(replace);
- if (node_attr(t)!=null) {
- delete_attribute_ref(node_attr(g));
- node_attr(g) = node_attr(t);
- attr_list_ref(node_attr(t)) += 1;
+ for (g = post; g != null; g = vlink(g)) {
+ font(g) = f;
+ if (node_attr(t) != null) {
+ delete_attribute_ref(node_attr(g));
+ node_attr(g) = node_attr(t);
+ attr_list_ref(node_attr(t)) += 1;
+ }
}
- }
- for (g=replace;g!=null;g =vlink(g)) {
- if (node_attr(t)!=null) {
- delete_attribute_ref(node_attr(g));
- node_attr(g) = node_attr(t);
- attr_list_ref(node_attr(t)) += 1;
+ for (g = replace; g != null; g = vlink(g)) {
+ if (node_attr(t) != null) {
+ delete_attribute_ref(node_attr(g));
+ node_attr(g) = node_attr(t);
+ attr_list_ref(node_attr(t)) += 1;
+ }
}
- }
- if (node_attr(t)!=null) {
- delete_attribute_ref(node_attr(vlink(t)));
- node_attr(vlink(t)) = node_attr(t);
- attr_list_ref(node_attr(t)) += 1;
- }
- t = vlink(t);
- set_disc_field(pre_break(t),pre);
- set_disc_field(post_break(t),post);
- set_disc_field(no_break(t),replace);
- return t;
-}
-
-halfword
-insert_syllable_discretionary ( halfword t, lang_variables *lan) {
- halfword g, n;
- n = new_node(disc_node,syllable_disc);
- couple_nodes(n,vlink(t));
- couple_nodes(t,n);
- delete_attribute_ref(node_attr(n));
- if (node_attr(t)!=null) {
- node_attr(n) = node_attr(t);
- attr_list_ref(node_attr(t))++ ;
- } else {
- node_attr(n) = null;
- }
- if (lan->pre_hyphen_char >0) {
- g = raw_glyph_node();
- set_to_character(g);
- character(g)=lan->pre_hyphen_char;
- font(g)=font(t);
- lang_data(g)=lang_data(t);
- if (node_attr(t)!=null) {
- node_attr(g) = node_attr(t);
- attr_list_ref(node_attr(t)) ++;
- }
- set_disc_field(pre_break(n),g);
- }
+ if (node_attr(t) != null) {
+ delete_attribute_ref(node_attr(vlink(t)));
+ node_attr(vlink(t)) = node_attr(t);
+ attr_list_ref(node_attr(t)) += 1;
+ }
+ t = vlink(t);
+ set_disc_field(pre_break(t), pre);
+ set_disc_field(post_break(t), post);
+ set_disc_field(no_break(t), replace);
+ return t;
+}
- if (lan->post_hyphen_char >0) {
- t = vlink(n);
- g = raw_glyph_node();
- set_to_character(g);
- character(g)=lan->post_hyphen_char;
- font(g)=font(t);
- lang_data(g)=lang_data(t);
- if (node_attr(t)!=null) {
- node_attr(g) = node_attr(t);
- attr_list_ref(node_attr(t)) += 1;
- }
- set_disc_field(post_break(n),g);
- }
- return n;
+halfword insert_syllable_discretionary(halfword t, lang_variables * lan)
+{
+ halfword g, n;
+ n = new_node(disc_node, syllable_disc);
+ couple_nodes(n, vlink(t));
+ couple_nodes(t, n);
+ delete_attribute_ref(node_attr(n));
+ if (node_attr(t) != null) {
+ node_attr(n) = node_attr(t);
+ attr_list_ref(node_attr(t))++;
+ } else {
+ node_attr(n) = null;
+ }
+ if (lan->pre_hyphen_char > 0) {
+ g = raw_glyph_node();
+ set_to_character(g);
+ character(g) = lan->pre_hyphen_char;
+ font(g) = font(t);
+ lang_data(g) = lang_data(t);
+ if (node_attr(t) != null) {
+ node_attr(g) = node_attr(t);
+ attr_list_ref(node_attr(t))++;
+ }
+ set_disc_field(pre_break(n), g);
+ }
+
+ if (lan->post_hyphen_char > 0) {
+ t = vlink(n);
+ g = raw_glyph_node();
+ set_to_character(g);
+ character(g) = lan->post_hyphen_char;
+ font(g) = font(t);
+ lang_data(g) = lang_data(t);
+ if (node_attr(t) != null) {
+ node_attr(g) = node_attr(t);
+ attr_list_ref(node_attr(t)) += 1;
+ }
+ set_disc_field(post_break(n), g);
+ }
+ return n;
}
-halfword insert_word_discretionary ( halfword t, lang_variables *lan) {
- halfword pre = null, pos = null;
- if (lan->pre_hyphen_char >0) pre = insert_character ( null, lan->pre_hyphen_char);
- if (lan->post_hyphen_char>0) pos = insert_character ( null, lan->post_hyphen_char);
- return insert_discretionary ( t, pre, pos, null);
+halfword insert_word_discretionary(halfword t, lang_variables * lan)
+{
+ halfword pre = null, pos = null;
+ if (lan->pre_exhyphen_char > 0)
+ pre = insert_character(null, lan->pre_exhyphen_char);
+ if (lan->post_exhyphen_char > 0)
+ pos = insert_character(null, lan->post_exhyphen_char);
+ return insert_discretionary(t, pre, pos, null);
}
-halfword insert_complex_discretionary ( halfword t, lang_variables *lan,
- halfword pre, halfword pos, halfword replace) {
- return insert_discretionary ( t, pre, pos, replace);
+halfword compound_word_break(halfword t, int clang)
+{
+ int disc;
+ lang_variables langdata;
+ langdata.pre_exhyphen_char = get_pre_exhyphen_char(clang);
+ langdata.post_exhyphen_char = get_post_exhyphen_char(clang);
+ disc = insert_word_discretionary(t, &langdata);
+ return disc;
}
-halfword insert_character ( halfword t, int c) {
- halfword p;
- p=new_node(glyph_node,0);
- set_to_character(p);
- character(p)=c;
- if (t!=null) {
- couple_nodes(t,p);
- }
- return p;
+halfword insert_complex_discretionary(halfword t, lang_variables * lan,
+ halfword pre, halfword pos,
+ halfword replace)
+{
+ (void) lan;
+ return insert_discretionary(t, pre, pos, replace);
}
-void
-set_disc_field (halfword f, halfword t) {
- if (t!=null) {
- couple_nodes(f,t);
- tlink(f) = tail_of_list(t);
- }
+halfword insert_character(halfword t, int c)
+{
+ halfword p;
+ p = new_node(glyph_node, 0);
+ set_to_character(p);
+ character(p) = c;
+ if (t != null) {
+ couple_nodes(t, p);
+ }
+ return p;
+}
+
+
+void set_disc_field(halfword f, halfword t)
+{
+ if (t != null) {
+ couple_nodes(f, t);
+ tlink(f) = tail_of_list(t);
+ } else {
+ vlink(f) = null;
+ tlink(f) = null;
+ }
}
-char *hyphenation_exception(int exceptions, char *w) {
- char *ret = NULL;
- lua_State *L = Luas[0];
- lua_checkstack(L,2);
- lua_rawgeti(L,LUA_REGISTRYINDEX,exceptions);
- if (lua_istable(L,-1)) { /* ?? */
- lua_pushstring(L,w); /* word table */
- lua_rawget(L,-2);
- if (lua_isstring(L,-1)) {
- ret = xstrdup((char *)lua_tostring(L,-1));
+char *hyphenation_exception(int exceptions, char *w)
+{
+ char *ret = NULL;
+ lua_State *L = Luas;
+ lua_checkstack(L, 2);
+ lua_rawgeti(L, LUA_REGISTRYINDEX, exceptions);
+ if (lua_istable(L, -1)) { /* ?? */
+ lua_pushstring(L, w); /* word table */
+ lua_rawget(L, -2);
+ if (lua_isstring(L, -1)) {
+ ret = xstrdup((char *) lua_tostring(L, -1));
+ }
+ lua_pop(L, 2);
+ } else {
+ lua_pop(L, 1);
}
- lua_pop(L,2);
- } else {
- lua_pop(L,1);
- }
- return ret;
-}
-
-
-char *exception_strings(struct tex_language *lang) {
- char *value;
- size_t size = 0, current =0;
- size_t l =0;
- char *ret = NULL;
- lua_State *L = Luas[0];
- if (lang->exceptions==0)
- return NULL;
- lua_checkstack(L,2);
- lua_rawgeti(L,LUA_REGISTRYINDEX,lang->exceptions);
- if (lua_istable(L,-1)) {
- /* iterate and join */
- lua_pushnil(L); /* first key */
- while (lua_next(L,-2) != 0) {
- value = (char *)lua_tolstring(L, -1, &l);
- if (current + 2 + l > size ) {
- ret = xrealloc(ret, (1.2*size)+current+l+1024);
- size = (1.2*size)+current+l+1024;
- }
- *(ret+current) = ' ';
- strcpy(ret+current+1,value);
- current += l+1;
- lua_pop(L, 1);
+ return ret;
+}
+
+
+char *exception_strings(struct tex_language *lang)
+{
+ char *value;
+ size_t size = 0, current = 0;
+ size_t l = 0;
+ char *ret = NULL;
+ lua_State *L = Luas;
+ if (lang->exceptions == 0)
+ return NULL;
+ lua_checkstack(L, 2);
+ lua_rawgeti(L, LUA_REGISTRYINDEX, lang->exceptions);
+ if (lua_istable(L, -1)) {
+ /* iterate and join */
+ lua_pushnil(L); /* first key */
+ while (lua_next(L, -2) != 0) {
+ value = (char *) lua_tolstring(L, -1, &l);
+ if (current + 2 + l > size) {
+ ret = xrealloc(ret, (1.2 * size) + current + l + 1024);
+ size = (1.2 * size) + current + l + 1024;
+ }
+ *(ret + current) = ' ';
+ strcpy(ret + current + 1, value);
+ current += l + 1;
+ lua_pop(L, 1);
+ }
}
- }
- return ret;
+ return ret;
}
/* the sequence from |wordstart| to |r| can contain only normal characters */
/* it could be faster to modify a halfword pointer and return an integer */
-halfword find_exception_part(unsigned int *j, int *uword, int len) {
- halfword g = null, gg = null;
- register int i = *j;
- i++; /* this puts uword[i] on the '{' */
- while (i<len && uword[i+1] != '}') {
- if (g==null) {
- gg = new_char(0,uword[i+1]);
- g = gg;
- } else {
- halfword s = new_char(0,uword[i+1]);
- couple_nodes(g,s);
- g = vlink(g);
+halfword find_exception_part(unsigned int *j, int *uword, int len)
+{
+ halfword g = null, gg = null;
+ register int i = *j;
+ i++; /* this puts uword[i] on the '{' */
+ while (i < len && uword[i + 1] != '}') {
+ if (g == null) {
+ gg = new_char(0, uword[i + 1]);
+ g = gg;
+ } else {
+ halfword s = new_char(0, uword[i + 1]);
+ couple_nodes(g, s);
+ g = vlink(g);
+ }
+ i++;
}
- i++;
- }
- *j = ++i;
- return gg;
+ *j = ++i;
+ return gg;
}
-int count_exception_part(unsigned int *j, int *uword, int len) {
- int ret=0;
- register int i = *j;
- i++; /* this puts uword[i] on the '{' */
- while (i<len && uword[i+1] != '}') {
- ret++;
- i++;
- }
- *j = ++i;
- return ret;
-}
-
-
-static char *PAT_ERROR[] = {
- "Exception discretionaries should contain three pairs of braced items.",
- "No intervening spaces are allowed.",
- NULL };
-
-void do_exception (halfword wordstart, halfword r, char *replacement) {
- unsigned i;
- halfword t;
- unsigned len;
- int clang;
- lang_variables langdata;
- int uword[MAX_WORD_LEN+1] = {0};
- (void)utf82u_strcpy((unsigned int *)uword,replacement);
- len = u_strlen((unsigned int *)uword);
- i = 0;
- t=wordstart;
- clang = char_lang(wordstart);
- langdata.pre_hyphen_char = get_pre_hyphen_char(clang);
- langdata.post_hyphen_char = get_post_hyphen_char(clang);
-
- for (i=0;i<len;i++) {
- if (uword[i+1] == '-') { /* a hyphen follows */
- while (vlink(t)!=r && (type(t)!=glyph_node || !is_simple_character(t)))
- t = vlink(t);
- if (vlink(t)==r)
- break;
- insert_syllable_discretionary(t, &langdata);
- t = vlink(t); /* skip the new disc */
- } else if (uword[i+1] == '=') {
- /* do nothing ? */
- t = vlink(t);
- } else if (uword[i+1] == '{') {
- halfword gg, hh, replace = null;
- int repl;
- gg = find_exception_part(&i,uword,len);
- if (i==len || uword[i+1] != '{') {
- tex_error ("broken pattern 1", PAT_ERROR);
- }
- hh = find_exception_part(&i,uword,len);
- if (i==len || uword[i+1] != '{') {
- tex_error ("broken pattern 2", PAT_ERROR);
- }
- repl = count_exception_part(&i,uword,len);
- if (i==len) {
- tex_error ("broken pattern 3", PAT_ERROR);
- }
- /*i++; */ /* jump over the last right brace */
- if (vlink(t)==r)
- break;
- if (repl>0) {
- halfword q = t;
- replace = vlink(q);
- while(repl>0 && q!=null) {
- q=vlink(q);
- if (type(q)==glyph_node) {
- repl--;
- }
- }
- try_couple_nodes(t,vlink(q));
- vlink(q)=null;
- }
- t = insert_discretionary(t,gg,hh,replace);
- } else {
- t = vlink(t);
+int count_exception_part(unsigned int *j, int *uword, int len)
+{
+ int ret = 0;
+ register int i = *j;
+ i++; /* this puts uword[i] on the '{' */
+ while (i < len && uword[i + 1] != '}') {
+ ret++;
+ i++;
+ }
+ *j = ++i;
+ return ret;
+}
+
+
+static char *PAT_ERROR[] = {
+ "Exception discretionaries should contain three pairs of braced items.",
+ "No intervening spaces are allowed.",
+ NULL
+};
+
+void do_exception(halfword wordstart, halfword r, char *replacement)
+{
+ unsigned i;
+ halfword t;
+ unsigned len;
+ int clang;
+ lang_variables langdata;
+ int uword[MAX_WORD_LEN + 1] = { 0 };
+ (void) utf82u_strcpy((unsigned int *) uword, replacement);
+ len = u_strlen((unsigned int *) uword);
+ i = 0;
+ t = wordstart;
+ clang = char_lang(wordstart);
+ langdata.pre_hyphen_char = get_pre_hyphen_char(clang);
+ langdata.post_hyphen_char = get_post_hyphen_char(clang);
+
+ for (i = 0; i < len; i++) {
+ if (uword[i + 1] == '-') { /* a hyphen follows */
+ while (vlink(t) != r
+ && (type(t) != glyph_node || !is_simple_character(t)))
+ t = vlink(t);
+ if (vlink(t) == r)
+ break;
+ insert_syllable_discretionary(t, &langdata);
+ t = vlink(t); /* skip the new disc */
+ } else if (uword[i + 1] == '=') {
+ /* do nothing ? */
+ t = vlink(t);
+ } else if (uword[i + 1] == '{') {
+ halfword gg, hh, replace = null;
+ int repl;
+ gg = find_exception_part(&i, uword, len);
+ if (i == len || uword[i + 1] != '{') {
+ tex_error("broken pattern 1", PAT_ERROR);
+ }
+ hh = find_exception_part(&i, uword, len);
+ if (i == len || uword[i + 1] != '{') {
+ tex_error("broken pattern 2", PAT_ERROR);
+ }
+ repl = count_exception_part(&i, uword, len);
+ if (i == len) {
+ tex_error("broken pattern 3", PAT_ERROR);
+ }
+ /*i++; *//* jump over the last right brace */
+ if (vlink(t) == r)
+ break;
+ if (repl > 0) {
+ halfword q = t;
+ replace = vlink(q);
+ while (repl > 0 && q != null) {
+ q = vlink(q);
+ if (type(q) == glyph_node) {
+ repl--;
+ }
+ }
+ try_couple_nodes(t, vlink(q));
+ vlink(q) = null;
+ }
+ t = insert_discretionary(t, gg, hh, replace);
+ t = vlink(t); /* skip the new disc */
+ } else {
+ t = vlink(t);
+ }
}
- }
}
/* This is a documentation section from the pascal web file. It is not
@@ -554,276 +735,299 @@ using an algorithm due to Frank~M. Liang.
/*
* This is incompatible with TEX because the first word of a paragraph
* can be hyphenated, but most european users seem to agree that
- * prohibiting hyphenation there was not a the best idea ever.
+ * prohibiting hyphenation there was not the best idea ever.
*/
-halfword find_next_wordstart(halfword r) {
- register int l;
- register int start_ok = 1;
- int mathlevel = 1;
- while (r!=null) {
- switch (type(r)) {
- case glue_node:
- start_ok = 1;
- break;
- case math_node:
- while (mathlevel>0 ){
- r = vlink(r);
- if (r==null)
- return r;
- if (type(r)==math_node) {
- if (subtype(r)==before) {
- mathlevel++;
- } else {
- mathlevel--;
- }
- }
- }
- break;
- case glyph_node:
- if (start_ok &&
- is_simple_character(r) &&
- (l = get_lc_code(character(r)))>0 &&
- (char_uchyph(r) || l == character(r)))
- return r;
- /* fall through */
- default:
- start_ok = 0;
- break;
- }
- r = vlink(r);
- }
- return r;
-}
-
-int valid_wordend( halfword s) {
- register halfword r = s;
- register int clang = char_lang(s);
- if (r==null)
- return 1;
- while ((r!=null) &&
- ((type(r)==glyph_node && is_simple_character(r) && clang == char_lang(r)) ||
- (type(r)==kern_node && subtype(r)==normal))) {
- r = vlink(r);
- }
- if (r==null ||
- (type(r)==glyph_node && is_simple_character(r) && clang != char_lang(r)) ||
- type(r)==glue_node ||
- type(r)==whatsit_node ||
- type(r)==ins_node ||
- type(r)==adjust_node ||
- type(r)==penalty_node ||
- (type(r)==kern_node && subtype(r)==explicit))
- return 1;
- return 0;
-}
-
-void
-hnj_hyphenation (halfword head, halfword tail) {
- int lchar, i;
- struct tex_language* lang;
- lang_variables langdata;
- char utf8word[(4*MAX_WORD_LEN)+1] = {0};
- int wordlen = 0;
- char *hy = utf8word;
- char *replacement = NULL;
- halfword s, r = head, wordstart = null, save_tail = null, left = null, right = null;
-
- /* this first movement assures two things:
- * a) that we won't waste lots of time on something that has been
- * handled already (in that case, none of the glyphs match |simple_character|).
- * b) that the first word can be hyphenated. if the movement was
- * not explicit, then the indentation at the start of a paragraph
- * list would make find_next_wordstart() look too far ahead.
- */
-
- while (r!=null && (type(r)!=glyph_node || !is_simple_character(r)))
- r =vlink(r);
- /* this will make |r| a glyph node with subtype_character */
- r = find_next_wordstart(r);
- if (r==null)
- return;
-
- assert (tail!=null);
- save_tail = vlink(tail);
- s = new_penalty(0);
- couple_nodes(tail, s);
-
- while (r!=null) { /* could be while(1), but let's be paranoid */
- int clang, lhmin, rhmin;
- wordstart = r;
- assert (is_simple_character(wordstart));
- clang = char_lang(wordstart);
- lhmin = char_lhmin(wordstart);
- rhmin = char_rhmin(wordstart);
- langdata.pre_hyphen_char = get_pre_hyphen_char(clang);
- langdata.post_hyphen_char = get_post_hyphen_char(clang);
- while (r!=null &&
- type(r)==glyph_node &&
- is_simple_character(r) &&
- clang == char_lang(r) &&
- (lchar = get_lc_code(character(r)))>0) {
- wordlen++;
- hy = utf8_idpb(hy,character(r));
- /* this should not be needed any more */
- /*if (vlink(r)!=null) alink(vlink(r))=r;*/
- r = vlink(r);
- }
- if (valid_wordend(r) && wordlen>=lhmin+rhmin && (lang=tex_languages[clang])!=NULL) {
- *hy=0;
- if (lang->exceptions!=0 &&
- (replacement = hyphenation_exception(lang->exceptions,utf8word))!=NULL) {
+halfword find_next_wordstart(halfword r)
+{
+ register int l;
+ register int start_ok = 1;
+ int mathlevel = 1;
+ while (r != null) {
+ switch (type(r)) {
+ case glue_node:
+ start_ok = 1;
+ break;
+ case math_node:
+ while (mathlevel > 0) {
+ r = vlink(r);
+ if (r == null)
+ return r;
+ if (type(r) == math_node) {
+ if (subtype(r) == before) {
+ mathlevel++;
+ } else {
+ mathlevel--;
+ }
+ }
+ }
+ break;
+ case glyph_node:
+ if (start_ok &&
+ is_simple_character(r) &&
+ (l = get_lc_code(character(r))) > 0 &&
+ (char_uchyph(r) || l == character(r)))
+ return r;
+ break;
+ default:
+ start_ok = 0;
+ break;
+ }
+ r = vlink(r);
+ }
+ return r;
+}
+
+int valid_wordend(halfword s)
+{
+ register halfword r = s;
+ register int clang = char_lang(s);
+ if (r == null)
+ return 1;
+ while ((r != null) && ((type(r) == glyph_node && is_simple_character(r)
+ && clang == char_lang(r)) || (type(r) == kern_node
+ && subtype(r) ==
+ normal))) {
+ r = vlink(r);
+ }
+ if (r == null || (type(r) == glyph_node && is_simple_character(r)
+ && clang != char_lang(r)) || type(r) == glue_node
+ || type(r) == whatsit_node || type(r) == ins_node
+ || type(r) == adjust_node || type(r) == penalty_node
+ || (type(r) == kern_node && subtype(r) == explicit))
+ return 1;
+ return 0;
+}
+
+void hnj_hyphenation(halfword head, halfword tail)
+{
+ int lchar, i;
+ struct tex_language *lang;
+ lang_variables langdata;
+ char utf8word[(4 * MAX_WORD_LEN) + 1] = { 0 };
+ int wordlen = 0;
+ char *hy = utf8word;
+ char *replacement = NULL;
+ halfword s, r = head, wordstart = null, save_tail = null, left =
+ null, right = null;
+
+ /* this first movement assures two things:
+ * a) that we won't waste lots of time on something that has been
+ * handled already (in that case, none of the glyphs match |simple_character|).
+ * b) that the first word can be hyphenated. if the movement was
+ * not explicit, then the indentation at the start of a paragraph
+ * list would make find_next_wordstart() look too far ahead.
+ */
+
+ while (r != null && (type(r) != glyph_node || !is_simple_character(r))) {
+ r = vlink(r);
+ }
+ /* this will make |r| a glyph node with subtype_character */
+ r = find_next_wordstart(r);
+ if (r == null)
+ return;
+
+ assert(tail != null);
+ save_tail = vlink(tail);
+ s = new_penalty(0);
+ couple_nodes(tail, s);
+
+ while (r != null) { /* could be while(1), but let's be paranoid */
+ int clang, lhmin, rhmin;
+ halfword hyf_font;
+ halfword end_word = r;
+ wordstart = r;
+ assert(is_simple_character(wordstart));
+ hyf_font = font(wordstart);
+ if (hyphen_char(hyf_font)<0) /* for backward compat */
+ hyf_font = 0;
+ clang = char_lang(wordstart);
+ lhmin = char_lhmin(wordstart);
+ rhmin = char_rhmin(wordstart);
+ langdata.pre_hyphen_char = get_pre_hyphen_char(clang);
+ langdata.post_hyphen_char = get_post_hyphen_char(clang);
+ while (r != null &&
+ type(r) == glyph_node &&
+ is_simple_character(r) &&
+ clang == char_lang(r) &&
+ (lchar = get_lc_code(character(r))) > 0) {
+ wordlen++;
+ hy = utf8_idpb(hy, character(r));
+ /* this should not be needed any more */
+ /*if (vlink(r)!=null) alink(vlink(r))=r; */
+ end_word = r;
+ r = vlink(r);
+ }
+ if (valid_wordend(r) && wordlen >= lhmin + rhmin
+ && (hyf_font != 0) && (lang = tex_languages[clang]) != NULL) {
+ *hy = 0;
+ if (lang->exceptions != 0 &&
+ (replacement =
+ hyphenation_exception(lang->exceptions, utf8word)) != NULL) {
#ifdef VERBOSE
- fprintf(stderr,"replacing %s (c=%d) by %s\n",utf8word,clang,replacement);
-#endif
- do_exception(wordstart,r,replacement);
- free(replacement);
- } else if (lang->patterns!=NULL) {
-
- left = wordstart;
- for (i=lhmin;i>1;i--) {
- left = vlink(left);
- while (!is_simple_character(left))
- left = vlink(left);
- }
- right = r;
- for (i=rhmin;i>0;i--) {
- right = alink(right);
- while (!is_simple_character(right))
- right = alink(right);
- }
-
+ fprintf(stderr, "replacing %s (c=%d) by %s\n", utf8word, clang,
+ replacement);
+#endif
+ do_exception(wordstart, r, replacement);
+ free(replacement);
+ } else if (lang->patterns != NULL) {
+
+ left = wordstart;
+ for (i = lhmin; i > 1; i--) {
+ left = vlink(left);
+ while (!is_simple_character(left))
+ left = vlink(left);
+ }
+ right = r;
+ for (i = rhmin; i > 0; i--) {
+ right = alink(right);
+ while (!is_simple_character(right))
+ right = alink(right);
+ }
+
#ifdef VERBOSE
- fprintf(stderr,"hyphenate %s (c=%d,l=%d,r=%d) from %c to %c\n",utf8word,
- clang,lhmin,rhmin,
- character(left), character(right));
-#endif
- (void)hnj_hyphen_hyphenate(lang->patterns,wordstart,r,wordlen,left,right, &langdata);
- }
- }
- wordlen = 0;
- hy = utf8word;
- if (r==null)
- break;
- r = find_next_wordstart(r);
- }
- flush_node(vlink(tail));
- vlink(tail) = save_tail;
-}
-
-
-void
-new_hyphenation (halfword head, halfword tail) {
- register int callback_id = 0;
- if (head==null || vlink(head)==null)
- return;
- fix_node_list (head); /* TODO: use couple_nodes() in append_tail()!*/
- callback_id = callback_defined(hyphenate_callback);
- if (callback_id>0) {
- lua_State *L = Luas[0];
- lua_rawgeti(L,LUA_REGISTRYINDEX,callback_callbacks_id);
- lua_rawgeti(L,-1, callback_id);
- if (!lua_isfunction(L,-1)) {
- lua_pop(L,2);
- return;
- }
- nodelist_to_lua(L,head);
- nodelist_to_lua(L,tail);
- if (lua_pcall(L,2,0,0) != 0) {
- fprintf(stdout,"error: %s\n",lua_tostring(L,-1));
- lua_pop(L,2);
- lua_error(L);
- return;
- }
- lua_pop(L,1);
- } else {
- hnj_hyphenation(head,tail);
- }
+ fprintf(stderr, "hyphenate %s (c=%d,l=%d,r=%d) from %c to %c\n",
+ utf8word, clang, lhmin, rhmin, character(left),
+ character(right));
+#endif
+ (void) hnj_hyphen_hyphenate(lang->patterns, wordstart, end_word,
+ wordlen, left, right, &langdata);
+ }
+ }
+ wordlen = 0;
+ hy = utf8word;
+ if (r == null)
+ break;
+ r = find_next_wordstart(r);
+ }
+ flush_node(vlink(tail));
+ vlink(tail) = save_tail;
+}
+
+
+void new_hyphenation(halfword head, halfword tail)
+{
+ register int callback_id = 0;
+ if (head == null || vlink(head) == null)
+ return;
+ fix_node_list(head); /* TODO: use couple_nodes() in append_tail()! */
+ callback_id = callback_defined(hyphenate_callback);
+ if (callback_id > 0) {
+ lua_State *L = Luas;
+ if (!get_callback(L, callback_id)) {
+ lua_pop(L, 2);
+ return;
+ }
+ nodelist_to_lua(L, head);
+ nodelist_to_lua(L, tail);
+ if (lua_pcall(L, 2, 0, 0) != 0) {
+ fprintf(stdout, "error: %s\n", lua_tostring(L, -1));
+ lua_pop(L, 2);
+ lua_error(L);
+ return;
+ }
+ lua_pop(L, 1);
+ } else {
+ hnj_hyphenation(head, tail);
+ }
}
/* dumping and undumping fonts */
-#define dump_string(a) \
- if (a!=NULL) { \
- x = strlen(a)+1; \
- dump_int(x); dump_things(*a, x); \
- } else { \
- x = 0; dump_int(x); \
+#define dump_string(a) \
+ if (a!=NULL) { \
+ x = strlen(a)+1; \
+ dump_int(x); dump_things(*a, x); \
+ } else { \
+ x = 0; dump_int(x); \
}
-void dump_one_language (int i) {
- char *s = NULL;
- unsigned x = 0;
- struct tex_language *lang;
- lang = tex_languages[i];
- dump_int(lang->id);
- dump_int(lang->pre_hyphen_char);
- dump_int(lang->post_hyphen_char);
- if (lang->patterns!=NULL) {
- s = (char *)hnj_serialize(lang->patterns);
- }
- dump_string(s);
- if (s!=NULL) {
- free(s);
- s = NULL;
- }
- if (lang->exceptions!=0)
- s = exception_strings(lang);
- dump_string(s);
- if (s!=NULL) {
- free(s);
- }
- free (lang);
+void dump_one_language(int i)
+{
+ char *s = NULL;
+ unsigned x = 0;
+ struct tex_language *lang;
+ lang = tex_languages[i];
+ dump_int(lang->id);
+ dump_int(lang->pre_hyphen_char);
+ dump_int(lang->post_hyphen_char);
+ dump_int(lang->pre_exhyphen_char);
+ dump_int(lang->post_exhyphen_char);
+ if (lang->patterns != NULL) {
+ s = (char *) hnj_serialize(lang->patterns);
+ }
+ dump_string(s);
+ if (s != NULL) {
+ free(s);
+ s = NULL;
+ }
+ if (lang->exceptions != 0)
+ s = exception_strings(lang);
+ dump_string(s);
+ if (s != NULL) {
+ free(s);
+ }
+ free(lang);
}
-void dump_language_data (void) {
- int i;
- dump_int(next_lang_id);
- for (i=0;i<next_lang_id;i++) {
- if (tex_languages[i]) {
- dump_int(1);
- dump_one_language(i);
- } else {
- dump_int(0);
+void dump_language_data(void)
+{
+ int i;
+ dump_int(next_lang_id);
+ for (i = 0; i < next_lang_id; i++) {
+ if (tex_languages[i]) {
+ dump_int(1);
+ dump_one_language(i);
+ } else {
+ dump_int(0);
+ }
}
- }
}
-void undump_one_language (int i) {
- char *s = NULL;
- unsigned x = 0;
- struct tex_language *lang = get_language(i);
- undump_int(x); lang->id = x;
- undump_int(x); lang->pre_hyphen_char = x;
- undump_int(x); lang->post_hyphen_char = x;
- /* patterns */
- undump_int (x);
- if (x>0) {
- s = xmalloc(x);
- undump_things(*s,x);
- load_patterns(lang,(unsigned char *)s);
- free(s);
- }
- /* exceptions */
- undump_int (x);
- if (x>0) {
- s = xmalloc(x);
- undump_things(*s,x);
- load_hyphenation(lang,(unsigned char *)s);
- free(s);
- }
-}
-
-void undump_language_data (void) {
- unsigned i, x, numlangs;
- undump_int(numlangs);
- for (i=0;i<numlangs;i++) {
+void undump_one_language(int i)
+{
+ char *s = NULL;
+ unsigned x = 0;
+ struct tex_language *lang = get_language(i);
+ undump_int(x);
+ lang->id = x;
+ undump_int(x);
+ lang->pre_hyphen_char = x;
undump_int(x);
- if (x==1) {
- undump_one_language(i);
+ lang->post_hyphen_char = x;
+ undump_int(x);
+ lang->pre_exhyphen_char = x;
+ undump_int(x);
+ lang->post_exhyphen_char = x;
+ /* patterns */
+ undump_int(x);
+ if (x > 0) {
+ s = xmalloc(x);
+ undump_things(*s, x);
+ load_patterns(lang, (unsigned char *) s);
+ free(s);
+ }
+ /* exceptions */
+ undump_int(x);
+ if (x > 0) {
+ s = xmalloc(x);
+ undump_things(*s, x);
+ load_hyphenation(lang, (unsigned char *) s);
+ free(s);
}
- }
}
+void undump_language_data(void)
+{
+ unsigned i, x, numlangs;
+ undump_int(numlangs);
+ next_lang_id = numlangs;
+ for (i = 0; i < numlangs; i++) {
+ undump_int(x);
+ if (x == 1) {
+ undump_one_language(i);
+ }
+ }
+}