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