]> git.lyx.org Git - lyx.git/blob - lib/lyx2lyx/lyx_2_3.py
support for Amharic, Asturian, Kannada and Khmer
[lyx.git] / lib / lyx2lyx / lyx_2_3.py
1 # -*- coding: utf-8 -*-
2 # This file is part of lyx2lyx
3 # -*- coding: utf-8 -*-
4 # Copyright (C) 2016 The LyX team
5 #
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 2
9 # of the License, or (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19
20 """ Convert files to the file format generated by lyx 2.3"""
21
22 import re, string
23 import unicodedata
24 import sys, os
25
26 # Uncomment only what you need to import, please.
27
28 from parser_tools import find_end_of#, find_token, find_tokens, \
29 #  find_token_exact, find_end_of_inset, find_end_of_layout, \
30 #  find_token_backwards, is_in_inset, get_value, get_quoted_value, \
31 #  del_token, check_token, get_option_value, get_bool_value
32
33 from parser_tools import find_token, find_end_of_inset, get_value, \
34      get_bool_value
35
36 from lyx2lyx_tools import add_to_preamble, put_cmd_in_ert
37 #  get_ert, lyx2latex, \
38 #  lyx2verbatim, length_in_bp, convert_info_insets
39 #  insert_to_preamble, latex_length, revert_flex_inset, \
40 #  revert_font_attrs, hex2ratio, str2bool
41
42 from lyx2lyx_tools import add_to_preamble, put_cmd_in_ert
43
44 ####################################################################
45 # Private helper functions
46
47
48
49 ###############################################################################
50 ###
51 ### Conversion and reversion routines
52 ###
53 ###############################################################################
54
55 def convert_microtype(document):
56     " Add microtype settings. "
57     i = find_token(document.header, "\\font_tt_scale" , 0)
58     if i == -1:
59         document.warning("Malformed LyX document: Can't find \\font_tt_scale.")
60         i = len(document.header) - 1
61
62     j = find_token(document.preamble, "\\usepackage{microtype}", 0)
63     if j == -1:
64         document.header.insert(i + 1, "\\use_microtype false")
65     else:
66         document.header.insert(i + 1, "\\use_microtype true")
67         del document.preamble[j]
68
69
70 def revert_microtype(document):
71     " Remove microtype settings. "
72     i = find_token(document.header, "\\use_microtype", 0)
73     if i == -1:
74         return
75     use_microtype = get_bool_value(document.header, "\\use_microtype" , i)
76     del document.header[i]
77     if use_microtype:
78         add_to_preamble(document, ["\\usepackage{microtype}"])
79
80
81 def convert_dateinset(document):
82     ' Convert date external inset to ERT '
83     i = 0
84     while True:
85         i = find_token(document.body, "\\begin_inset External", i)
86         if i == -1:
87             return
88         j = find_end_of_inset(document.body, i)
89         if j == -1:
90             document.warning("Malformed lyx document: Missing '\\end_inset' in convert_dateinset.")
91             i += 1
92             continue
93         if get_value(document.body, 'template', i, j) == "Date":
94             document.body[i : j + 1] = put_cmd_in_ert("\\today ")
95         i += 1
96         continue
97
98
99 def convert_ibranches(document):
100     ' Add "inverted 0" to branch insets'
101     i = 0
102     while True:
103         i = find_token(document.body, "\\begin_inset Branch", i)
104         if i == -1:
105             return
106         document.body.insert(i + 1, "inverted 0")
107         i += 1
108
109
110 def revert_ibranches(document):
111     ' Convert inverted branches to explicit anti-branches'
112     # Get list of branches
113     ourbranches = {}
114     i = 0
115     while True:
116         i = find_token(document.header, "\\branch", i)
117         if i == -1:
118             break
119         branch = document.header[i][8:].strip()
120         if document.header[i+1].startswith("\\selected "):
121             #document.warning(document.header[i+1])
122             #document.warning(document.header[i+1][10])
123             selected = int(document.header[i+1][10])
124         else:
125             document.warning("Malformed LyX document: No selection indicator for branch " + branch)
126             selected = 1
127             
128         # the value tells us whether the branch is selected
129         ourbranches[document.header[i][8:].strip()] = selected
130         i += 1
131
132     # Figure out what inverted branches, if any, have been used
133     # and convert them to "Anti-OldBranch"
134     ibranches = {}
135     i = 0
136     while True:
137         i = find_token(document.body, "\\begin_inset Branch", i)
138         if i == -1:
139             break
140         if not document.body[i+1].startswith("inverted "):
141             document.warning("Malformed LyX document: Missing 'inverted' tag!")
142             i += 1
143             continue
144         inverted = document.body[i+1][9]
145         #document.warning(document.body[i+1])
146
147         if inverted == "1":
148             branch = document.body[i][20:].strip()
149             #document.warning(branch)
150             if not branch in ibranches:
151                 antibranch = "Anti-" + branch
152                 while antibranch in ibranches:
153                     antibranch = "x" + antibranch
154                 ibranches[branch] = antibranch
155             else:
156                 antibranch = ibranches[branch]
157             #document.warning(antibranch)
158             document.body[i] = "\\begin_inset Branch " + antibranch
159
160         # remove "inverted" key
161         del document.body[i+1]
162         i += 1
163
164     # now we need to add the new branches to the header
165     for old, new in ibranches.iteritems():
166         i = find_token(document.header, "\\branch " + old, 0)
167         if i == -1:
168             document.warning("Can't find branch %s even though we found it before!" % (old))
169             continue
170         j = find_token(document.header, "\\end_branch", i)
171         if j == -1:
172             document.warning("Malformed LyX document! Can't find end of branch " + old)
173             continue
174         # ourbranches[old] - 1 inverts the selection status of the old branch
175         lines = ["\\branch " + new,
176                  "\\selected " + str(ourbranches[old] - 1)]
177         # these are the old lines telling us color, etc.
178         lines += document.header[i+2 : j+1]
179         document.header[i:i] = lines
180
181
182 def revert_beamer_article_styles(document):
183     " Include (scr)article styles in beamer article "
184
185     beamer_articles = ["article-beamer", "scrarticle-beamer"]
186     if document.textclass not in beamer_articles:
187         return
188
189     inclusion = "article.layout"
190     if document.textclass == "scrarticle-beamer":
191         inclusion = "scrartcl.layout"
192
193     while True:
194         i = find_token(document.header, "\\begin_local_layout", 0)
195         if i == -1:
196             k = find_token(document.header, "\\language", 0)
197             if k == -1:
198                 # this should not happen
199                 document.warning("Malformed LyX document! No \\language header found!")
200                 break
201             document.header[k-1 : k-1] = ["\\begin_local_layout", "\\end_local_layout"]
202             i = find_token(document.header, "\\begin_local_layout", 0)
203         if i != -1:
204             j = find_end_of(document.header, i, "\\begin_local_layout", "\\end_local_layout")
205             if j == -1:
206                 # this should not happen
207                 break
208
209             document.header[i+1 : i+1] = ["### Inserted by lyx2lyx (more [scr]article styles) ###",
210                                           "Input " + inclusion,
211                                           "Input beamer.layout",
212                                           "Provides geometry 0",
213                                           "Provides hyperref 0",
214                                           "DefaultFont",
215                                           "     Family                Roman",
216                                           "     Series                Medium",
217                                           "     Shape                 Up",
218                                           "     Size                  Normal",
219                                           "     Color                 None",
220                                           "EndFont",
221                                           "Preamble",
222                                           "     \\usepackage{beamerarticle,pgf}",
223                                           "     % this default might be overridden by plain title style",
224                                           "     \\newcommand\makebeamertitle{\\frame{\\maketitle}}%",
225                                           "     \\AtBeginDocument{",
226                                           "             \\let\\origtableofcontents=\\tableofcontents",
227                                           "             \\def\\tableofcontents{\\@ifnextchar[{\\origtableofcontents}{\\gobbletableofcontents}}",
228                                           "             \\def\\gobbletableofcontents#1{\\origtableofcontents}",
229                                           "     }",
230                                           "EndPreamble",
231                                           "### End of insertion by lyx2lyx (more [scr]article styles) ###"]
232         return
233
234
235 def convert_beamer_article_styles(document):
236     " Remove included (scr)article styles in beamer article "
237
238     beamer_articles = ["article-beamer", "scrarticle-beamer"]
239     if document.textclass not in beamer_articles:
240         return
241
242     while True:
243         i = find_token(document.header, "\\begin_local_layout", 0)
244         if i == -1:
245             return
246
247         j = find_end_of(document.header, i, "\\begin_local_layout", "\\end_local_layout")
248         if j == -1:
249             # this should not happen
250             break
251
252         k = find_token(document.header, "### Inserted by lyx2lyx (more [scr]article styles) ###", i, j)
253         if k != -1:
254             l = find_token(document.header, "### End of insertion by lyx2lyx (more [scr]article styles) ###", i, j)
255             if l == -1:
256                 # this should not happen
257                 document.warning("End of lyx2lyx local layout insertion not found!")
258                 break
259
260             document.header[k : l + 1] = []
261
262         return
263
264
265 def revert_bosnian(document):
266     "Set the document language to English but assure Bosnian output"
267
268     if document.language == "bosnian":
269         document.language = "english"
270         i = find_token(document.header, "\\language bosnian", 0)
271         if i != -1:
272             document.header[i] = "\\language english"
273         j = find_token(document.header, "\\language_package default", 0)
274         if j != -1:
275             document.header[j] = "\\language_package babel"
276         k = find_token(document.header, "\\options", 0)
277         if k != -1:
278             document.header[k] = document.header[k].replace("\\options", "\\options bosnian,")
279         else:
280             l = find_token(document.header, "\\use_default_options", 0)
281             document.header.insert(l + 1, "\\options bosnian")
282
283
284 def revert_friulan(document):
285     "Set the document language to English but assure Friulan output"
286
287     if document.language == "friulan":
288         document.language = "english"
289         i = find_token(document.header, "\\language friulan", 0)
290         if i != -1:
291             document.header[i] = "\\language english"
292         j = find_token(document.header, "\\language_package default", 0)
293         if j != -1:
294             document.header[j] = "\\language_package babel"
295         k = find_token(document.header, "\\options", 0)
296         if k != -1:
297             document.header[k] = document.header[k].replace("\\options", "\\options friulan,")
298         else:
299             l = find_token(document.header, "\\use_default_options", 0)
300             document.header.insert(l + 1, "\\options friulan")
301
302
303 def revert_macedonian(document):
304     "Set the document language to English but assure Macedonian output"
305
306     if document.language == "macedonian":
307         document.language = "english"
308         i = find_token(document.header, "\\language macedonian", 0)
309         if i != -1:
310             document.header[i] = "\\language english"
311         j = find_token(document.header, "\\language_package default", 0)
312         if j != -1:
313             document.header[j] = "\\language_package babel"
314         k = find_token(document.header, "\\options", 0)
315         if k != -1:
316             document.header[k] = document.header[k].replace("\\options", "\\options macedonian,")
317         else:
318             l = find_token(document.header, "\\use_default_options", 0)
319             document.header.insert(l + 1, "\\options macedonian")
320
321
322 def revert_piedmontese(document):
323     "Set the document language to English but assure Piedmontese output"
324
325     if document.language == "piedmontese":
326         document.language = "english"
327         i = find_token(document.header, "\\language piedmontese", 0)
328         if i != -1:
329             document.header[i] = "\\language english"
330         j = find_token(document.header, "\\language_package default", 0)
331         if j != -1:
332             document.header[j] = "\\language_package babel"
333         k = find_token(document.header, "\\options", 0)
334         if k != -1:
335             document.header[k] = document.header[k].replace("\\options", "\\options piedmontese,")
336         else:
337             l = find_token(document.header, "\\use_default_options", 0)
338             document.header.insert(l + 1, "\\options piedmontese")
339
340
341 def revert_romansh(document):
342     "Set the document language to English but assure Romansh output"
343
344     if document.language == "romansh":
345         document.language = "english"
346         i = find_token(document.header, "\\language romansh", 0)
347         if i != -1:
348             document.header[i] = "\\language english"
349         j = find_token(document.header, "\\language_package default", 0)
350         if j != -1:
351             document.header[j] = "\\language_package babel"
352         k = find_token(document.header, "\\options", 0)
353         if k != -1:
354             document.header[k] = document.header[k].replace("\\options", "\\options romansh,")
355         else:
356             l = find_token(document.header, "\\use_default_options", 0)
357             document.header.insert(l + 1, "\\options romansh")
358
359
360 def revert_amharic(document):
361     "Set the document language to English but assure Amharic output"
362
363     if document.language == "amharic":
364         document.language = "english"
365         i = find_token(document.header, "\\language amharic", 0)
366         if i != -1:
367             document.header[i] = "\\language english"
368         j = find_token(document.header, "\\language_package default", 0)
369         if j != -1:
370             document.header[j] = "\\language_package default"
371         add_to_preamble(document, ["\\AtBeginDocument{\setotherlanguage{amharic}}"])
372         document.body[2 : 2] = ["\\begin_layout Standard",
373                                 "\\begin_inset ERT", "status open", "",
374                                 "\\begin_layout Plain Layout", "", "",
375                                 "\\backslash",
376                                 "resetdefaultlanguage{amharic}",
377                                 "\\end_layout", "", "\\end_inset", "", "",
378                                 "\\end_layout", ""]
379
380
381 def revert_asturian(document):
382     "Set the document language to English but assure Asturian output"
383
384     if document.language == "asturian":
385         document.language = "english"
386         i = find_token(document.header, "\\language asturian", 0)
387         if i != -1:
388             document.header[i] = "\\language english"
389         j = find_token(document.header, "\\language_package default", 0)
390         if j != -1:
391             document.header[j] = "\\language_package default"
392         add_to_preamble(document, ["\\AtBeginDocument{\setotherlanguage{asturian}}"])
393         document.body[2 : 2] = ["\\begin_layout Standard",
394                                 "\\begin_inset ERT", "status open", "",
395                                 "\\begin_layout Plain Layout", "", "",
396                                 "\\backslash",
397                                 "resetdefaultlanguage{asturian}",
398                                 "\\end_layout", "", "\\end_inset", "", "",
399                                 "\\end_layout", ""]
400
401
402 def revert_kannada(document):
403     "Set the document language to English but assure Kannada output"
404
405     if document.language == "kannada":
406         document.language = "english"
407         i = find_token(document.header, "\\language kannada", 0)
408         if i != -1:
409             document.header[i] = "\\language english"
410         j = find_token(document.header, "\\language_package default", 0)
411         if j != -1:
412             document.header[j] = "\\language_package default"
413         add_to_preamble(document, ["\\AtBeginDocument{\setotherlanguage{kannada}}"])
414         document.body[2 : 2] = ["\\begin_layout Standard",
415                                 "\\begin_inset ERT", "status open", "",
416                                 "\\begin_layout Plain Layout", "", "",
417                                 "\\backslash",
418                                 "resetdefaultlanguage{kannada}",
419                                 "\\end_layout", "", "\\end_inset", "", "",
420                                 "\\end_layout", ""]
421
422
423 def revert_khmer(document):
424     "Set the document language to English but assure Khmer output"
425
426     if document.language == "khmer":
427         document.language = "english"
428         i = find_token(document.header, "\\language khmer", 0)
429         if i != -1:
430             document.header[i] = "\\language english"
431         j = find_token(document.header, "\\language_package default", 0)
432         if j != -1:
433             document.header[j] = "\\language_package default"
434         add_to_preamble(document, ["\\AtBeginDocument{\setotherlanguage{khmer}}"])
435         document.body[2 : 2] = ["\\begin_layout Standard",
436                                 "\\begin_inset ERT", "status open", "",
437                                 "\\begin_layout Plain Layout", "", "",
438                                 "\\backslash",
439                                 "resetdefaultlanguage{khmer}",
440                                 "\\end_layout", "", "\\end_inset", "", "",
441                                 "\\end_layout", ""]
442
443
444 ##
445 # Conversion hub
446 #
447
448 supported_versions = ["2.3.0", "2.3"]
449 convert = [
450            [509, [convert_microtype]],
451            [510, [convert_dateinset]],
452            [511, [convert_ibranches]],
453            [512, [convert_beamer_article_styles]],
454            [513, []],
455            [514, []]
456           ]
457
458 revert =  [
459            [513, [revert_amharic, revert_asturian, revert_kannada, revert_khmer]],
460            [512, [revert_bosnian, revert_friulan, revert_macedonian, revert_piedmontese, revert_romansh]],
461            [511, [revert_beamer_article_styles]],
462            [510, [revert_ibranches]],
463            [509, []],
464            [508, [revert_microtype]]
465           ]
466
467
468 if __name__ == "__main__":
469     pass