File Coverage

blib/lib/LaTeX/ToUnicode/Tables.pm
Criterion Covered Total %
statement 10 10 100.0
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 14 100.0


line stmt bran cond sub pod time code
1             package LaTeX::ToUnicode::Tables;
2             BEGIN {
3 1     1   44 $LaTeX::ToUnicode::Tables::VERSION = '1.93';
4             }
5 1     1   6 use strict;
  1         2  
  1         30  
6 1     1   5 use warnings;
  1         2  
  1         52  
7             #ABSTRACT: Character tables for LaTeX::ToUnicode
8              
9 1     1   10 use utf8; # just for the german support
  1         2  
  1         8  
10              
11             # The replacement texts throughout this file must not use HTML markup,
12             # since any <>& may be converted to entities in the main convert()
13             # function in ToUnicode.pm.
14              
15              
16             # TeXnically not all of these are ligatures, but close enough.
17             # Order is important, so has to be a list, not a hash.
18             #
19             our @LIGATURES = (
20             "---" => '\x{2014}', # em dash
21             "--" => '\x{2013}', # en dash
22             "!`" => '\x{00A1}', # inverted exclam
23             "?`" => '\x{00A1}', # inverted question
24             "``" => '\x{201c}', # left double
25             "''" => '\x{201d}', # right double
26             "`" => '\x{2018}', # left single
27             "'" => '\x{2019}', # right single
28             );
29             # test text: em---dash, en--dash, exc!`am, quest?`ion, ``ld, rd'', `ls, rs'.
30             #
31             # Some additional ligatures supported in T1 encoding, but we won't (from
32             # tex-text.map):
33             # ,, -> DOUBLE LOW-9 QUOTATION MARK (U+201E)
34             # << -> LEFT POINTING GUILLEMET (U+00AB)
35             # >> -> RIGHT POINTING GUILLEMET (U+00BB)
36              
37             # for {\MARKUP ...} and {\MARKUPshape ...} and \textMARKUP{...}. Not
38             # every combination is defined (e.g., there is no \subscriptshape
39             # command), but we convert them all anyway (in convert_markups).
40             #
41             # LaTeX has more font axes that are not included here: md, ulc, sw, ssc,
42             # etc. See ltfntcmd.dtx and ltfssaxes.dtx if we ever want to try for
43             # completeness.
44             #
45             our %MARKUPS = (
46             'bf' => 'b',
47             'cal' => '',
48             'em' => 'em',
49             'french' => '', # polyglossia
50             'it' => 'i',
51             'rm' => '',
52             'sc' => '', # qqq should uppercasify
53             'sf' => '',
54             'sl' => 'i',
55             'small' => '',
56             'subscript' => 'sub', # i.e., \textsubscript
57             'superscript' => 'sup', # \textsuperscript
58             'tt' => 'tt',
59             );
60              
61             # More commands taking arguments that we want to handle.
62             #
63             our %ARGUMENT_COMMANDS = (
64             'emph' => ['\textem{', '}'], # \textem doesn't exist, but we handle it
65             'enquote' => ["`", "'"],
66             'natexlab' => ["", ""], # natbib
67             'path' => ['\texttt{', '}'], # ugh, might not be a braced argument
68             );
69              
70             # Non-alphabetic \COMMANDs, other than accents and special cases.
71             #
72             our %CONTROL_SYMBOLS = (
73             ' ' => ' ', # control space
74             "\t" => ' ', # control space
75             "\n" => '\x{0020}', # control space; use entity to avoid being trimmed
76             '!' => '', # negative thin space
77             # " umlaut
78             '#' => '#', # sharp sign
79             '$' => '$', # dollar sign
80             '%' => '%', # percent sign
81             '&' => '\x{0026}', # ampersand, entity to avoid html conflict
82             # ' acute accent
83             '(' => '', # start inline math
84             ')' => '', # end inline math
85             '*' => '', # discretionary multiplication
86             '+' => '', # tabbing: tab stop to right
87             ',' => '', # thin space
88             '-' => '', # discretionary hyphenation
89             # . overdot accent
90             '/' => '', # italic correction
91             # 0..9 undefined
92             ':' => '', # medium space
93             ';' => ' ', # thick space
94             '<' => '', # tabbing: text to left of margin
95             # = macron accent
96             '>' => '', # tabbing: next tab stop
97             # ? undefined
98             '@' => '', # end of sentence
99             # A..Z control words, not symbols
100             '[' => '', # start display math
101             '\\' => ' ', # line break, usually not in HTML
102             ']' => '', # end display math
103             # ^ circumflex accent
104             '_' => '_', # underscore
105             # ` grave accent
106             # a..z control words, not symbols
107             '{' => '\x{007b}', # lbrace
108             '|' => '\x{2225}', # parallel
109             '}' => '\x{007d}', # rbrace
110             # ~ tilde accent
111             );
112              
113             # Alphabetic \COMMANDs that map to nothing. This is simply
114             # interpolated into %CONTROL_WORDS (next), not used directly, so we
115             # redundantly specify the '' on every line.
116             #
117             our %CONTROL_WORDS_EMPTY = (
118             'begingroup' => '',
119             'bgroup' => '',
120             'checkcomma' => '',
121             #'cite' => '', # keep \cite undefined since it needs manual work
122             'clearpage' => '',
123             'doi' => '',
124             'egroup' => '',
125             'endgroup' => '',
126             'ensuremath' => '',
127             'hbox' => '',
128             'ignorespaces' => '',
129             'mbox' => '',
130             'medspace' => '',
131             'negmedspace' => '',
132             'negthickspace' => '',
133             'negthinspace' => '',
134             'newblock' => '',
135             'newpage' => '',
136             'nobreak' => '',
137             'noindent' => '',
138             'nolinkurl' => '',
139             'oldstylenums' => '',
140             'par' => '',
141             'pagebreak' => '',
142             'protect' => '',
143             'raggedright' => '',
144             'relax' => '',
145             'thinspace' => '',
146             'unskip' => '',
147             'urlprefix' => '',
148             );
149              
150             # Alphabetic commands, that expand to nothing (above) and to
151             # something (below).
152             #
153             our %CONTROL_WORDS = (
154             %CONTROL_WORDS_EMPTY,
155             'BibLaTeX' => 'BibLaTeX',
156             'BibTeX' => 'BibTeX',
157             'LaTeX' => 'LaTeX',
158             'LuaLaTeX' => 'LuaLaTeX',
159             'LuaTeX' => 'LuaTeX',
160             'MF' => 'Metafont',
161             'MP' => 'MetaPost',
162             'Omega' => '\x{03A9}',
163             'P' => '\x{00B6}',
164             'S' => '\x{00A7}',
165             'TeX' => 'TeX',
166             'XeLaTeX' => 'XeLaTeX',
167             'XeTeX' => 'XeTeX',
168             'allowbreak' => '\x{200B}', # zero width space to allow breaks
169             'ast' => '*',
170             'bullet' => '\x{2022}',
171             'dag' => '\x{2020}',
172             'dagger' => '\x{2020}',
173             'ddag' => '\x{2021}',
174             'ddagger' => '\x{2021}',
175             'dots' => '\x{2026}',
176             'epsilon' => '\x{03F5}',
177             'guillemetleft' => '\x{00AB}',
178             'guillemetright' => '\x{00BB}',
179             'hookleftarrow' => '\x{21A9}',
180             'hookrightarrow' => '\x{21AA}',
181             'ldots' => '\x{2026}',
182             'log' => 'log',
183             'omega' => '\x{03C9}',
184             'par' => "\n\n",
185             'parallel' => '\x{2016}',
186             'qquad' => ' ', # 2em space
187             'quad' => ' ', # em space
188             'textbackslash' => '\x{005C}', # entities so \ in output indicates
189             # untranslated TeX source
190             'textbraceleft' => '\x{007B}', # entities so our bare-brace removal
191             'textbraceright' => '\x{007D}', # skips them
192             'textdagger' => '\x{2020}',
193             'textddagger' => '\x{2020}',
194             'textgreater' => '\x{003E}',
195             'textless' => '\x{003C}',
196             'textquotedbl' => '"',
197             'thickspace' => ' ',
198             'varepsilon' => '\x{03B5}',
199             );
200              
201             # Control words (not symbols) that generate various non-English
202             # letters and symbols. Lots more could be added.
203             #
204             our %SYMBOLS = ( # Table 3.2 in Lamport, plus more
205             'AA' => '\x{00C5}', # A with ring
206             'aa' => '\x{00E5}',
207             'AE' => '\x{00C6}', # AE
208             'ae' => '\x{00E6}',
209             'DH' => '\x{00D0}', # ETH
210             'dh' => '\x{00F0}',
211             'DJ' => '\x{0110}', # D with stroke
212             'dj' => '\x{0111}',
213             'i' => '\x{0131}', # small dotless i
214             'L' => '\x{0141}', # L with stroke
215             'l' => '\x{0142}',
216             'NG' => '\x{014A}', # ENG
217             'ng' => '\x{014B}',
218             'OE' => '\x{0152}', # OE
219             'oe' => '\x{0153}',
220             'O' => '\x{00D8}', # O with stroke
221             'o' => '\x{00F8}',
222             'SS' => 'SS', # lately also U+1E9E, but SS seems good enough
223             'ss' => '\x{00DF}',
224             'TH' => '\x{00DE}', # THORN
225             'textordfeminine' => '\x{00AA}',
226             'textordmasculine' => '\x{00BA}',
227             "textquotesingle" => '\x{0027}',
228             'textregistered' => '\x{00AE}',
229             'th' => '\x{00FE}',
230             'TM' => '\x{2122}', # trade mark sign
231             );
232              
233             # Accent commands that are not alphabetic.
234             #
235             our %ACCENT_SYMBOLS = (
236             "\"" => { # with diaresis
237             A => '\x{00C4}',
238             E => '\x{00CB}',
239             H => '\x{1E26}',
240             I => '\x{00CF}',
241             O => '\x{00D6}',
242             U => '\x{00DC}',
243             W => '\x{1E84}',
244             X => '\x{1E8c}',
245             Y => '\x{0178}',
246             "\\I" => '\x{00CF}',
247             "\\i" => '\x{00EF}',
248             a => '\x{00E4}',
249             e => '\x{00EB}',
250             h => '\x{1E27}',
251             i => '\x{00EF}',
252             o => '\x{00F6}',
253             t => '\x{1E97}',
254             u => '\x{00FC}',
255             w => '\x{1E85}',
256             x => '\x{1E8d}',
257             y => '\x{00FF}',
258             },
259             "'" => { # with acute
260             A => '\x{00C1}',
261             AE => '\x{01FC}',
262             C => '\x{0106}',
263             E => '\x{00C9}',
264             G => '\x{01F4}',
265             I => '\x{00CD}',
266             K => '\x{1E30}',
267             L => '\x{0139}',
268             M => '\x{1E3E}',
269             N => '\x{0143}',
270             O => '\x{00D3}',
271             P => '\x{1E54}',
272             R => '\x{0154}',
273             S => '\x{015A}',
274             U => '\x{00DA}',
275             W => '\x{1E82}',
276             Y => '\x{00DD}',
277             Z => '\x{0179}',
278             "\\I" => '\x{00CD}',
279             "\\i" => '\x{00ED}',
280             a => '\x{00E1}',
281             ae => '\x{01FD}',
282             c => '\x{0107}',
283             e => '\x{00E9}',
284             g => '\x{01F5}',
285             i => '\x{00ED}',
286             k => '\x{1E31}',
287             l => '\x{013A}',
288             m => '\x{1E3f}',
289             n => '\x{0144}',
290             o => '\x{00F3}',
291             p => '\x{1E55}',
292             r => '\x{0155}',
293             s => '\x{015B}',
294             u => '\x{00FA}',
295             w => '\x{1E83}',
296             y => '\x{00FD}',
297             z => '\x{017A}',
298             },
299             "^" => { # with circumflex
300             A => '\x{00C2}',
301             C => '\x{0108}',
302             E => '\x{00CA}',
303             G => '\x{011C}',
304             H => '\x{0124}',
305             I => '\x{00CE}',
306             J => '\x{0134}',
307             O => '\x{00D4}',
308             R => 'R\x{0302}',
309             S => '\x{015C}',
310             U => '\x{00DB}',
311             W => '\x{0174}',
312             Y => '\x{0176}',
313             Z => '\x{1E90}',
314             "\\I" => '\x{00CE}',
315             "\\J" => '\x{0134}',
316             "\\i" => '\x{00EE}',
317             "\\j" => '\x{0135}',
318             a => '\x{00E2}',
319             c => '\x{0109}',
320             e => '\x{00EA}',
321             g => '\x{011D}',
322             h => '\x{0125}',
323             i => '\x{00EE}',
324             j => '\x{0135}',
325             o => '\x{00F4}',
326             s => '\x{015D}',
327             u => '\x{00FB}',
328             w => '\x{0175}',
329             y => '\x{0177}',
330             z => '\x{1E91}',
331             },
332             "`" => { # with grave
333             A => '\x{00C0}',
334             E => '\x{00C8}',
335             I => '\x{00CC}',
336             N => '\x{01F8}',
337             O => '\x{00D2}',
338             U => '\x{00D9}',
339             W => '\x{1E80}',
340             Y => '\x{1Ef2}',
341             "\\I" => '\x{00CC}',
342             "\\i" => '\x{00EC}',
343             a => '\x{00E0}',
344             e => '\x{00E8}',
345             i => '\x{00EC}',
346             n => '\x{01F9}',
347             o => '\x{00F2}',
348             u => '\x{00F9}',
349             w => '\x{1E81}',
350             y => '\x{1EF3}',
351             },
352             "." => { # with dot above
353             A => '\x{0226}',
354             B => '\x{1E02}',
355             C => '\x{010A}',
356             D => '\x{1E0A}',
357             E => '\x{0116}',
358             F => '\x{1E1E}',
359             G => '\x{0120}',
360             H => '\x{1E22}',
361             I => '\x{0130}',
362             M => '\x{1E40}',
363             N => '\x{1E44}',
364             O => '\x{022E}',
365             P => '\x{1E56}',
366             R => '\x{1E58}',
367             S => '\x{1E60}',
368             T => '\x{1E6a}',
369             W => '\x{1E86}',
370             X => '\x{1E8A}',
371             Y => '\x{1E8E}',
372             Z => '\x{017B}',
373             "\\I" => '\x{0130}',
374             a => '\x{0227}',
375             b => '\x{1E03}',
376             c => '\x{010B}',
377             d => '\x{1E0B}',
378             e => '\x{0117}',
379             f => '\x{1e1f}',
380             g => '\x{0121}',
381             h => '\x{1E23}',
382             m => '\x{1E41}',
383             n => '\x{1E45}',
384             o => '\x{022F}',
385             p => '\x{1E57}',
386             r => '\x{1E59}',
387             s => '\x{1E61}',
388             t => '\x{1E6b}',
389             w => '\x{1E87}',
390             x => '\x{1E8b}',
391             y => '\x{1E8f}',
392             z => '\x{017C}',
393             },
394             '=' => { # with macron
395             A => '\x{0100}',
396             AE => '\x{01E2}',
397             E => '\x{0112}',
398             G => '\x{1E20}',
399             I => '\x{012A}',
400             O => '\x{014C}',
401             U => '\x{016A}',
402             Y => '\x{0232}',
403             "\\I" => '\x{012A}',
404             "\\i" => '\x{012B}',
405             a => '\x{0101}',
406             ae => '\x{01E3}',
407             e => '\x{0113}',
408             g => '\x{1E21}',
409             i => '\x{012B}',
410             o => '\x{014D}',
411             u => '\x{016B}',
412             y => '\x{0233}',
413             },
414             "~" => { # with tilde
415             A => '\x{00C3}',
416             E => '\x{1EBC}',
417             I => '\x{0128}',
418             N => '\x{00D1}',
419             O => '\x{00D5}',
420             U => '\x{0168}',
421             V => '\x{1E7C}',
422             Y => '\x{1EF8}',
423             "\\I" => '\x{0128}',
424             "\\i" => '\x{0129}',
425             a => '\x{00E3}',
426             e => '\x{1EBD}',
427             i => '\x{0129}',
428             n => '\x{00F1}',
429             o => '\x{00F5}',
430             u => '\x{0169}',
431             v => '\x{1E7D}',
432             y => '\x{1EF9}',
433             },
434             );
435              
436             # Accent commands that are alphabetic.
437             #
438             our %ACCENT_LETTERS = (
439             "H" => { # with double acute
440             O => '\x{0150}',
441             U => '\x{0170}',
442             o => '\x{0151}',
443             u => '\x{0171}',
444             },
445             "c" => { # with cedilla
446             C => '\x{00C7}',
447             D => '\x{1E10}',
448             E => '\x{0228}',
449             G => '\x{0122}',
450             H => '\x{1E28}',
451             K => '\x{0136}',
452             L => '\x{013B}',
453             N => '\x{0145}',
454             R => '\x{0156}',
455             S => '\x{015E}',
456             T => '\x{0162}',
457             c => '\x{00E7}',
458             d => '\x{1E11}',
459             e => '\x{0229}',
460             g => '\x{0123}',
461             h => '\x{1E29}',
462             k => '\x{0137}',
463             l => '\x{013C}',
464             n => '\x{0146}',
465             r => '\x{0157}',
466             s => '\x{015F}',
467             t => '\x{0163}',
468             },
469             "d" => { # with dot below
470             A => '\x{1EA0}',
471             B => '\x{1E04}',
472             D => '\x{1E0C}',
473             E => '\x{1EB8}',
474             H => '\x{1E24}',
475             I => '\x{1ECA}',
476             K => '\x{1E32}',
477             L => '\x{1E36}',
478             M => '\x{1E42}',
479             N => '\x{1E46}',
480             O => '\x{1ECC}',
481             R => '\x{1E5A}',
482             S => '\x{1E62}',
483             T => '\x{1E6C}',
484             U => '\x{1EE4}',
485             V => '\x{1E7E}',
486             W => '\x{1E88}',
487             Y => '\x{1Ef4}',
488             Z => '\x{1E92}',
489             "\\I" => '\x{1ECA}',
490             "\\i" => '\x{1ECB}',
491             a => '\x{1EA1}',
492             b => '\x{1E05}',
493             d => '\x{1E0D}',
494             e => '\x{1EB9}',
495             h => '\x{1E25}',
496             i => '\x{1ECB}',
497             k => '\x{1E33}',
498             l => '\x{1E37}',
499             m => '\x{1E43}',
500             n => '\x{1E47}',
501             o => '\x{1ECD}',
502             r => '\x{1E5b}',
503             s => '\x{1E63}',
504             t => '\x{1E6D}',
505             u => '\x{1EE5}',
506             v => '\x{1E7F}',
507             w => '\x{1E89}',
508             y => '\x{1EF5}',
509             z => '\x{1E93}',
510             },
511             "h" => { # with hook above
512             A => '\x{1EA2}',
513             E => '\x{1EBA}',
514             I => '\x{1EC8}',
515             O => '\x{1ECe}',
516             U => '\x{1EE6}',
517             Y => '\x{1EF6}',
518             "\\I" => '\x{1EC8}',
519             "\\i" => '\x{1EC9}',
520             a => '\x{1EA3}',
521             e => '\x{1EBB}',
522             i => '\x{1EC9}',
523             o => '\x{1ECF}',
524             u => '\x{1EE7}',
525             y => '\x{1EF7}',
526             },
527             "k" => { # with ogonek
528             A => '\x{0104}',
529             E => '\x{0118}',
530             I => '\x{012E}',
531             O => '\x{01EA}',
532             U => '\x{0172}',
533             "\\I" => '\x{012E}',
534             "\\i" => '\x{012F}',
535             a => '\x{0105}',
536             e => '\x{0119}',
537             i => '\x{012F}',
538             o => '\x{01EB}',
539             u => '\x{0173}',
540             },
541             "r" => { # with ring above
542             A => '\x{00C5}',
543             U => '\x{016E}',
544             a => '\x{00E5}',
545             u => '\x{016F}',
546             w => '\x{1E98}',
547             y => '\x{1E99}',
548             },
549             "u" => { # with breve
550             A => '\x{0102}',
551             E => '\x{0114}',
552             G => '\x{011E}',
553             I => '\x{012C}',
554             O => '\x{014E}',
555             U => '\x{016C}',
556             "\\I" => '\x{012C}',
557             "\\i" => '\x{012D}',
558             a => '\x{0103}',
559             e => '\x{0115}',
560             g => '\x{011F}',
561             i => '\x{012D}',
562             o => '\x{014F}',
563             u => '\x{016D}',
564             },
565             "v" => { # with caron
566             A => '\x{01CD}',
567             C => '\x{010C}',
568             D => '\x{010E}',
569             DZ => '\x{01C4}',
570             E => '\x{011A}',
571             G => '\x{01E6}',
572             H => '\x{021E}',
573             I => '\x{01CF}',
574             K => '\x{01E8}',
575             L => '\x{013D}',
576             N => '\x{0147}',
577             O => '\x{01D1}',
578             R => '\x{0158}',
579             S => '\x{0160}',
580             T => '\x{0164}',
581             U => '\x{01D3}',
582             Z => '\x{017D}',
583             "\\I" => '\x{01CF}',
584             "\\i" => '\x{01D0}',
585             "\\j" => '\x{01F0}',
586             a => '\x{01CE}',
587             c => '\x{010D}',
588             d => '\x{010F}',
589             dz => '\x{01C6}',
590             e => '\x{011B}',
591             g => '\x{01E7}',
592             h => '\x{021F}',
593             i => '\x{01D0}',
594             j => '\x{01F0}',
595             k => '\x{01E9}',
596             l => '\x{013E}',
597             n => '\x{0148}',
598             o => '\x{01D2}',
599             r => '\x{0159}',
600             s => '\x{0161}',
601             t => '\x{0165}',
602             u => '\x{01D4}',
603             z => '\x{017E}',
604             },
605             );
606              
607             #
608             our %GERMAN = ( # for package `german'/`ngerman'
609             '"a' => 'ä',
610             '"A' => 'Ä',
611             '"e' => 'ë',
612             '"E' => 'Ë',
613             '"i' => 'ï',
614             '"I' => 'Ï',
615             '"o' => 'ö',
616             '"O' => 'Ö',
617             '"u' => 'ü',
618             '"U' => 'Ü',
619             '"s' => 'ß',
620             '"S' => 'SS',
621             '"z' => 'ß',
622             '"Z' => 'SZ',
623             '"ck' => 'ck', # old spelling: ck -> k-k
624             '"ff' => 'ff', # old spelling: ff -> ff-f
625             '"`' => '„',
626             "\"'" => '“',
627             '"<' => '«',
628             '">' => '»',
629             '"-' => '\x{00AD}', # soft hyphen
630             '""' => '\x{200B}', # zero width space
631             '"~' => '\x{2011}', # non-breaking hyphen
632             '"=' => '-',
633             '\glq' => '‚', # left german single quote
634             '\grq' => '‘', # right german single quote
635             '\flqq' => '«',
636             '\frqq' => '»',
637             '\dq' => '"',
638             );
639              
640             1;
641              
642             __END__