~ubuntu-branches/ubuntu/raring/kbibtex/raring

« back to all changes in this revision

Viewing changes to src/encoderlatex.cpp

  • Committer: Package Import Robot
  • Author(s): Michael Hanke
  • Date: 2011-07-18 09:29:48 UTC
  • mfrom: (1.1.6) (2.1.5 sid)
  • Revision ID: package-import@ubuntu.com-20110718092948-ksxjmg7kdfamolmg
Tags: 0.3-1
* First upstream release for KDE4 (Closes: #634255). A number of search
  engines are still missing, in comparison to the 0.2 series.
* Bumped Standards-Version to 3.9.2, no changes necessary.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/***************************************************************************
2
 
*   Copyright (C) 2004-2009 by Thomas Fischer                             *
3
 
*   fischer@unix-ag.uni-kl.de                                             *
4
 
*                                                                         *
5
 
*   This program is free software; you can redistribute it and/or modify  *
6
 
*   it under the terms of the GNU General Public License as published by  *
7
 
*   the Free Software Foundation; either version 2 of the License, or     *
8
 
*   (at your option) any later version.                                   *
9
 
*                                                                         *
10
 
*   This program is distributed in the hope that it will be useful,       *
11
 
*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12
 
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13
 
*   GNU General Public License for more details.                          *
14
 
*                                                                         *
15
 
*   You should have received a copy of the GNU General Public License     *
16
 
*   along with this program; if not, write to the                         *
17
 
*   Free Software Foundation, Inc.,                                       *
18
 
*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19
 
***************************************************************************/
20
 
#include <qstring.h>
21
 
#include <qapplication.h>
22
 
#include <qregexp.h>
23
 
 
24
 
#include "encoderlatex.h"
25
 
 
26
 
namespace BibTeX
27
 
{
28
 
    EncoderLaTeX *EncoderLaTeX::encoderLaTeX = NULL;
29
 
 
30
 
    static struct Decomposition
31
 
    {
32
 
        const char *latexCommand;
33
 
        unsigned int unicode;
34
 
    }
35
 
    decompositions[] =
36
 
    {
37
 
        {"`", 0x0300},
38
 
        {"'", 0x0301},
39
 
        {"^", 0x0302},
40
 
        {"~", 0x0303},
41
 
        {"=", 0x0304},
42
 
        /*{"x", 0x0305},  OVERLINE */
43
 
        {"u", 0x0306},
44
 
        {".", 0x0307},
45
 
        /*{"x", 0x0309},  HOOK ABOVE */
46
 
        {"r", 0x030a},
47
 
        {"H", 0x030b},
48
 
        {"v", 0x030c},
49
 
        /*{"x", 0x030d},  VERTICAL LINE ABOVE */
50
 
        /*{"x", 0x030e},  DOUBLE VERTICAL LINE ABOVE */
51
 
        /*{"x", 0x030f},  DOUBLE GRAVE ACCENT */
52
 
        /*{"x", 0x0310},  CANDRABINDU */
53
 
        /*{"x", 0x0311},  INVERTED BREVE */
54
 
        /*{"x", 0x0312},  TURNED COMMA ABOVE */
55
 
        /*{"x", 0x0313},  COMMA ABOVE */
56
 
        /*{"x", 0x0314},  REVERSED COMMA ABOVE */
57
 
        /*{"x", 0x0315},   */
58
 
        /*{"x", 0x0316},   */
59
 
        /*{"x", 0x0317},   */
60
 
        /*{"x", 0x0318},   */
61
 
        /*{"x", 0x0319},   */
62
 
        /*{"x", 0x031a},   */
63
 
        /*{"x", 0x031b},   */
64
 
        /*{"x", 0x031c},   */
65
 
        /*{"x", 0x031d},   */
66
 
        /*{"x", 0x031e},   */
67
 
        /*{"x", 0x031f},   */
68
 
        /*{"x", 0x0320},   */
69
 
        /*{"x", 0x0321},   */
70
 
        /*{"x", 0x0322},   */
71
 
        {"d", 0x0323},
72
 
        /*{"x", 0x0324},   */
73
 
        /*{"x", 0x0325},   */
74
 
        /*{"x", 0x0326},   */
75
 
        {"d", 0x0327},
76
 
        {"k", 0x0328},
77
 
        /*{"x", 0x0329},   */
78
 
        /*{"x", 0x032a},   */
79
 
        /*{"x", 0x032b},   */
80
 
        /*{"x", 0x032c},   */
81
 
        /*{"x", 0x032d},   */
82
 
        /*{"x", 0x032e},   */
83
 
        /*{"x", 0x032f},   */
84
 
        {"b", 0x0331},
85
 
        {"t", 0x0361}
86
 
    };
87
 
 
88
 
    static const int decompositionscount = sizeof( decompositions ) / sizeof( decompositions[ 0 ] ) ;
89
 
 
90
 
    static const struct EncoderLaTeXCommandMapping
91
 
    {
92
 
        const char *letters;
93
 
        unsigned int unicode;
94
 
    }
95
 
    commandmappingdatalatex[] =
96
 
    {
97
 
        {"AA", 0x00C5},
98
 
        {"AE", 0x00C6},
99
 
        {"ss", 0x00DF},
100
 
        {"aa", 0x00E5},
101
 
        {"ae", 0x00E6},
102
 
        {"OE", 0x0152},
103
 
        {"oe", 0x0153},
104
 
        {"ldots", 0x2026},
105
 
        {"L", 0x0141},
106
 
        {"l", 0x0142},
107
 
        {"grqq", 0x201C},
108
 
        {"glqq", 0x201E},
109
 
        {"frqq", 0x00BB},
110
 
        {"flqq", 0x00AB},
111
 
 
112
 
// awk -F '[{}\\\\]+' '/DeclareUnicodeCharacter/ { print "{\""$4"\", 0x"$3"},"}' /usr/share/texmf-dist/tex/latex/base/t2aenc.dfu | grep '0x04' | sort -r -f
113
 
        {"cyrzhdsc", 0x0497},
114
 
        {"CYRZHDSC", 0x0496},
115
 
        {"cyrzh", 0x0436},
116
 
        {"CYRZH", 0x0416},
117
 
        {"cyrzdsc", 0x0499},
118
 
        {"CYRZDSC", 0x0498},
119
 
        {"cyrz", 0x0437},
120
 
        {"CYRZ", 0x0417},
121
 
        {"cyryu", 0x044E},
122
 
        {"CYRYU", 0x042E},
123
 
        {"cyryo", 0x0451},
124
 
        {"CYRYO", 0x0401},
125
 
        {"cyryi", 0x0457},
126
 
        {"CYRYI", 0x0407},
127
 
        {"cyryhcrs", 0x04B1},
128
 
        {"CYRYHCRS", 0x04B0},
129
 
        {"cyrya", 0x044F},
130
 
        {"CYRYA", 0x042F},
131
 
        {"cyry", 0x04AF},
132
 
        {"CYRY", 0x04AE},
133
 
        {"cyrv", 0x0432},
134
 
        {"CYRV", 0x0412},
135
 
        {"cyrushrt", 0x045E},
136
 
        {"CYRUSHRT", 0x040E},
137
 
        {"cyru", 0x0443},
138
 
        {"CYRU", 0x0423},
139
 
        {"cyrtshe", 0x045B},
140
 
        {"CYRTSHE", 0x040B},
141
 
        {"cyrtdsc", 0x04AD},
142
 
        {"CYRTDSC", 0x04AC},
143
 
        {"cyrt", 0x0442},
144
 
        {"CYRT", 0x0422},
145
 
        {"cyrshha", 0x04BB},
146
 
        {"CYRSHHA", 0x04BA},
147
 
        {"cyrshch", 0x0449},
148
 
        {"CYRSHCH", 0x0429},
149
 
        {"cyrsh", 0x0448},
150
 
        {"CYRSH", 0x0428},
151
 
        {"cyrsftsn", 0x044C},
152
 
        {"CYRSFTSN", 0x042C},
153
 
        {"cyrsdsc", 0x04AB},
154
 
        {"CYRSDSC", 0x04AA},
155
 
        {"cyrschwa", 0x04D9},
156
 
        {"CYRSCHWA", 0x04D8},
157
 
        {"cyrs", 0x0441},
158
 
        {"CYRS", 0x0421},
159
 
        {"cyrr", 0x0440},
160
 
        {"CYRR", 0x0420},
161
 
        {"CYRpalochka", 0x04C0},
162
 
        {"cyrp", 0x043F},
163
 
        {"CYRP", 0x041F},
164
 
        {"cyrotld", 0x04E9},
165
 
        {"CYROTLD", 0x04E8},
166
 
        {"cyro", 0x043E},
167
 
        {"CYRO", 0x041E},
168
 
        {"cyrnje", 0x045A},
169
 
        {"CYRNJE", 0x040A},
170
 
        {"cyrng", 0x04A5},
171
 
        {"CYRNG", 0x04A4},
172
 
        {"cyrndsc", 0x04A3},
173
 
        {"CYRNDSC", 0x04A2},
174
 
        {"cyrn", 0x043D},
175
 
        {"CYRN", 0x041D},
176
 
        {"cyrm", 0x043C},
177
 
        {"CYRM", 0x041C},
178
 
        {"cyrlje", 0x0459},
179
 
        {"CYRLJE", 0x0409},
180
 
        {"cyrl", 0x043B},
181
 
        {"CYRL", 0x041B},
182
 
        {"cyrkvcrs", 0x049D},
183
 
        {"CYRKVCRS", 0x049C},
184
 
        {"cyrkdsc", 0x049B},
185
 
        {"CYRKDSC", 0x049A},
186
 
        {"cyrk", 0x043A},
187
 
        {"CYRK", 0x041A},
188
 
        {"cyrje", 0x0458},
189
 
        {"CYRJE", 0x0408},
190
 
        {"cyrishrt", 0x0439},
191
 
        {"CYRISHRT", 0x0419},
192
 
        {"cyrii", 0x0456},
193
 
        {"CYRII", 0x0406},
194
 
        {"cyrie", 0x0454},
195
 
        {"CYRIE", 0x0404},
196
 
        {"cyri", 0x0438},
197
 
        {"CYRI", 0x0418},
198
 
        {"cyrhrdsn", 0x044A},
199
 
        {"CYRHRDSN", 0x042A},
200
 
        {"cyrhdsc", 0x04B3},
201
 
        {"CYRHDSC", 0x04B2},
202
 
        {"cyrh", 0x0445},
203
 
        {"CYRH", 0x0425},
204
 
        {"cyrgup", 0x0491},
205
 
        {"CYRGUP", 0x0490},
206
 
        {"cyrghcrs", 0x0493},
207
 
        {"CYRGHCRS", 0x0492},
208
 
        {"cyrg", 0x0433},
209
 
        {"CYRG", 0x0413},
210
 
        {"cyrf", 0x0444},
211
 
        {"CYRF", 0x0424},
212
 
        {"cyrery", 0x044B},
213
 
        {"CYRERY", 0x042B},
214
 
        {"cyrerev", 0x044D},
215
 
        {"CYREREV", 0x042D},
216
 
        {"cyre", 0x0435},
217
 
        {"CYRE", 0x0415},
218
 
        {"cyrdzhe", 0x045F},
219
 
        {"CYRDZHE", 0x040F},
220
 
        {"cyrdze", 0x0455},
221
 
        {"CYRDZE", 0x0405},
222
 
        {"cyrdje", 0x0452},
223
 
        {"CYRDJE", 0x0402},
224
 
        {"cyrd", 0x0434},
225
 
        {"CYRD", 0x0414},
226
 
        {"cyrchvcrs", 0x04B9},
227
 
        {"CYRCHVCRS", 0x04B8},
228
 
        {"cyrchrdsc", 0x04B7},
229
 
        {"CYRCHRDSC", 0x04B6},
230
 
        {"cyrch", 0x0447},
231
 
        {"CYRCH", 0x0427},
232
 
        {"cyrc", 0x0446},
233
 
        {"CYRC", 0x0426},
234
 
        {"cyrb", 0x0431},
235
 
        {"CYRB", 0x0411},
236
 
        {"cyrae", 0x04D5},
237
 
        {"CYRAE", 0x04D4},
238
 
        {"cyra", 0x0430},
239
 
        {"CYRA", 0x0410}
240
 
    };
241
 
 
242
 
    static const int commandmappingdatalatexcount = sizeof( commandmappingdatalatex ) / sizeof( commandmappingdatalatex[ 0 ] ) ;
243
 
 
244
 
    /** Command can be either
245
 
        (1) {embraced}
246
 
        (2) delimited by {},
247
 
        (3) <space>, line end,
248
 
        (4) \following_command (including \<space>, which must be maintained!),
249
 
        (5) } (end of entry or group)
250
 
     **/
251
 
    const char *expansionsCmd[] = {"\\{\\\\%1\\}", "\\\\%1\\{\\}", "\\\\%1(\\n|\\r|\\\\|\\})", "\\\\%1\\s"};
252
 
    static const  int expansionscmdcount = sizeof( expansionsCmd ) / sizeof( expansionsCmd[0] );
253
 
 
254
 
    static const struct EncoderLaTeXModCharMapping
255
 
    {
256
 
        const char *modifier;
257
 
        const char *letter;
258
 
        unsigned int unicode;
259
 
    }
260
 
    modcharmappingdatalatex[] =
261
 
    {
262
 
        {"\\\\`", "A", 0x00C0},
263
 
        {"\\\\'", "A", 0x00C1},
264
 
        {"\\\\\\^", "A", 0x00C2},
265
 
        {"\\\\~", "A", 0x00C3},
266
 
        {"\\\\\"", "A", 0x00C4},
267
 
        {"\\\\r", "A", 0x00C5},
268
 
        /** 0x00C6 */
269
 
        {"\\\\c", "C", 0x00C7},
270
 
        {"\\\\`", "E", 0x00C8},
271
 
        {"\\\\'", "E", 0x00C9},
272
 
        {"\\\\\\^", "E", 0x00CA},
273
 
        {"\\\\\"", "E", 0x00CB},
274
 
        {"\\\\`", "I", 0x00CC},
275
 
        {"\\\\'", "I", 0x00CD},
276
 
        {"\\\\\\^", "I", 0x00CE},
277
 
        {"\\\\\"", "I", 0x00CF},
278
 
        /** 0x00D0 */
279
 
        {"\\\\~", "N", 0x00D1},
280
 
        {"\\\\`", "O", 0x00D2},
281
 
        {"\\\\'", "O", 0x00D3},
282
 
        {"\\\\\\^", "O", 0x00D4},
283
 
        /** 0x00D5 */
284
 
        {"\\\\\"", "O", 0x00D6},
285
 
        /** 0x00D7 */
286
 
        {"\\\\", "O", 0x00D8},
287
 
        {"\\\\`", "U", 0x00D9},
288
 
        {"\\\\'", "U", 0x00DA},
289
 
        {"\\\\\\^", "U", 0x00DB},
290
 
        {"\\\\\"", "U", 0x00DC},
291
 
        {"\\\\'", "Y", 0x00DD},
292
 
        /** 0x00DE */
293
 
        {"\\\\\"", "s", 0x00DF},
294
 
        {"\\\\`", "a", 0x00E0},
295
 
        {"\\\\'", "a", 0x00E1},
296
 
        {"\\\\\\^", "a", 0x00E2},
297
 
        {"\\\\~", "a", 0x00E3},
298
 
        {"\\\\\"", "a", 0x00E4},
299
 
        {"\\\\r", "a", 0x00E5},
300
 
        /** 0x00E6 */
301
 
        {"\\\\c", "c", 0x00E7},
302
 
        {"\\\\`", "e", 0x00E8},
303
 
        {"\\\\'", "e", 0x00E9},
304
 
        {"\\\\\\^", "e", 0x00EA},
305
 
        {"\\\\\"", "e", 0x00EB},
306
 
        {"\\\\`", "i", 0x00EC},
307
 
        {"\\\\'", "i", 0x00ED},
308
 
        {"\\\\'", "\\\\i", 0x00ED},
309
 
        {"\\\\\\^", "i", 0x00EE},
310
 
        /** 0x00EF */
311
 
        /** 0x00F0 */
312
 
        {"\\\\~", "n", 0x00F1},
313
 
        {"\\\\`", "o", 0x00F2},
314
 
        {"\\\\'", "o", 0x00F3},
315
 
        {"\\\\\\^", "o", 0x00F4},
316
 
        /** 0x00F5 */
317
 
        {"\\\\\"", "o", 0x00F6},
318
 
        /** 0x00F7 */
319
 
        {"\\\\", "o", 0x00F8},
320
 
        {"\\\\`", "u", 0x00F9},
321
 
        {"\\\\'", "u", 0x00FA},
322
 
        {"\\\\\\^", "u", 0x00FB},
323
 
        {"\\\\\"", "u", 0x00FC},
324
 
        {"\\\\'", "y", 0x00FD},
325
 
        /** 0x00FE */
326
 
        /** 0x00FF */
327
 
        /** 0x0100 */
328
 
        /** 0x0101 */
329
 
        {"\\\\u", "A", 0x0102},
330
 
        {"\\\\u", "a", 0x0103},
331
 
        /** 0x0104 */
332
 
        /** 0x0105 */
333
 
        {"\\\\'", "C", 0x0106},
334
 
        {"\\\\'", "c", 0x0107},
335
 
        /** 0x0108 */
336
 
        /** 0x0109 */
337
 
        /** 0x010A */
338
 
        /** 0x010B */
339
 
        {"\\\\v", "C", 0x010C},
340
 
        {"\\\\v", "c", 0x010D},
341
 
        {"\\\\v", "D", 0x010E},
342
 
        /** 0x010F */
343
 
        /** 0x0110 */
344
 
        /** 0x0111 */
345
 
        /** 0x0112 */
346
 
        /** 0x0113 */
347
 
        /** 0x0114 */
348
 
        /** 0x0115 */
349
 
        /** 0x0116 */
350
 
        /** 0x0117 */
351
 
        {"\\\\c", "E", 0x0118},
352
 
        {"\\\\c", "e", 0x0119},
353
 
        {"\\\\v", "E", 0x011A},
354
 
        {"\\\\v", "e", 0x011B},
355
 
        /** 0x011C */
356
 
        /** 0x011D */
357
 
        {"\\\\u", "G", 0x011E},
358
 
        {"\\\\u", "g", 0x011F},
359
 
        /** 0x0120 */
360
 
        /** 0x0121 */
361
 
        /** 0x0122 */
362
 
        /** 0x0123 */
363
 
        /** 0x0124 */
364
 
        /** 0x0125 */
365
 
        /** 0x0126 */
366
 
        /** 0x0127 */
367
 
        /** 0x0128 */
368
 
        /** 0x0129 */
369
 
        /** 0x012A */
370
 
        /** 0x012B */
371
 
        {"\\\\u", "I", 0x012C},
372
 
        {"\\\\u", "i", 0x012D},
373
 
        /** 0x012E */
374
 
        /** 0x012F */
375
 
        /** 0x0130 */
376
 
        /** 0x0131 */
377
 
        /** 0x0132 */
378
 
        /** 0x0133 */
379
 
        /** 0x0134 */
380
 
        /** 0x0135 */
381
 
        /** 0x0136 */
382
 
        /** 0x0137 */
383
 
        /** 0x0138 */
384
 
        {"\\\\'", "L", 0x0139},
385
 
        {"\\\\'", "l", 0x013A},
386
 
        /** 0x013B */
387
 
        /** 0x013C */
388
 
        /** 0x013D */
389
 
        /** 0x013E */
390
 
        /** 0x013F */
391
 
        /** 0x0140 */
392
 
        /** 0x0141 */
393
 
        /** 0x0142 */
394
 
        {"\\\\'", "N", 0x0143},
395
 
        {"\\\\'", "n", 0x0144},
396
 
        /** 0x0145 */
397
 
        /** 0x0146 */
398
 
        {"\\\\v", "N", 0x0147},
399
 
        {"\\\\v", "n", 0x0148},
400
 
        /** 0x0149 */
401
 
        /** 0x014A */
402
 
        /** 0x014B */
403
 
        /** 0x014C */
404
 
        /** 0x014D */
405
 
        {"\\\\u", "O", 0x014E},
406
 
        {"\\\\u", "o", 0x014F},
407
 
        {"\\\\H", "O", 0x0150},
408
 
        {"\\\\H", "o", 0x0151},
409
 
        /** 0x0152 */
410
 
        /** 0x0153 */
411
 
        {"\\\\'", "R", 0x0154},
412
 
        {"\\\\'", "r", 0x0155},
413
 
        /** 0x0156 */
414
 
        /** 0x0157 */
415
 
        {"\\\\v", "R", 0x0158},
416
 
        {"\\\\v", "r", 0x0159},
417
 
        {"\\\\'", "S", 0x015A},
418
 
        {"\\\\'", "s", 0x015B},
419
 
        /** 0x015C */
420
 
        /** 0x015D */
421
 
        {"\\\\c", "S", 0x015E},
422
 
        {"\\\\c", "s", 0x015F},
423
 
        {"\\\\v", "S", 0x0160},
424
 
        {"\\\\v", "s", 0x0161},
425
 
        /** 0x0162 */
426
 
        /** 0x0163 */
427
 
        {"\\\\v", "T", 0x0164},
428
 
        /** 0x0165 */
429
 
        /** 0x0166 */
430
 
        /** 0x0167 */
431
 
        /** 0x0168 */
432
 
        /** 0x0169 */
433
 
        /** 0x016A */
434
 
        /** 0x016B */
435
 
        {"\\\\u", "U", 0x016C},
436
 
        {"\\\\u", "u", 0x016D},
437
 
        {"\\\\r", "U", 0x016E},
438
 
        {"\\\\r", "u", 0x016F},
439
 
        /** 0x0170 */
440
 
        /** 0x0171 */
441
 
        /** 0x0172 */
442
 
        /** 0x0173 */
443
 
        /** 0x0174 */
444
 
        /** 0x0175 */
445
 
        /** 0x0176 */
446
 
        /** 0x0177 */
447
 
        {"\\\\\"", "Y", 0x0178},
448
 
        {"\\\\'", "Z", 0x0179},
449
 
        {"\\\\'", "z", 0x017A},
450
 
        /** 0x017B */
451
 
        /** 0x017C */
452
 
        {"\\\\v", "Z", 0x017D},
453
 
        {"\\\\v", "z", 0x017E},
454
 
        /** 0x017F */
455
 
        /** 0x0180 */
456
 
        {"\\\\v", "A", 0x01CD},
457
 
        {"\\\\v", "a", 0x01CE},
458
 
        {"\\\\v", "G", 0x01E6},
459
 
        {"\\\\v", "g", 0x01E7}
460
 
    };
461
 
 
462
 
    const char *expansionsMod1[] = {"\\{%1\\{%2\\}\\}", "\\{%1 %2\\}", "%1\\{%2\\}"};
463
 
    static const  int expansionsmod1count = sizeof( expansionsMod1 ) / sizeof( expansionsMod1[0] );
464
 
    const char *expansionsMod2[] = {"\\{%1%2\\}", "%1%2\\{\\}", "%1%2"};
465
 
    static const  int expansionsmod2count = sizeof( expansionsMod2 ) / sizeof( expansionsMod2[0] );
466
 
 
467
 
    static const int modcharmappingdatalatexcount = sizeof( modcharmappingdatalatex ) / sizeof( modcharmappingdatalatex[ 0 ] ) ;
468
 
 
469
 
    static const struct EncoderLaTeXCharMapping
470
 
    {
471
 
        const char *regexp;
472
 
        unsigned int unicode;
473
 
        const char *latex;
474
 
    }
475
 
    charmappingdatalatex[] =
476
 
    {
477
 
        {"\\\\#", 0x0023, "\\#"},
478
 
        {"\\\\&", 0x0026, "\\&"},
479
 
        {"\\\\_", 0x005F, "\\_"},
480
 
        {"!`", 0x00A1, "!`"},
481
 
        {"\"<", 0x00AB, "\"<"},
482
 
        {"\">", 0x00BB, "\">"},
483
 
        {"[?]`", 0x00BF, "?`"},
484
 
        {"--", 0x2013, "--"}
485
 
    };
486
 
 
487
 
    static const int charmappingdatalatexcount = sizeof( charmappingdatalatex ) / sizeof( charmappingdatalatex[ 0 ] ) ;
488
 
 
489
 
    EncoderLaTeX::EncoderLaTeX()
490
 
    {
491
 
        buildCharMapping();
492
 
        buildCombinedMapping();
493
 
    }
494
 
 
495
 
    EncoderLaTeX::~EncoderLaTeX()
496
 
    {
497
 
        // nothing
498
 
    }
499
 
 
500
 
    QString EncoderLaTeX::decode( const QString & text )
501
 
    {
502
 
        const QString splitMarker = "|KBIBTEX|";
503
 
        QString result = text;
504
 
 
505
 
        /** Collect (all?) urls from the BibTeX file and store them in urls */
506
 
        /** Problem is that the replace function below will replace
507
 
          * character sequences in the URL rendering the URL invalid.
508
 
          * Later, all URLs will be replaced back to their original
509
 
          * in the hope nothing breaks ... */
510
 
        QStringList urls;
511
 
        QRegExp httpRegExp( "(ht|f)tp://[^\"} ]+" );
512
 
        httpRegExp.setMinimal( false );
513
 
        int pos = 0;
514
 
        while ( pos >= 0 )
515
 
        {
516
 
            pos = httpRegExp.search( result, pos );
517
 
            if ( pos >= 0 )
518
 
            {
519
 
                ++pos;
520
 
                QString url = httpRegExp.cap( 0 );
521
 
                urls << url;
522
 
            }
523
 
        }
524
 
 
525
 
        decomposedUTF8toLaTeX( result );
526
 
 
527
 
        /** split text into math and non-math regions */
528
 
        QStringList intermediate = QStringList::split( '$', result, true );
529
 
        QStringList::Iterator it = intermediate.begin();
530
 
        while ( it != intermediate.end() )
531
 
        {
532
 
            /**
533
 
             * Sometimes we split strings like "\$", which is not intended.
534
 
             * So, we have to manually fix things by checking for strings
535
 
             * ending with "\" and append both the removed dollar sign and
536
 
             * the following string (which was never supposed to be an
537
 
             * independent string). Finally, we remove the unnecessary
538
 
             * string and continue.
539
 
             */
540
 
            if (( *it ).endsWith( "\\" ) )
541
 
            {
542
 
                QStringList::Iterator cur = it;
543
 
                ++it;
544
 
                ( *cur ).append( '$' ).append( *it );
545
 
                intermediate.remove( it );
546
 
                it = cur;
547
 
            }
548
 
            else
549
 
                ++it;
550
 
        }
551
 
 
552
 
        qApp->processEvents();
553
 
 
554
 
        result = "";
555
 
        for ( QStringList::Iterator it = intermediate.begin(); it != intermediate.end(); ++it )
556
 
        {
557
 
            if ( !result.isEmpty() ) result.append( splitMarker );
558
 
            result.append( *it );
559
 
 
560
 
            ++it;
561
 
            if ( it == intermediate.end() )
562
 
                break;
563
 
 
564
 
            if (( *it ).length() > 256 )
565
 
                qDebug( "Very long math equation using $ found, maybe due to broken inline math: %s", ( *it ).left( 48 ).latin1() );
566
 
        }
567
 
 
568
 
        qApp->processEvents();
569
 
 
570
 
        for ( QValueList<CharMappingItem>::ConstIterator cmit = m_charMapping.begin(); cmit != m_charMapping.end(); ++cmit )
571
 
            result.replace(( *cmit ).regExp, ( *cmit ).unicode );
572
 
 
573
 
        qApp->processEvents();
574
 
 
575
 
        QStringList transformed = QStringList::split( splitMarker, result, true );
576
 
 
577
 
        qApp->processEvents();
578
 
 
579
 
        result = "";
580
 
        for ( QStringList::Iterator itt = transformed.begin(), iti = intermediate.begin(); itt != transformed.end() && iti != intermediate.end(); ++itt, ++iti )
581
 
        {
582
 
            result.append( *itt );
583
 
 
584
 
            ++iti;
585
 
            if ( iti == intermediate.end() )
586
 
                break;
587
 
 
588
 
            result.append( "$" ).append( *iti ).append( "$" );
589
 
        }
590
 
 
591
 
        qApp->processEvents();
592
 
 
593
 
        /** Reinserting original URLs as explained above */
594
 
        pos = 0;
595
 
        int idx = 0;
596
 
        while ( pos >= 0 )
597
 
        {
598
 
            pos = httpRegExp.search( result, pos );
599
 
            if ( pos >= 0 )
600
 
            {
601
 
                ++pos;
602
 
                int len = httpRegExp.cap( 0 ).length();
603
 
                result = result.left( pos - 1 ).append( urls[idx++] ).append( result.mid( pos + len - 1 ) );
604
 
            }
605
 
        }
606
 
 
607
 
        return result;
608
 
    }
609
 
 
610
 
    QString EncoderLaTeX::encode( const QString & text )
611
 
    {
612
 
        const QString splitMarker = "|KBIBTEX|";
613
 
        QString result = text;
614
 
 
615
 
        /** Collect (all?) urls from the BibTeX file and store them in urls */
616
 
        /** Problem is that the replace function below will replace
617
 
          * character sequences in the URL rendering the URL invalid.
618
 
          * Later, all URLs will be replaced back to their original
619
 
          * in the hope nothing breaks ... */
620
 
        QStringList urls;
621
 
        QRegExp httpRegExp( "(ht|f)tp://[^\"} ]+" );
622
 
        httpRegExp.setMinimal( false );
623
 
        int pos = 0;
624
 
        while ( pos >= 0 )
625
 
        {
626
 
            pos = httpRegExp.search( result, pos );
627
 
            if ( pos >= 0 )
628
 
            {
629
 
                ++pos;
630
 
                QString url = httpRegExp.cap( 0 );
631
 
                urls << url;
632
 
            }
633
 
        }
634
 
 
635
 
        /** split text into math and non-math regions */
636
 
        QStringList intermediate = QStringList::split( '$', result, true );
637
 
        QStringList::Iterator it = intermediate.begin();
638
 
        while ( it != intermediate.end() )
639
 
        {
640
 
            /**
641
 
             * Sometimes we split strings like "\$", which is not intended.
642
 
             * So, we have to manually fix things by checking for strings
643
 
             * ending with "\" and append both the removed dollar sign and
644
 
             * the following string (which was never supposed to be an
645
 
             * independent string). Finally, we remove the unnecessary
646
 
             * string and continue.
647
 
             */
648
 
            if (( *it ).endsWith( "\\" ) )
649
 
            {
650
 
                QStringList::Iterator cur = it;
651
 
                ++it;
652
 
                ( *cur ).append( '$' ).append( *it );
653
 
                intermediate.remove( it );
654
 
                it = cur;
655
 
            }
656
 
            else
657
 
                ++it;
658
 
        }
659
 
 
660
 
        qApp->processEvents();
661
 
 
662
 
        result = "";
663
 
        for ( QStringList::Iterator it = intermediate.begin(); it != intermediate.end(); ++it )
664
 
        {
665
 
            if ( !result.isEmpty() ) result.append( splitMarker );
666
 
            result.append( *it );
667
 
 
668
 
            ++it;
669
 
            if ( it == intermediate.end() )
670
 
                break;
671
 
 
672
 
            if (( *it ).length() > 256 )
673
 
                qDebug( "Very long math equation using $ found, maybe due to broken inline math: %s", ( *it ).left( 48 ).latin1() );
674
 
        }
675
 
 
676
 
        qApp->processEvents();
677
 
 
678
 
        for ( QValueList<CharMappingItem>::ConstIterator cmit = m_charMapping.begin(); cmit != m_charMapping.end(); ++cmit )
679
 
            result.replace(( *cmit ).unicode, ( *cmit ).latex );
680
 
 
681
 
        qApp->processEvents();
682
 
 
683
 
        QStringList transformed = QStringList::split( splitMarker, result, true );
684
 
 
685
 
        qApp->processEvents();
686
 
 
687
 
        result = "";
688
 
        for ( QStringList::Iterator itt = transformed.begin(), iti = intermediate.begin(); itt != transformed.end() && iti != intermediate.end(); ++itt, ++iti )
689
 
        {
690
 
            result.append( *itt );
691
 
 
692
 
            ++iti;
693
 
            if ( iti == intermediate.end() )
694
 
                break;
695
 
 
696
 
            result.append( "$" ).append( *iti ).append( "$" );
697
 
        }
698
 
 
699
 
        qApp->processEvents();
700
 
 
701
 
        /** \url accepts unquotet & and _
702
 
           May introduce new problem tough */
703
 
        if ( result.contains( "\\url{" ) )
704
 
            result.replace( "\\&", "&" ).replace( "\\_", "_" ).replace( QChar( 0x2013 ), "--" ).replace( "\\#", "#" );
705
 
 
706
 
        decomposedUTF8toLaTeX( result );
707
 
 
708
 
        /** Reinserting original URLs as explained above */
709
 
        pos = 0;
710
 
        int idx = 0;
711
 
        while ( pos >= 0 )
712
 
        {
713
 
            pos = httpRegExp.search( result, pos );
714
 
            if ( pos >= 0 )
715
 
            {
716
 
                ++pos;
717
 
                int len = httpRegExp.cap( 0 ).length();
718
 
                result = result.left( pos - 1 ).append( urls[idx++] ).append( result.mid( pos + len - 1 ) );
719
 
            }
720
 
        }
721
 
 
722
 
        return result;
723
 
    }
724
 
 
725
 
    QString EncoderLaTeX::encode( const QString &text, const QChar &replace )
726
 
    {
727
 
        QString result = text;
728
 
        for ( QValueList<CharMappingItem>::ConstIterator it = m_charMapping.begin(); it != m_charMapping.end(); ++it )
729
 
            if (( *it ).unicode == replace )
730
 
                result.replace(( *it ).unicode, ( *it ).latex );
731
 
        return result;
732
 
    }
733
 
 
734
 
    QString EncoderLaTeX::encodeSpecialized( const QString & text, const EntryField::FieldType fieldType )
735
 
    {
736
 
        QString result = encode( text );
737
 
 
738
 
        switch ( fieldType )
739
 
        {
740
 
        case EntryField::ftPages:
741
 
            result.replace( QChar( 0x2013 ), "--" );
742
 
            break;
743
 
 
744
 
        case EntryField::ftURL:
745
 
            result.replace( "\\&", "&" ).replace( "\\_", "_" ).replace( QChar( 0x2013 ), "--" ).replace( "\\#", "#" );
746
 
            break;
747
 
 
748
 
        default:
749
 
            break;
750
 
        }
751
 
 
752
 
        return result;
753
 
    }
754
 
 
755
 
    QString& EncoderLaTeX::decomposedUTF8toLaTeX( QString &text )
756
 
    {
757
 
        for ( QValueList<CombinedMappingItem>::Iterator it = m_combinedMapping.begin(); it != m_combinedMapping.end(); ++it )
758
 
        {
759
 
            int i = ( *it ).regExp.search( text );
760
 
            while ( i >= 0 )
761
 
            {
762
 
                QString a = ( *it ).regExp.cap( 1 );
763
 
                text = text.left( i ) + "\\" + ( *it ).latex + "{" + a + "}" + text.mid( i + 2 );
764
 
                i = ( *it ).regExp.search( text, i + 1 );
765
 
            }
766
 
        }
767
 
 
768
 
        return text;
769
 
    }
770
 
 
771
 
    void EncoderLaTeX::buildCombinedMapping()
772
 
    {
773
 
        for ( int i = 0; i < decompositionscount; i++ )
774
 
        {
775
 
            CombinedMappingItem item;
776
 
            item.regExp = QRegExp( "(.)" + QString( QChar( decompositions[i].unicode ) ) );
777
 
            item.latex = decompositions[i].latexCommand;
778
 
            m_combinedMapping.append( item );
779
 
        }
780
 
    }
781
 
 
782
 
    void EncoderLaTeX::buildCharMapping()
783
 
    {
784
 
        /** encoding and decoding for digraphs such as -- or ?` */
785
 
        for ( int i = 0; i < charmappingdatalatexcount; i++ )
786
 
        {
787
 
            CharMappingItem charMappingItem;
788
 
            charMappingItem.regExp = QRegExp( charmappingdatalatex[ i ].regexp );
789
 
            charMappingItem.unicode = QChar( charmappingdatalatex[ i ].unicode );
790
 
            charMappingItem.latex = QString( charmappingdatalatex[ i ].latex );
791
 
            m_charMapping.append( charMappingItem );
792
 
        }
793
 
 
794
 
        /** encoding and decoding for commands such as \AA or \ss */
795
 
        for ( int i = 0; i < commandmappingdatalatexcount; ++i )
796
 
        {
797
 
            /** different types of writing such as {\AA} or \AA{} possible */
798
 
            for ( int j = 0; j < expansionscmdcount; ++j )
799
 
            {
800
 
                CharMappingItem charMappingItem;
801
 
                charMappingItem.regExp = QRegExp( QString( expansionsCmd[j] ).arg( commandmappingdatalatex[i].letters ) );
802
 
                charMappingItem.unicode = QChar( commandmappingdatalatex[i].unicode );
803
 
                if ( charMappingItem.regExp.numCaptures() > 0 )
804
 
                    charMappingItem.unicode += QString( "\\1" );
805
 
                charMappingItem.latex = QString( "{\\%1}" ).arg( commandmappingdatalatex[i].letters );
806
 
                m_charMapping.append( charMappingItem );
807
 
            }
808
 
        }
809
 
 
810
 
        /** encoding and decoding for letters such as \"a */
811
 
        for ( int i = 0; i < modcharmappingdatalatexcount; ++i )
812
 
        {
813
 
            QString modifierRegExp = QString( modcharmappingdatalatex[i].modifier );
814
 
            QString modifier = modifierRegExp;
815
 
            modifier.replace( "\\^", "^" ).replace( "\\\\", "\\" );
816
 
 
817
 
            /** first batch of replacement rules, where no separator is required between modifier and character (e.g. \"a) */
818
 
            if ( !modifierRegExp.at( modifierRegExp.length() - 1 ).isLetter() )
819
 
                for ( int j = 0; j < expansionsmod2count; ++j )
820
 
                {
821
 
                    CharMappingItem charMappingItem;
822
 
                    charMappingItem.regExp = QRegExp( QString( expansionsMod2[j] ).arg( modifierRegExp ).arg( modcharmappingdatalatex[i].letter ) );
823
 
                    charMappingItem.unicode = QChar( modcharmappingdatalatex[i].unicode );
824
 
                    charMappingItem.latex = QString( "{%1%2}" ).arg( modifier ).arg( modcharmappingdatalatex[i].letter );
825
 
                    m_charMapping.append( charMappingItem );
826
 
                }
827
 
 
828
 
            /** second batch of replacement rules, where a separator is required between modifier and character (e.g. \v{g}) */
829
 
            for ( int j = 0; j < expansionsmod1count; ++j )
830
 
            {
831
 
                CharMappingItem charMappingItem;
832
 
                charMappingItem.regExp = QRegExp( QString( expansionsMod1[j] ).arg( modifierRegExp ).arg( modcharmappingdatalatex[i].letter ) );
833
 
                charMappingItem.unicode = QChar( modcharmappingdatalatex[i].unicode );
834
 
                charMappingItem.latex = QString( "%1{%2}" ).arg( modifier ).arg( modcharmappingdatalatex[i].letter );
835
 
                m_charMapping.append( charMappingItem );
836
 
            }
837
 
        }
838
 
    }
839
 
 
840
 
    EncoderLaTeX* EncoderLaTeX::currentEncoderLaTeX()
841
 
    {
842
 
        if ( encoderLaTeX == NULL )
843
 
            encoderLaTeX = new EncoderLaTeX();
844
 
 
845
 
        return encoderLaTeX;
846
 
    }
847
 
 
848
 
    void EncoderLaTeX::deleteCurrentEncoderLaTeX()
849
 
    {
850
 
        if ( encoderLaTeX != NULL )
851
 
        {
852
 
            delete encoderLaTeX;
853
 
            encoderLaTeX = NULL;
854
 
        }
855
 
    }
856
 
 
857
 
    char EncoderLaTeX::unicodeToASCII( unsigned int unicode )
858
 
    {
859
 
        if ( unicode < 128 ) return ( char )unicode;
860
 
        for ( int i = 0; i < modcharmappingdatalatexcount; ++i )
861
 
            if ( modcharmappingdatalatex[i].unicode == unicode )
862
 
                return *modcharmappingdatalatex[i].letter;
863
 
        return '?';
864
 
    }
865
 
 
866
 
}