File size: 8,367 Bytes
745e7ed
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
// Maths utilitary functions,
// adapted from latex_envs, see github.com/jfbercher/jupyter_latex_envs

/****************************************************************************************************************
* Series of elementary functions for manipulating nested environments
* needed to do that because standard regular expressions are not well suited for recursive things
****************************************************************************************************************/
var OPENINGENV = '#!<',
    OPENINGENVre = new RegExp(OPENINGENV, 'g');
var CLOSINGENV = '#!>',
    CLOSINGENVre = new RegExp(CLOSINGENV, 'g');

function envSearch(text, env_open, env_close) {
    var reg = new RegExp(env_open + '[\\S\\s]*?' + env_close, 'gm');
    var start = text.match(reg);
    var env_open_re = new RegExp(env_open);
    var env_close_re = new RegExp(env_close);
    var retval;
    var r = "";
    if (typeof(start[0]) != 'undefined' && start[0] != null) {
        var r = start[0].substr(1)
    }
    var out = env_open_re.test(r) //test if there exists an opening env at level +1 
        //of the same kind inside

    if (out) { //in such case: replace the new opening at level +1 and the closing at level
        var rnew = r.replace(env_close_re, CLOSINGENV).replace(env_open_re, OPENINGENV)
        .replace(/\$\$/g,"!@$!@$") //last replace is because "$$" in the replacement string does not work
        var text = text.replace(r, rnew).replace(/!@\$/g,"$");
        if (env_open_re.test(rnew)) { // if it remains nested envs, call the function again
            retval = envSearch(text, env_open, env_close);
            if (retval !== undefined) {
                text = retval;
            }
        }
        return text
    }
    return text
}

function nestedEnvSearch(text, env_open, env_close) {
    var regtest = new RegExp(env_open + '[\\S\\s]*?' + env_close);
    var inmatches = text.match(regtest);
    if (inmatches != null) {
        for (i = 0; i < inmatches.length; i++) 
            inmatches[i] = inmatches[i].replace(/\*/g, '\\*')
        var n = 0;
        env_open = env_open.replace(/\([\\\+\S ]*?\)/g, function() {
            return inmatches[++n]
        })
        env_close = env_close.replace(/\\\d/g, function(x) {
            return inmatches[parseInt(x.substr(1))]
        })
        var output = envSearch(text, env_open, env_close)
        var matches = output.match(env_open + '([\\S\\s]*?)' + env_close);
        matches[0] = matches[0].replace(OPENINGENVre, env_open.replace('\\\\', '\\'))
            .replace(CLOSINGENVre, env_close.replace('\\\\', '\\'))
        matches[1] = matches[1].replace(OPENINGENVre, env_open.replace('\\\\', '\\'))
            .replace(CLOSINGENVre, env_close.replace('\\\\', '\\'))
        var result = [matches[0], inmatches[1], matches[1]]
        for (i = 0; i < result.length; i++) 
            result[i] = result[i].replace(/\\\*\}/g, '*}')
        return result;
    } else return [];
}


function envReplaceApply(text, matches, replacement) {
    var output;
    if (matches.length != 0) {
        if (replacement instanceof Function) {
            output = text.replace(matches[0], 
                replacement(matches[0], matches[1], matches[2])
                .replace(/\$\$/g,"!@$!@$")).replace(/!@\$/g,"$") 
                //last line because "$$" in the replacement string does not work
        } else if (typeof replacement == "string") {
            output = text.replace(matches[0], replacement)
        }
        return output
    } else {
        return text;
    }
}

function nestedEnvReplace(text, env_open, env_close, replacement, flags) {
    var list_of_matches = [];
    var count = 200; //protection
    var matches = nestedEnvSearch(text, env_open, env_close);
    if (flags == undefined) {
        return envReplaceApply(text, matches, replacement)
    } else if (flags.indexOf('g') !== -1) {
        var tmp_text = text; // tmp text
        while (count-- > 0 & matches.length != 0) {
            list_of_matches.push(matches[0]);
            tmp_text = tmp_text.replace(matches[0], ""); //suppress from tmp_text
            text = envReplaceApply(text, matches, replacement);
            matches = nestedEnvSearch(tmp_text, env_open, env_close);
        }
        return text;
    } else {
        return text;
    }
}

var textEnvs = {'theorem':'theorem', 'lemma':'lemma', 'remark':'remark', 
'example':'example', 'exercise':'exercise', 'corollary':'corollary', 
'proposition':'proposition', 'definition':'definition','problem':'problem', 
'proof':'proof', 'property':'property', 'itemize':'itemize', 'enumerate':'enumerate'}

var textCmds = {'textbf':'textbf', 'textit':'textit', 'underline':'underline', 
'texttt':'texttt', 'textem':'textem', 'emph':'emph'}
//label and ref not added because their content shall not be translated

var OPENmath = 'mathid'//'\u003cmathid',
    OPENmathRe = new RegExp(OPENmath, 'g');
var CLOSEmath = ''//'\u003e',
    CLOSEmathRe = new RegExp(CLOSEmath, 'g');

function removeMaths(text){
    var math=[];
    function replacement(m0,m1,m2) {
        if (m1 in textEnvs){
            math.push('\\begin{'+m1+'}'); var id_beg = math.length;
            math.push('\\end{'+m1+'}'); var id_end = math.length;
            m2 = nestedEnvReplace(m2, '\\\\begin{(\\w+\\\*?)}', '\\\\end{\\1}', replacement, 'g')
            return OPENmath + id_beg + CLOSEmath + m2 + OPENmath + id_end + CLOSEmath;
        }
        else if (m1 in textCmds){
            math.push('\\' + m1 + '{')
            math.push('}')
            return OPENmath + String(math.length - 1) + CLOSEmath + m2 + OPENmath + math.length + CLOSEmath;
        }
        else {
            math.push(m0)
            return OPENmath + math.length + CLOSEmath;
        }
    }
    text = nestedEnvReplace(text, '\\\\begin{(\\w+\\\*?)}', '\\\\end{\\1}', replacement, 'g')    
    text = text.replace(/\\\[([\S\s]*?)\\\]/gm,replacement)
    text = text.replace(/\\\(([\S\s]*?)\\\)/gm,replacement)
    text = text.replace(/\$\$([\S\s]*?)\$\$/gm,replacement)    
    text = text.replace(/\$([\S\s]*?)\$/gm,replacement)    
    text = text.replace(/\\item/gm,replacement)  
    text = text.replace(/\\([\S]*?){([\S\s]*?)}/gm,replacement) //textcmd      
    return [math, text]
}

function restoreMaths(math_and_text) {
    var math = math_and_text[0];
    var text = math_and_text[1];
    var newtext;
    var OPENmathUnicode = escape(OPENmath).replace(/%u([A-F0-9]{4})|%([A-F0-9]{2})/g, function(_, u, x) { return "\\\\u" + (u || '00' + x).toLowerCase() });
    var CLOSEmathUnicode = escape(CLOSEmath).replace(/%u([A-F0-9]{4})|%([A-F0-9]{2})/g, function(_, u, x) { return "\\\\u" + (u || '00' + x).toLowerCase() });
    var mathDetectRe = new RegExp(OPENmathUnicode+'\\s*?(\\d+)\\s*?'+CLOSEmathUnicode, 'gim');
    var cont = true;
    while (cont) {
        var newtext = text.replace(mathDetectRe, function(wholeMatch, n) {
            return math[n - 1];
                });
        /*var newtext = newtext.replace(/\\u003cmathiid\s*?(\d+)\s*?\\u003e/gim, function(wholeMatch, n) {
            return math[n - 1];
                });    */    
        cont = text !== newtext; //recurse in text (possible nesting -- just one level)
        text=newtext;
    }
    return text;
}

var OPENhtml = 'htmlid'
    OPENhtmlRe = new RegExp(OPENhtml, 'g');
var CLOSEhtml = ''//'\u003e',
    CLOSEhtmlRe = new RegExp(CLOSEhtml, 'g');

function removeHtml(text) {
    var html = [];
    function replacement(m0, m1) {
        html.push(m0)
        return OPENhtml + html.length + CLOSEhtml;

    }
    text = text.replace(/<(\S[\S\s]*?)\S>/gm, replacement)
    return [html, text]
}


function restoreHtml(html_and_text) {
    var html = html_and_text[0];
    var text = html_and_text[1];
    var newtext;
    var OPENhtmlUnicode = escape(OPENhtml).replace(/%u([A-F0-9]{4})|%([A-F0-9]{2})/g, function(_, u, x) {
        return "\\\\u" + (u || '00' + x).toLowerCase() });
    var CLOSEhtmlUnicode = escape(CLOSEhtml).replace(/%u([A-F0-9]{4})|%([A-F0-9]{2})/g, function(_, u, x) {
        return "\\\\u" + (u || '00' + x).toLowerCase() });
    var htmlDetectRe = new RegExp(OPENhtmlUnicode + '\\s*?(\\d+)\\s*?' + CLOSEhtmlUnicode, 'gim');
    text = text.replace(htmlDetectRe, function(wholeMatch, n) {
        return html[n - 1];
    });

    return text;
}