~ubuntu-branches/debian/squeeze/sword/squeeze

« back to all changes in this revision

Viewing changes to src/frontend/im/hebrewmcim.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Glassey
  • Date: 2004-01-15 15:50:07 UTC
  • Revision ID: james.westby@ubuntu.com-20040115155007-n9mz4x0zxrs1isd3
Tags: upstream-1.5.7
ImportĀ upstreamĀ versionĀ 1.5.7

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/**
 
3
 * Title: Keyboard mapping for Michigan-Claremont Hebrew input
 
4
 * Description:
 
5
 * Copyright:    Copyright (c) 2001 CrossWire Bible Society under the terms of the GNU GPL
 
6
 * Company:
 
7
 * @author Troy A. Griffitts
 
8
 * @version 1.0
 
9
 */
 
10
 
 
11
#include <hebrewmcim.h>
 
12
 
 
13
HebrewMCIM::HebrewMCIM()
 
14
                :SWInputMethod() {
 
15
 
 
16
   init();
 
17
}
 
18
 
 
19
 
 
20
int *HebrewMCIM::translate(char in) {
 
21
        int retVal = 0;
 
22
        static int retString[5];
 
23
        int retStringIndex = 0;
 
24
 
 
25
        memset(retString, 0, 5);
 
26
 
 
27
        if (getState() > 1) {
 
28
                if (getState() >= 12) { // serious issue with internal structure
 
29
                        setState(0);
 
30
                        retString[retStringIndex++] = in;
 
31
                        return retString;
 
32
                }
 
33
                map<int, int>::iterator find = subst2[getState()].find(in);
 
34
                if (find != subst2[getState()].end())
 
35
                        retVal = find->second;
 
36
                else retVal = in;
 
37
 
 
38
                setState(0);
 
39
                retString[retStringIndex++] = retVal;
 
40
                return retString;
 
41
        }
 
42
        else {
 
43
                retVal = subst[in];
 
44
 
 
45
                if (retVal == 0) {
 
46
                        setState(0);
 
47
                        retString[retStringIndex++] = in;
 
48
                        return retString;
 
49
                }
 
50
                if (retVal > 100) {
 
51
                        setState(1);
 
52
                        retString[retStringIndex++] = retVal;
 
53
                        return retString;
 
54
                }
 
55
                if (retVal == 50) {  // multiChar
 
56
                        setState(1);
 
57
                        int *chars = multiChars[in];
 
58
                        if (chars != 0) {
 
59
                                retString[retStringIndex++] = chars[0];
 
60
                                retString[retStringIndex++] = chars[1];
 
61
                                return retString;
 
62
                        }
 
63
                }
 
64
        }
 
65
        setState(retVal);
 
66
        return 0;
 
67
}
 
68
 
 
69
 
 
70
void HebrewMCIM::init() {
 
71
        memset(subst, 0, 255);
 
72
 
 
73
        subst[')'] = 1488;
 
74
        subst['B'] = 1489;
 
75
        subst['G'] = 1490;
 
76
        subst['D'] = 1491;
 
77
        subst['H'] = 1492;
 
78
        subst['W'] = 1493;
 
79
        subst['Z'] = 1494;
 
80
        subst['X'] = 1495;
 
81
        subst['+'] = 1496;
 
82
        subst['Y'] = 1497;
 
83
 
 
84
        subst['k'] = 1498;  // finals
 
85
        subst['m'] = 1501;
 
86
        subst['n'] = 1503;
 
87
        subst['c'] = 1509;
 
88
 
 
89
        subst['P'] = 1508;
 
90
        subst['K'] = 1499;
 
91
        subst['L'] = 1500;
 
92
        subst['M'] = 1502;
 
93
        subst['N'] = 1504;
 
94
        subst['S'] = 1505;
 
95
        subst['('] = 1506;
 
96
        subst['p'] = 1507;
 
97
        subst['C'] = 1510;
 
98
        subst['Q'] = 1511;
 
99
        subst['R'] = 1512;
 
100
        subst['#'] = 1513;
 
101
 
 
102
        // special multiChars
 
103
        subst['&'] = 50;
 
104
        subst['$'] = 50;
 
105
 
 
106
        static int x[] = {1513, 1474};
 
107
        multiChars['&'] = x;
 
108
        static int y[] = {1513, 1473};
 
109
        multiChars['$'] = y;
 
110
 
 
111
        subst['T'] = 1514;
 
112
 
 
113
        // VOWELS
 
114
        subst['A'] = 1463;
 
115
        subst['F'] = 1464;
 
116
        subst['E'] = 1462;
 
117
        subst['"'] = 1461;
 
118
        subst['I'] = 1460;
 
119
        subst['O'] = 1465;
 
120
        subst['U'] = 1467;
 
121
 
 
122
 
 
123
 
 
124
        // OTHER DIACRITICS
 
125
        subst['.'] = 1468;
 
126
        subst['-'] = 1470;
 
127
        subst[','] = 1471;
 
128
 
 
129
        // Compound input
 
130
 
 
131
        // CANTILLATION
 
132
 
 
133
        subst[':'] = 2;
 
134
        subst2[2]['A'] = 1458;
 
135
        subst2[2]['E'] = 1457;
 
136
        subst2[2]['F'] = 1459;
 
137
 
 
138
 
 
139
        /* Telisha qetana is postpositive as in '04' above. However, Michigan
 
140
# code '24' is for a medial telisha. Graphically, there is no
 
141
# difference.
 
142
        */
 
143
        subst['2'] = 5;
 
144
        subst2[5]['4'] = 1449;
 
145
 
 
146
 
 
147
        /* Note Michigan encoding distinguishes between medial metheg '35' (occuring
 
148
# on the left of the vowel), and the ordinary meteg '95' (occuring on the
 
149
# right of the vowel). It is also used for silluq.
 
150
        */
 
151
        subst['3'] = 6;
 
152
        subst2[6]['3'] = 1433;
 
153
        subst2[6]['5'] = 1469;
 
154
 
 
155
 
 
156
        /* The Michigan code of telisha gedola in medial position. Graphically,
 
157
# there is no difference.
 
158
        */
 
159
        subst['4'] = 7;
 
160
        subst2[7]['4'] = 1440;
 
161
 
 
162
        subst['6'] = 8;
 
163
        subst2[8]['0'] = 1451;
 
164
        subst2[8]['1'] = 1436;
 
165
 
 
166
        subst['1'] = 4;
 
167
        subst2[4]['0'] = 1434;
 
168
 
 
169
        /* In the poetic books, prepositive dehi occurs; it's unclear whether
 
170
# tipeha also occurs in the poetic books. Otherwise, we could simply
 
171
# check for what book in the Tanach we are in. Michigan uses the same
 
172
# code for each.
 
173
        */
 
174
 
 
175
        subst2[4]['3'] = 1430;
 
176
 
 
177
        /* This is the poetic accent mugrash, which also includes rebia, but is
 
178
# encoded separately as '81' in the Michigan text.
 
179
        */
 
180
        subst2[4]['1'] = 1437;
 
181
        subst2[4]['4'] = 1440;
 
182
 
 
183
 
 
184
        subst['0'] = 3;
 
185
        subst2[3]['0'] = 1475;
 
186
        subst2[3]['1'] = 1426;
 
187
 
 
188
        /* According to BHS, zarqa and sinnor are both postpositive. However,
 
189
# the Michigan encoding uses one code for both. The Unicode zarqa
 
190
# (0x0598) is definitely NOT postpositive. And further, the shape of
 
191
# the symbol is different in BHS and Uniocde. This needs further
 
192
# research to determine what's going on here. For now, we follow BHS
 
193
# and use the postpositive Unicode zinor or both accents.
 
194
        */
 
195
 
 
196
        subst2[3]['2'] = 1454;
 
197
 
 
198
        /* Pashta is postpositive, and the Unicode equivalent reflects
 
199
# this. However, there is a poetic equivalent -- azla legarmeh --
 
200
# which is not postpositive, but no equivalent code point exists in
 
201
# Unicode. The Michigan encoding does not distinguish between the two,
 
202
# although it could be algorithmically determined.
 
203
        */
 
204
 
 
205
        subst2[3]['3'] = 1433;
 
206
        subst2[3]['4'] = 1449;
 
207
        subst2[3]['5'] = 1472;
 
208
 
 
209
 
 
210
        /* This is the Unicode Hebrew *accent*; there is also another Hebrew
 
211
# *punctuation* called GERSHAYIM 0x05F4. I'm using the more
 
212
# traditional rounded marks, rather than the alternate straight
 
213
# marks.
 
214
        */
 
215
 
 
216
        subst2[8]['2'] = 1438;
 
217
 
 
218
        // Also known as azla
 
219
        subst2[8]['3'] = 1448;
 
220
        subst2[8]['4'] = 1452;
 
221
        subst2[8]['5'] = 1427;
 
222
 
 
223
 
 
224
        subst['8'] = 9;
 
225
        subst2[9]['0'] = 1428;
 
226
        subst2[9]['1'] = 1431;
 
227
 
 
228
        /* Note, this accent is actually sinnorit, but it does not exist as a
 
229
# separate glyph in the Unicode standard. The 'ZINOR' Unicode accent
 
230
# is postpositive, while sinnorit is not. ZARQA is as close as I can
 
231
# get to this.
 
232
        */
 
233
        subst2[9]['2'] = 1432;
 
234
 
 
235
        /* The Unicode form does not match the form used by BHS, but the names
 
236
# are the same.
 
237
        */
 
238
        subst2[9]['3'] = 1441;
 
239
        subst2[9]['4'] = 1439;
 
240
        subst2[9]['5'] = 1429;
 
241
 
 
242
        subst['7'] = 10;
 
243
        subst2[10]['0'] = 1444;
 
244
        subst2[10]['1'] = 1445;
 
245
        subst2[10]['2'] = 1446;
 
246
        subst2[10]['3'] = 1430;  // also '13', '73' also is used for majela
 
247
        subst2[10]['4'] = 1443;
 
248
        subst2[10]['5'] = 1469;  // this is silluq; should appear to the left of the vowel
 
249
 
 
250
        subst['9'] = 11;
 
251
        subst2[11]['1'] = 1435;
 
252
        subst2[11]['2'] = 1425;
 
253
        subst2[11]['3'] = 1450;
 
254
        subst2[11]['4'] = 1447;
 
255
        subst2[11]['5'] = 1469;  // should appear to the right of the vowel
 
256
 
 
257
}
 
258
 
 
259
        /*
 
260
 
 
261
 
 
262
# CANTILLION MARKS
 
263
 
 
264
        my  $ETNAHTA =           '&#1425;';
 
265
# officially the Unicode name for this symbol was "SEGOL." However, that is
 
266
# not a unique name, conflicting with the vowel of the same name. Further,
 
267
# the position of the symbol is different. I have changed the name of the
 
268
# accent to "SEGOLTA," the traditional name for this accent.
 
269
        my  $SEGOLTA =           '&#1426;';
 
270
        my  $SHALSHELET =        '&#1427;';
 
271
        my  $ZAQEF_QATAN =       '&#1428;';
 
272
        my  $ZAQEF_GADOL =       '&#1429;';
 
273
        my  $TIPEHA =            '&#1430;';
 
274
        my  $REVIA =             '&#1431;';
 
275
        my  $ZARQA =             '&#1432;';
 
276
        my  $PASHTA =            '&#1433;';
 
277
        my  $YETIV =             '&#1434;';
 
278
        my  $TEVIR =             '&#1435;';
 
279
        my  $GERESH =            '&#1436;';
 
280
        my  $GERESH_MUQDAM =     '&#1437;';
 
281
        my  $GERSHAYIM =         '&#1438;';
 
282
        my  $QARNEY_PARA =       '&#1439;';
 
283
        my  $TELISHA_GEDOLA =    '&#1440;';
 
284
        my  $PAZER =             '&#1441;';
 
285
        my  $MUNAH =             '&#1443;';
 
286
        my  $MAHAPAKH =          '&#1444;';
 
287
        my  $MERKHA =            '&#1445;';
 
288
        my  $MERKHA_KEFULA =     '&#1446;';
 
289
        my  $DARGA =             '&#1447;';
 
290
        my  $QADMA =             '&#1448;';
 
291
        my  $TELISHA_QETANA =    '&#1449;';
 
292
        my  $YERAH_BEN_YOMO =    '&#1450;';
 
293
        my  $OLE =               '&#1451;';
 
294
        my  $ILUY =              '&#1452;';
 
295
        my  $DEHI =              '&#1453;';
 
296
        my  $ZINOR =             '&#1454;';
 
297
# HEBREW MARK
 
298
        my  $MASORA_CIRCLE =     '&#1455;';
 
299
# HEBREW EXTENDED-A  points and punctuation
 
300
        my  $SHEVA =             '&#1456;';
 
301
        my  $HATAF_SEGOL =       '&#1457;';
 
302
        my  $HATAF_PATAH =       '&#1458;';
 
303
        my  $HATAF_QAMATS =      '&#1459;';
 
304
        my  $HIRIQ =             '&#1460;';
 
305
        my  $TSERE =             '&#1461;';
 
306
        my  $SEGOL =             '&#1462;';
 
307
# furtive Patah is not a distinct character
 
308
        my  $PATAH =             '&#1463;';
 
309
        my  $QAMATS =            '&#1464;';
 
310
        my  $HOLAM =             '&#1465;';
 
311
        my  $QUBUTS =            '&#1467;';
 
312
# also used as shuruq
 
313
# falls within the base letter
 
314
        my  $DAGESH_OR_MAPIQ =   '&#1468;';
 
315
# also used as siluq
 
316
        my  $METAG =             '&#1469;';
 
317
        my  $MAQAF =             '&#1470;';
 
318
        my  $RAFE =              '&#1471;';
 
319
# Also used for legarmeh
 
320
#   may be treated as spacing punctuation, not as a point
 
321
        my  $PASEQ =             '&#1472;';
 
322
        my  $SHIN_DOT =          '&#1473;';
 
323
        my  $SIN_DOT =           '&#1474;';
 
324
        my  $SOF_PASUQ =         '&#1475;';
 
325
# HEBREW MARK
 
326
        my  $UPPER_DOT =         '&#1476;';
 
327
# HEBREW LETTERS based on ISO 8859-8
 
328
# aleph
 
329
#  x (alef symbol - 2135)
 
330
        my  $ALEF =              '&#1488;';
 
331
#  x (bet symbol - 2136)
 
332
        my  $BET =               '&#1489;';
 
333
#  x (gimel symbol - 2137)
 
334
        my  $GIMEL =             '&#1490;';
 
335
#  x (dalet symbol - 2138)
 
336
        my  $DALET =             '&#1491;';
 
337
        my  $HE =                '&#1492;';
 
338
        my  $VAV =               '&#1493;';
 
339
        my  $ZAYIN =             '&#1494;';
 
340
        my  $HET =               '&#1495;';
 
341
        my  $TET =               '&#1496;';
 
342
        my  $YOD =               '&#1497;';
 
343
        my  $FINAL_KAF =         '&#1498;';
 
344
        my  $KAF =               '&#1499;';
 
345
        my  $LAMED =             '&#1500;';
 
346
        my  $FINAL_MEM =         '&#1501;';
 
347
        my  $MEM =               '&#1502;';
 
348
        my  $FINAL_NUN =         '&#1503;';
 
349
        my  $NUN =               '&#1504;';
 
350
        my  $SAMEKH =            '&#1505;';
 
351
        my  $AYIN =              '&#1506;';
 
352
        my  $FINAL_PE =          '&#1507;';
 
353
        my  $PE =                '&#1508;';
 
354
        my  $FINAL_TSADI =       '&#1509;';
 
355
# also known as zade
 
356
        my  $TSADI =             '&#1510;';
 
357
        my  $QOF =               '&#1511;';
 
358
        my  $RESH =              '&#1512;';
 
359
        my  $SHIN =              '&#1513;';
 
360
        my  $TAV =               '&#1514;';
 
361
# Yiddish digraphs
 
362
#   Hebrew Ligature
 
363
# tsvey vovn
 
364
        my  $DOUBLE_VAV =        '&#1520;';
 
365
        my  $VAV_YOD =           '&#1521;';
 
366
# tsvey yudn
 
367
        my  $DOUBLE_YOD =        '&#1522;';
 
368
 
 
369
# Additional punctuation
 
370
        my  $PUNCT_GERESH =      '&#1523;';
 
371
        my  $PUNCT_GERSHAYIM =   '&#1524;';
 
372
# Reserved: 0x05F5"
 
373
# x (hebrew point judeo-spanish varika - FB1E)
 
374
#my  $JUDEO_SPANISH_VARIKA = pack("U",0xFB1E); # UTF-8 OxFB1E
 
375
 
 
376
#############################
 
377
# End of Unicode 2.0 Hebrew #
 
378
#############################
 
379
 
 
380
# A hash whose key is a Michagan code, and whose value is a Unicode
 
381
# equvalent
 
382
 
 
383
        char subst[] = new char [255];
 
384
        subst[')'] = 1488;
 
385
        'B'  => $BET,
 
386
        'G'  => $GIMEL,
 
387
        'D'  => $DALET,
 
388
        'H'  => $HE,
 
389
        'W'  => $VAV,
 
390
        'Z'  => $ZAYIN,
 
391
        'X'  => $HET,
 
392
        '+'  => $TET,
 
393
        'Y'  => $YOD,
 
394
        'K'  => $KAF,
 
395
        'L'  => $LAMED,
 
396
        'M'  => $MEM,
 
397
        'N'  => $NUN,
 
398
        'S'  => $SAMEKH,
 
399
        '('  => $AYIN,
 
400
        'P'  => $PE,
 
401
        'C'  => $TSADI,
 
402
        'Q'  => $QOF,
 
403
        'R'  => $RESH,
 
404
        '#'  => $SHIN, # the letter shin without a point
 
405
        '&'  => ($SHIN . $SIN_DOT),
 
406
        '$'  => ($SHIN . $SHIN_DOT), # '
 
407
        'T'  => $TAV,
 
408
# VOWELS
 
409
        'A'  => $PATAH,
 
410
        'F'  => $QAMATS,
 
411
        'E'  => $SEGOL,
 
412
        '"'  => $TSERE,
 
413
        'I'  => $HIRIQ,
 
414
        'O'  => $HOLAM,
 
415
        'U'  => $QUBUTS,
 
416
        ':'  => $SHEVA,
 
417
        ':A' => $HATAF_PATAH,
 
418
        ':E' => $HATAF_SEGOL,
 
419
        ':F' => $HATAF_QAMATS,
 
420
# OTHER DIACRITICS
 
421
        '.'  => $DAGESH_OR_MAPIQ,
 
422
        '-'  => $MAQAF,
 
423
        ','  => $RAFE,
 
424
# CANTILLATION
 
425
        '00' => $SOF_PASUQ,
 
426
        '01' => $SEGOLTA,
 
427
# According to BHS, zarqa and sinnor are both postpositive. However,
 
428
# the Michigan encoding uses one code for both. The Unicode zarqa
 
429
# (0x0598) is definitely NOT postpositive. And further, the shape of
 
430
# the symbol is different in BHS and Uniocde. This needs further
 
431
# research to determine what's going on here. For now, we follow BHS
 
432
# and use the postpositive Unicode zinor or both accents.
 
433
        '02' => $ZINOR,
 
434
# Pashta is postpositive, and the Unicode equivalent reflects
 
435
# this. However, there is a poetic equivalent -- azla legarmeh --
 
436
# which is not postpositive, but no equivalent code point exists in
 
437
# Unicode. The Michigan encoding does not distinguish between the two,
 
438
# although it could be algorithmically determined.
 
439
        '03' => $PASHTA,
 
440
        '04' => $TELISHA_QETANA,
 
441
        '05' => $PASEQ,
 
442
        '10' => $YETIV,
 
443
# In the poetic books, prepositive dehi occurs; it's unclear whether
 
444
# tipeha also occurs in the poetic books. Otherwise, we could simply
 
445
# check for what book in the Tanach we are in. Michigan uses the same
 
446
# code for each.
 
447
        '13' => $TIPEHA, # also $DEHI
 
448
# This is the poetic accent mugrash, which also includes rebia, but is
 
449
# encoded separately as '81' in the Michigan text.
 
450
        '11' => $GERESH_MUQDAM,
 
451
        '14' => $TELISHA_GEDOLA,
 
452
# Telisha qetana is postpositive as in '04' above. However, Michigan
 
453
# code '24' is for a medial telisha. Graphically, there is no
 
454
# difference.
 
455
        '24' => $TELISHA_QETANA,
 
456
        '33' => $PASHTA,
 
457
# The Michigan code of telisha gedola in medial position. Graphically,
 
458
# there is no difference.
 
459
        '44' => $TELISHA_GEDOLA,
 
460
        '60' => $OLE,
 
461
        '61' => $GERESH,
 
462
# This is the Unicode Hebrew *accent*; there is also another Hebrew
 
463
# *punctuation* called GERSHAYIM 0x05F4. I'm using the more
 
464
# traditional rounded marks, rather than the alternate straight
 
465
# marks.
 
466
        '62' => $GERSHAYIM,
 
467
# Also known as azla
 
468
        '63' => $QADMA,
 
469
        '64' => $ILUY,
 
470
        '65' => $SHALSHELET,
 
471
        '80' => $ZAQEF_QATAN,
 
472
        '81' => $REVIA,
 
473
# Note, this accent is actually sinnorit, but it does not exist as a
 
474
# separate glyph in the Unicode standard. The 'ZINOR' Unicode accent
 
475
# is postpositive, while sinnorit is not. ZARQA is as close as I can
 
476
# get to this.
 
477
        '82' => $ZARQA,
 
478
# The Unicode form does not match the form used by BHS, but the names
 
479
# are the same.
 
480
        '83' => $PAZER,
 
481
        '84' => $QARNEY_PARA,
 
482
        '85' => $ZAQEF_GADOL,
 
483
# Note Michigan encoding distinguishes between medial metheg '35' (occuring
 
484
# on the left of the vowel), and the ordinary meteg '95' (occuring on the
 
485
# right of the vowel). It is also used for silluq.
 
486
        '35' => $METAG,
 
487
        '70' => $MAHAPAKH,
 
488
        '71' => $MERKHA,
 
489
        '72' => $MERKHA_KEFULA,
 
490
        '73' => $TIPEHA, # also '13', '73' also is used for majela
 
491
        '74' => $MUNAH,
 
492
        '75' => $METAG, # this is silluq; should appear to the left of the vowel
 
493
        '91' => $TEVIR,
 
494
        '92' => $ETNAHTA,
 
495
        '93' => $YERAH_BEN_YOMO,
 
496
        '94' => $DARGA,
 
497
        '95' => $METAG, # should appear to the right of the vowel
 
498
 
 
499
# Not used by the Michigan Encoding
 
500
# $UPPER_DOT = '05C4';
 
501
        );
 
502
 
 
503
# declare other variables
 
504
        my (@bhsLines,
 
505
        @bhsVerse,
 
506
        @entity_line) = ();
 
507
 
 
508
        my ($i,
 
509
        $verse,
 
510
        $word,
 
511
        $character) = 0;
 
512
 
 
513
        my ($element,
 
514
        $saveGuttural) = "";
 
515
 
 
516
# read in a line
 
517
        while (<>) {
 
518
# Process one verse
 
519
# iterate over every character and change to XML decimal entity
 
520
        CHAR: for ( $i = 0; ($i < scalar(@bhsVerse)); $i++) {
 
521
         # find and convert final kaf, mem, nun, pe, tsade
 
522
         ( # if final form
 
523
          $bhsVerse[$i] =~ /[KMNPC]/
 
524
         )
 
525
           &&
 
526
                (
 
527
                 ( # whitespace or
 
528
                  $bhsVerse[$i+1] =~ /[ \-?]/
 
529
                 )
 
530
                 ||
 
531
                 ( # EOL or
 
532
                  $i == ( scalar(@bhsVerse) - 1 )
 
533
                 )
 
534
                 ||
 
535
                 ( # sof pasuq or
 
536
                  ( $bhsVerse[$i+1] =~ /0/ ) &&
 
537
                  ( $bhsVerse[$i+2] =~ /0/ )
 
538
                 )
 
539
                 ||
 
540
                 ( # one accent followed by white, eol or
 
541
                  (
 
542
                   ( $bhsVerse[$i+1] =~ /\d/ ) &&
 
543
                   ( $bhsVerse[$i+2] =~ /\d/ )
 
544
                  ) &&
 
545
                  (
 
546
                   ( $bhsVerse[$i+3] =~ /[ \-?]/ ) ||
 
547
                   ( $i == ( scalar(@bhsVerse) - 1 ) )
 
548
                  )
 
549
                 )
 
550
                 ||
 
551
                 ( # two accents followed by white, eol
 
552
                  (
 
553
                   ( $bhsVerse[$i+1] =~ /\d/ ) &&
 
554
                   ( $bhsVerse[$i+2] =~ /\d/ ) &&
 
555
                   ( $bhsVerse[$i+3] =~ /\d/ ) &&
 
556
                   ( $bhsVerse[$i+4] =~ /\d/ )
 
557
                  ) &&
 
558
                  (
 
559
                   ( $bhsVerse[$i+5] =~ /[ \-?]/ ) ||
 
560
                   ( $i == ( scalar(@bhsVerse) - 1 ) )
 
561
                  )
 
562
                 )
 
563
                 ||
 
564
                 ( # followed by a vowel and white, eol, sof pasuq
 
565
                  ( $bhsVerse[$i+1] =~ /[:F]/ ) &&
 
566
                  ( # followed by
 
567
                   ( $bhsVerse[$i+2] =~ /[ \-?]/ ) || # whitespace or
 
568
                   ( $i == ( scalar(@bhsVerse) - 1 ) ) || # eol or
 
569
                   ( # sof pasuq
 
570
                    ( $bhsVerse[$i+2] =~ /0/ ) &&
 
571
                    ( $bhsVerse[$i+3] =~ /0/ )
 
572
                   )
 
573
                  )
 
574
                 )
 
575
                ) # end of what follows after final letter
 
576
                  &&
 
577
                    do {
 
578
                         $bhsVerse[$i] =~ /K/ && eval { push @entity_line,$FINAL_KAF; }
 
579
                           && next CHAR;
 
580
                         $bhsVerse[$i] =~ /M/ && eval { push @entity_line,$FINAL_MEM; }
 
581
                           && next CHAR;
 
582
                         $bhsVerse[$i] =~ /N/ && eval { push @entity_line,$FINAL_NUN; }
 
583
                           && next CHAR;
 
584
                         $bhsVerse[$i] =~ /P/ && eval { push @entity_line,$FINAL_PE; }
 
585
                           && next CHAR;
 
586
                         $bhsVerse[$i] =~ /C/ && eval { push @entity_line,$FINAL_TSADI; }
 
587
                           && next CHAR;
 
588
                    };
 
589
         # find and convert "furtive patach"
 
590
         ( $bhsVerse[$i] =~ /A/ ) &&             # If the letter is a patach
 
591
           ( $bhsVerse[$i-1] =~ /[)HX(]/ ) &&    #  and is preceeded by a guttural
 
592
           ( ( $bhsVerse[$i-2] =~ /[AEFOU]/ ) || #  and is preceeded by a vowel
 
593
                ( ( $bhsVerse[$i-2] =~ /\./ ) &&    #  or by suruq
 
594
                  ( $bhsVerse[$i-3] =~ /W/ ) ) ||    #
 
595
                ( ( $bhsVerse[$i-2] =~ /W/ ) &&      #  or by holem (written plene)
 
596
                  ( $bhsVerse[$i-3] =~ /O/ ) ) ||    #
 
597
                ( ( $bhsVerse[$i-2] =~ /Y/ ) &&      #  or by hiriq-yod
 
598
                  ( $bhsVerse[$i-3] =~ /I/ ) ) ) &&
 
599
                  do {
 
600
                         $saveGuttural = pop @entity_line; # snip off the gutteral
 
601
                         push @entity_line,$PATAH;         # push on the patach
 
602
                         push @entity_line,$saveGuttural;  # push back on the gutteral
 
603
                         next CHAR;
 
604
                  };
 
605
         # convert cantillation
 
606
         #   since we have previously dealt with all other cases of
 
607
         #   numbers, two digit patterns are all we have to search for
 
608
         $bhsVerse[$i] =~ /\d/ && $bhsVerse[$i+1] =~ /\d/ && do {
 
609
                push @entity_line,$Michigan2XMLentity{"$bhsVerse[$i]$bhsVerse[$i+1]"};
 
610
                $i++; # accents are two digits long, so advance past the 2nd digit
 
611
                next CHAR;
 
612
         };
 
613
         # convert katef vowels, which are two characters long
 
614
         $bhsVerse[$i] =~ /:/ && $bhsVerse[$i+1] =~ /[AEF]/ && do {
 
615
                push @entity_line,$Michigan2XMLentity{"$bhsVerse[$i]$bhsVerse[$i+1]"};
 
616
                $i++;
 
617
                next CHAR;
 
618
         };
 
619
         # convert everything else
 
620
         push @entity_line,$Michigan2XMLentity{"$bhsVerse[$i]"};
 
621
        } # end CHAR
 
622
# print the line to standard output with XML character-level encoding
 
623
# each character has the following format:
 
624
# <c id="1kg1.verse#.word#.character#">&#1234;</c>
 
625
 
 
626
# set up the verse element
 
627
        $word = 1;
 
628
        $character = 1;
 
629
        print "<verse>\n<word>\n";
 
630
# print each character element
 
631
# if there is a space, then close the word entity, open a new word
 
632
# entity, increment the word number, reset the character number to
 
633
# zero.
 
634
        foreach $element (@entity_line) {
 
635
         if ( $element =~ " " ) {
 
636
           $word++;
 
637
           $character = 1;
 
638
           print "</word>\n<word>\n";
 
639
           next;
 
640
         }
 
641
         print "<c id=\"1kg1.$verse.$word.$character\">$element</c>\n";
 
642
         $character++;
 
643
        }
 
644
# close the verse element
 
645
        print "</word></verse>\n";
 
646
# reinitialize variables
 
647
        @bhsVerse = ();
 
648
        @entity_line = ();
 
649
        @bhsLines = ();
 
650
        } # end while
 
651
# close the XML document
 
652
        print "</body>\n";
 
653
        */