forked from ypsu/latex-to-unicode
-
Notifications
You must be signed in to change notification settings - Fork 1
/
latexify.pl
159 lines (138 loc) · 3.72 KB
/
latexify.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
use 5.010;
use utf8;
use strict;
use warnings;
use File::Basename;
use vars qw($VERSION %IRSSI);
$VERSION = '0.001';
%IRSSI = (
authors => 'Patrick Xia',
contact => '[email protected]',
name => 'latexify',
description => 'Latexify outgoing messages',
license => 'BSD',
url => 'none',
modules => 'File::Basename'
);
sub evt_send_text {
my ($line, $server_rec, $wi_item_rec) = @_;
if (convert($line) ne $line) {
Irssi::signal_emit('send text', convert($line), $server_rec, $wi_item_rec);
Irssi::signal_stop();
}
}
Irssi::signal_add_first('send text', 'evt_send_text');
# the following is just a direct no-brainer port of the python
# so some (or most!) of it may seem like a kludge
# except:
# - latex_symbols is now a hash and not a flat array of pairs
# - process_starting_modifiers is no longer implemented
my $data_loaded = 0;
my
(%latex_symbols,
%superscripts,
%subscripts,
%textbb,
%textbf,
%textit,
%textcal,
%textfrak,
%textmono);
my $dir = dirname(__FILE__);
my $pfx = "$dir/data";
sub convert($) {
my $s = $_[0];
unless ($data_loaded) {
load_data();
$data_loaded = 1;
}
my $ss = convert_single_symbol($s);
return $ss if $ss;
$s = convert_latex_symbols($s);
$s = apply_all_modifiers($s);
return $s;
}
# If s is just a latex code "alpha" or "beta" it converts it to its
# unicode representation.
sub convert_single_symbol($) {
return $latex_symbols{'\\' . $_[0]};
}
# Replace each "\alpha", "\beta" and similar latex symbols with
# their unicode representation.
sub convert_latex_symbols($) {
$_ = $_[0];
for my $key (reverse sort {length $a <=> length $b} keys %latex_symbols) {
s/\Q$key\E/$latex_symbols{$key}/g;
}
return $_;
}
sub apply_all_modifiers($) {
$_ = $_[0];
$_ = apply_modifier($_, "^", \%superscripts);
$_ = apply_modifier($_, "_", \%subscripts);
$_ = apply_modifier($_, "\\bb", \%textbb);
$_ = apply_modifier($_, "\\bf", \%textbf);
$_ = apply_modifier($_, "\\it", \%textit);
$_ = apply_modifier($_, "\\cal", \%textcal);
$_ = apply_modifier($_, "\\frak", \%textfrak);
$_ = apply_modifier($_, "\\mono", \%textmono);
return $_;
}
# Example: modifier = "^", D = superscripts
# This will search for the ^ signs and replace the next
# digit or (digits when {} is used) with its/their uppercase representation.
sub apply_modifier($$$) {
$_ = shift;
my $modifier = shift;
my %D = %{shift @_};
s/\Q$modifier\E/\^/;
# whoo why am I porting this state machine
my $newtext = "";
my ($mode_normal, $mode_modified, $mode_long) = 0..2;
my $mode = $mode_normal;
for (split//) {
if ($mode == $mode_normal && $_ eq '^') {
$mode = $mode_modified;
next;
} elsif ($mode == $mode_modified) {
if ($_ eq '{') {
$mode = $mode_long;
} elsif ($_ ne ' ') {
$newtext .= $D{$_} // $_;
$mode = $mode_normal;
}
next;
} elsif ($mode == $mode_long && $_ eq '}') {
$mode = $mode_normal;
next;
}
if ($mode == $mode_normal) {
$newtext .= $_;
} else {
$newtext .= $D{$_} // $_;
}
}
return $newtext;
}
sub load_data() {
load_dict("$pfx/symbols", \%latex_symbols);
load_dict("$pfx/subscripts", \%subscripts);
load_dict("$pfx/superscripts", \%superscripts);
load_dict("$pfx/textbb", \%textbb);
load_dict("$pfx/textbf", \%textbf);
load_dict("$pfx/textit", \%textit);
load_dict("$pfx/textcal", \%textcal);
load_dict("$pfx/textfrak", \%textfrak);
load_dict("$pfx/textmono", \%textmono);
}
sub load_dict($$) {
my $filename = shift;
my $D = shift;
open(my $f, "<", $filename) or die "cannot open $filename: $!";
while (<$f>) {
my @words = split;
my $code = $words[0];
my $val = $words[1];
$D->{$code} = $val;
}
}