~ubuntu-branches/ubuntu/jaunty/luatex/jaunty

« back to all changes in this revision

Viewing changes to src/texk/web2c/luatexdir/lang/hyphen.c

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Preining
  • Date: 2007-12-10 10:24:34 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20071210102434-9w9ljypghznwb4dy
Tags: 0.20.1-1
* new upstreams, add the announcements with changes to the debian dir
* call build.sh.linux with bash, not with sh, otherwise building breaks
  (thanks to Pascal de Bruijn <pmjdebruijn@gmail.com> from Ubuntu for
  letting us know) [np]
* update libpoppler patch
* change the texdoclua patch to use the new os.tmpdir with a template of
  /tmp/luatex.XXXXXX
* bump standards version to 3.7.3, no changes necessary
* convert copyright file to utf-8

Show diffs side-by-side

added added

removed removed

Lines of Context:
48
48
 
49
49
#include <ctype.h>
50
50
 
51
 
//#define VERBOSE
 
51
/*#define VERBOSE*/
52
52
 
53
53
#include "hnjalloc.h"
54
54
#include "hyphen.h"
74
74
  return 0;
75
75
}
76
76
 
77
 
// --------------------------------------------------------------------
78
 
//
79
 
// Type definitions
80
 
//
81
 
// --------------------------------------------------------------------
 
77
/* --------------------------------------------------------------------
 
78
 *
 
79
 * Type definitions
 
80
 *
 
81
 * --------------------------------------------------------------------
 
82
 */
82
83
 
83
84
/* a little bit of a hash table implementation. This simply maps strings
84
85
   to state numbers */
130
131
 
131
132
struct _HyphenState {
132
133
  char *match;
133
 
//char *repl;
134
 
//signed char replindex;
135
 
//signed char replcut;
 
134
  /*char *repl;*/
 
135
  /*signed char replindex;*/
 
136
  /*signed char replcut;*/
136
137
  int fallback_state;
137
138
  int num_trans;
138
139
  HyphenTrans *trans;
144
145
};
145
146
 
146
147
 
147
 
// Combine two right-aligned number patterns, 04000 + 020 becomes 04020
 
148
/* Combine two right-aligned number patterns, 04000 + 020 becomes 04020*/
148
149
static char *combine(
149
150
  char *expr,
150
151
  const char *subexpr
153
154
  int l2 = strlen(subexpr);
154
155
  int off = l1-l2;
155
156
  int j;
156
 
  // this works also for utf8 sequences because the substring is identical
157
 
  // to the last substring-length bytes of expr except for the (single byte)
158
 
  // hyphenation encoders
 
157
  /* this works also for utf8 sequences because the substring is identical
 
158
   * to the last substring-length bytes of expr except for the (single byte)
 
159
   * hyphenation encoders
 
160
   */
159
161
  for (j=0; j<l2; j++) {
160
162
    if (expr[off+j]<subexpr[j]) expr[off+j] = subexpr[j];
161
163
  }
163
165
}
164
166
 
165
167
 
166
 
// --------------------------------------------------------------------
167
 
// ORIGINAL CODE
168
 
// --------------------------------------------------------------------
169
 
 
170
 
 
171
 
//
172
 
//
 
168
/* --------------------------------------------------------------------
 
169
 * ORIGINAL CODE
 
170
 * --------------------------------------------------------------------
 
171
 */
 
172
 
173
173
HashIter* new_HashIter(
174
174
  HashTab* h
175
175
) {
181
181
}
182
182
 
183
183
 
184
 
//
185
 
//
186
184
int nextHashStealPattern(
187
185
  HashIter*i,
188
186
  unsigned char**word,
200
198
}
201
199
 
202
200
 
203
 
//
204
 
//
205
201
int nextHash(
206
202
  HashIter*i,
207
203
  unsigned char**word
216
212
}
217
213
 
218
214
 
219
 
//
220
 
//
221
215
int eachHash(
222
216
  HashIter*i,
223
217
  unsigned char**word,
234
228
}
235
229
 
236
230
 
237
 
//
238
 
//
239
231
void delete_HashIter(
240
232
  HashIter*i
241
233
) {
243
235
}
244
236
 
245
237
 
246
 
//
247
 
//
248
238
/* a char* hash function from ASU - adapted from Gtk+ */
249
239
static unsigned int hnj_string_hash (
250
240
  const unsigned char *s
263
253
}
264
254
 
265
255
 
266
 
//
267
256
/* assumes that key is not already present! */
268
257
static void state_insert(
269
258
  HashTab *hashtab,
282
271
}
283
272
 
284
273
 
285
 
//
286
274
/* assumes that key is not already present! */
287
275
static void hyppat_insert(
288
276
  HashTab *hashtab,
309
297
}
310
298
 
311
299
 
312
 
//
313
300
/* return state if found, otherwise -1 */
314
301
static int state_lookup(
315
302
  HashTab *hashtab,
328
315
}
329
316
 
330
317
 
331
 
//
332
318
/* return state if found, otherwise -1 */
333
319
static char* hyppat_lookup(
334
320
  HashTab *hashtab,
337
323
) {
338
324
  int i;
339
325
  HashEntry *e;
340
 
  unsigned char key[128]; // should be ample
 
326
  unsigned char key[128]; /* should be ample*/
341
327
  strncpy((char*)key,(char*)chars,l); key[l]=0;
342
328
  i = hnj_string_hash (key) % HASH_SIZE;
343
329
  for (e = hashtab->entries[i]; e; e = e->next) {
349
335
}
350
336
 
351
337
 
352
 
//
353
338
/* Get the state number, allocating a new state if necessary. */
354
339
static int hnj_get_state(
355
340
  HyphenDict *dict,
376
361
}
377
362
 
378
363
 
379
 
//
380
364
/* add a transition from state1 to state2 through ch - assumes that the
381
365
   transition does not already exist */
382
366
static void hnj_add_trans(
407
391
 
408
392
#ifdef VERBOSE
409
393
 
410
 
//
411
 
//
412
394
static unsigned char *get_state_str(
413
395
  int state
414
396
) {
448
430
  return *length ? here : NULL; /* zero sensed */
449
431
}
450
432
 
451
 
//
452
 
//
453
433
static void init_hash(
454
434
  HashTab**h
455
435
) {
460
440
}
461
441
 
462
442
 
463
 
//
464
 
//
465
443
static void clear_state_hash(
466
444
  HashTab**h
467
445
) {
480
458
}
481
459
 
482
460
 
483
 
//
484
 
//
485
461
static void clear_hyppat_hash(
486
462
  HashTab**h
487
463
) {
501
477
}
502
478
 
503
479
 
504
 
//
505
 
//
506
480
static void init_dict(
507
481
  HyphenDict* dict
508
482
) {
520
494
}
521
495
 
522
496
 
523
 
//
524
 
//
525
497
static void clear_dict(
526
498
  HyphenDict* dict
527
499
) {
538
510
}
539
511
 
540
512
 
541
 
// used by hyphnate
542
 
// NB: we 'loose' this memory as it is never freed
543
 
static halfword begin = null;
544
 
static halfword end   = null;
545
513
 
546
 
//
547
 
//
548
514
HyphenDict* hnj_hyphen_new() {
549
515
  HyphenDict* dict = hnj_malloc (sizeof(HyphenDict));
550
516
  init_dict(dict);
551
 
  if (begin==null) begin = insert_character(null,(int)'.');
552
 
  if (end  ==null) end   = insert_character(null,(int)'.');
553
517
  return dict;
554
518
}
555
519
 
556
520
 
557
 
//
558
 
//
559
521
void hnj_hyphen_clear(
560
522
  HyphenDict* dict
561
523
) {
564
526
}
565
527
 
566
528
 
567
 
//
568
 
//
569
529
void hnj_hyphen_free(
570
530
  HyphenDict *dict
571
531
) {
573
533
  hnj_free(dict);
574
534
}
575
535
 
576
 
//
577
 
//
578
536
unsigned char* hnj_serialize(
579
537
  HyphenDict* dict
580
538
) {
600
558
}
601
559
 
602
560
 
603
 
//
604
 
//
605
561
void hnj_free_serialize(
606
562
  unsigned char* c
607
563
) {
609
565
}
610
566
 
611
567
 
612
 
// hyphenation pattern:
613
 
// signed bytes
614
 
// 0 indicates end (actually any negative number)
615
 
// : prio(1+),startpos,length,len1,[replace],len2,[replace]
616
 
// most basic example is:
617
 
//  p n 0 0 0
618
 
// for a hyphenation point between characters
619
 
 
620
 
//
621
 
//
 
568
/* hyphenation pattern:
 
569
 * signed bytes
 
570
 * 0 indicates end (actually any negative number)
 
571
 * : prio(1+),startpos,length,len1,[replace],len2,[replace]
 
572
 * most basic example is:
 
573
 *  p n 0 0 0
 
574
 * for a hyphenation point between characters
 
575
 */
 
576
 
 
577
 
622
578
void hnj_hyphen_load(
623
579
  HyphenDict* dict,
624
580
  const unsigned char *f
634
590
  size_t l = 0;
635
591
 
636
592
 
637
 
//***************************************
 
593
  /***************************************/
638
594
 
639
595
  const unsigned char* format;
640
596
  const unsigned char* begin = f;
641
597
  while((format = next_pattern(&l,&f))!=NULL) {
642
598
    int i,j,e;
643
 
    //printf("%s\n",format);
644
599
    /*
 
600
    printf("%s\n",format);
645
601
    char* repl = strnchr(format, '/',l);
646
602
    int replindex = 0;
647
603
    int replcut = 0;
657
613
        }
658
614
      } else {
659
615
        hnj_strchomp(repl + 1);
660
 
//      replindex = 0;
 
616
                replindex = 0;
661
617
        replcut = strlen(buf);
662
618
      }
663
619
      repl = hnj_strdup(repl + 1);
667
623
      if (format[i]>='0'&&format[i]<='9') j++;
668
624
      if (is_utf8_follow(format[i])) e++;
669
625
    }
670
 
    // l-e   => number of _characters_ not _bytes_
671
 
    // l-e-j => number of pattern characters
 
626
    /* l-e   => number of _characters_ not _bytes_*/
 
627
    /* l-e-j => number of pattern characters*/
672
628
    unsigned char *pat = (unsigned char*) malloc(1+l-j);
673
629
             char *org = (         char*) malloc(2+l-e-j);
674
 
    // remove hyphenation encoders (digits) from pat
 
630
                         /* remove hyphenation encoders (digits) from pat*/
675
631
    org[0] = '0';
676
632
    for (i=0,j=0,e=0; i<l; i++) {
677
633
      unsigned char c = format[i];
688
644
    org[j+1] = 0;
689
645
    hyppat_insert(dict->patterns,pat,org);
690
646
  }
691
 
  dict->pat_length += (f-begin)+2; // 2 for spurious spaces
 
647
  dict->pat_length += (f-begin)+2; /* 2 for spurious spaces*/
692
648
  init_hash(&dict->merged);
693
649
  v = new_HashIter(dict->patterns);
694
650
  while (nextHash(v,&word)) {
695
651
    int   wordsize = strlen((char*)word);
696
652
    int   j,l;
697
653
    for (l=1; l<=wordsize; l++) {
698
 
      if (is_utf8_follow(word[l])) continue; // Do not clip an utf8 sequence
 
654
      if (is_utf8_follow(word[l])) continue; /* Do not clip an utf8 sequence*/
699
655
      for (j=1; j<=l; j++) {
700
656
        int i = l-j;
701
 
        if (is_utf8_follow(word[i])) continue; // Do not start halfway an utf8 sequence
 
657
        if (is_utf8_follow(word[i])) continue; /* Do not start halfway an utf8 sequence*/
702
658
        char *subpat_pat;
703
659
        if ((subpat_pat = hyppat_lookup(dict->patterns,word+i,j))!=NULL) {
704
660
          char* newpat_pat;
708
664
            int e=0;
709
665
            for (i=0; i<l; i++) if (is_utf8_follow(newword[i])) e++;
710
666
            char *neworg = malloc(l+2-e);
711
 
            sprintf(neworg,"%0*d",l+1-e,0); // fill with right amount of '0'
 
667
            sprintf(neworg,"%0*d",l+1-e,0); /* fill with right amount of '0'*/
712
668
            hyppat_insert(dict->merged,newword,combine(neworg,subpat_pat));
713
669
          } else {
714
670
            combine(newpat_pat,subpat_pat);
754
710
  delete_HashIter(v);
755
711
  clear_hyppat_hash(&dict->merged);
756
712
 
757
 
//***************************************
 
713
  /***************************************/
758
714
 
759
715
  /* put in the fallback states */
760
716
  for (i = 0; i < HASH_SIZE; i++) {
761
717
    for (e = dict->state_num->entries[i]; e; e = e->next) {
762
 
      // do not do state==0 otherwise things get confused
 
718
      /* do not do state==0 otherwise things get confused*/
763
719
      if (e->u.state) {
764
720
        for (j = 1; 1; j++) {
765
721
          state_num = state_lookup(dict->state_num, e->key + j);
785
741
}
786
742
 
787
743
 
788
 
//
789
 
//
790
744
void hnj_hyphen_hyphenate(
791
745
  HyphenDict *dict,
792
746
  halfword first,
796
750
  halfword right,
797
751
  lang_variables *lan
798
752
) {
799
 
  // +2 for dots at each end, +1 for points /outside/ characters
 
753
  /* +2 for dots at each end, +1 for points /outside/ characters*/
800
754
  int ext_word_len = length+2;
801
755
  int hyphen_len   = ext_word_len+1;
802
 
//char *hyphens = hnj_malloc((hyphen_len*2)+1); // LATER
 
756
  /*char *hyphens = hnj_malloc((hyphen_len*2)+1); */ /* LATER */
803
757
  char *hyphens = hnj_malloc(hyphen_len+1);
804
758
 
805
 
  // Add a '.' to beginning and end to facilitate matching
806
 
  set_vlink(begin,first);
807
 
  set_vlink(end,get_vlink(last));
808
 
  set_vlink(last,end);
 
759
  /* Add a '.' to beginning and end to facilitate matching*/
 
760
  set_vlink(begin_point,first);
 
761
  set_vlink(end_point,get_vlink(last));
 
762
  set_vlink(last,end_point);
809
763
 
810
764
  int char_num;
811
765
  for (char_num = 0; char_num < hyphen_len; char_num++) {
812
 
//  hyphens[char_num*2] = '0';    // LATER
813
 
//  hyphens[char_num*2+1] = '0';    // LATER
 
766
        /*  hyphens[char_num*2] = '0';    */ /* LATER */
 
767
        /*  hyphens[char_num*2+1] = '0';    */ /* LATER */
814
768
    hyphens[char_num] = '0';    
815
769
  }
816
 
//hyphens[hyphen_len*2] = 0;  // LATER
 
770
  /*hyphens[hyphen_len*2] = 0;  */ /* LATER */
817
771
  hyphens[hyphen_len] = 0;
818
772
 
819
773
  /* now, run the finite state machine */
820
774
  int state = 0;
821
775
  halfword here;
822
 
  for (char_num=0, here=begin; here!=end; here=get_vlink(here)) {
 
776
  for (char_num=0, here=begin_point; here!=end_point; here=get_vlink(here)) {
823
777
 
824
778
    int ch = get_character(here);
825
779
 
826
780
    while (state!=-1) {
827
 
//+   printf("%*s%s%c",char_num-strlen(get_state_str(state)),"",get_state_str(state),(char)ch);
 
781
          /*   printf("%*s%s%c",char_num-strlen(get_state_str(state)),"",get_state_str(state),(char)ch);*/
828
782
      HyphenState *hstate = &dict->states[state];
829
783
      int k;
830
784
      for (k = 0; k < hstate->num_trans; k++) {
831
785
        if (hstate->trans[k].uni_ch == ch) {
832
786
          state = hstate->trans[k].new_state;
833
 
//+       printf(" state %d\n",state);
 
787
                  /*       printf(" state %d\n",state);*/
834
788
          char *match = dict->states[state].match;
835
789
          if (match) {
836
 
            // +2 because:
837
 
            //  1 string length is one bigger than offset
838
 
            //  1 hyphenation starts before first character
 
790
            /* +2 because:
 
791
                         *  1 string length is one bigger than offset
 
792
                         *  1 hyphenation starts before first character
 
793
                         */
839
794
            int offset = char_num + 2 - strlen (match);
840
 
//+         printf ("%*s%s\n", offset,"", match);
 
795
                        /*         printf ("%*s%s\n", offset,"", match);*/
841
796
            int m;
842
797
            for (m = 0; match[m]; m++) {
843
798
              if (hyphens[offset+m] < match[m]) hyphens[offset+m] = match[m];
847
802
        }
848
803
      }
849
804
      state = hstate->fallback_state;
850
 
//+   printf (" back to %d\n", state);
 
805
          /*   printf (" back to %d\n", state);*/
851
806
    }
852
 
    // nothing worked, let's go to the next character
 
807
    /* nothing worked, let's go to the next character*/
853
808
    state = 0;
854
809
try_next_letter: ;
855
810
    char_num++;
856
811
  }
857
812
 
858
 
  // restore the correct pointers
859
 
  set_vlink(last,get_vlink(end));
 
813
  /* restore the correct pointers*/
 
814
  set_vlink(last,get_vlink(end_point));
860
815
 
861
 
  // pattern is ^.^w^o^r^d^.^   word_len=4, ext_word_len=6, hyphens=7
862
 
  // check          ^ ^ ^       so drop first two and stop after word_len-1
 
816
  /* pattern is ^.^w^o^r^d^.^   word_len=4, ext_word_len=6, hyphens=7
 
817
   * check          ^ ^ ^       so drop first two and stop after word_len-1
 
818
   */
863
819
  for (here=first,char_num=2; here!=left; here=get_vlink(here)) char_num++;
864
820
  for (; here!=right; here=get_vlink(here)) {
865
821
    if (hyphens[char_num] & 1)