]> git.lyx.org Git - features.git/blob - lib/lyx2lyx/lyx_2_3.py
File format update after 418016bf792
[features.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_inputenc(document):
100     " Replace no longer supported input encoding settings. "
101     i = find_token(document.header, "\\inputenc", 0)
102     if i == -1:
103         return
104     if get_value(document.header, "\\inputencoding", i) == "pt254":
105         document.header[i] = "\\inputencoding pt154"
106     
107
108 def convert_ibranches(document):
109     ' Add "inverted 0" to branch insets'
110     i = 0
111     while True:
112         i = find_token(document.body, "\\begin_inset Branch", i)
113         if i == -1:
114             return
115         document.body.insert(i + 1, "inverted 0")
116         i += 1
117
118
119 def revert_ibranches(document):
120     ' Convert inverted branches to explicit anti-branches'
121     # Get list of branches
122     ourbranches = {}
123     i = 0
124     while True:
125         i = find_token(document.header, "\\branch", i)
126         if i == -1:
127             break
128         branch = document.header[i][8:].strip()
129         if document.header[i+1].startswith("\\selected "):
130             #document.warning(document.header[i+1])
131             #document.warning(document.header[i+1][10])
132             selected = int(document.header[i+1][10])
133         else:
134             document.warning("Malformed LyX document: No selection indicator for branch " + branch)
135             selected = 1
136             
137         # the value tells us whether the branch is selected
138         ourbranches[document.header[i][8:].strip()] = selected
139         i += 1
140
141     # Figure out what inverted branches, if any, have been used
142     # and convert them to "Anti-OldBranch"
143     ibranches = {}
144     i = 0
145     while True:
146         i = find_token(document.body, "\\begin_inset Branch", i)
147         if i == -1:
148             break
149         if not document.body[i+1].startswith("inverted "):
150             document.warning("Malformed LyX document: Missing 'inverted' tag!")
151             i += 1
152             continue
153         inverted = document.body[i+1][9]
154         #document.warning(document.body[i+1])
155
156         if inverted == "1":
157             branch = document.body[i][20:].strip()
158             #document.warning(branch)
159             if not branch in ibranches:
160                 antibranch = "Anti-" + branch
161                 while antibranch in ibranches:
162                     antibranch = "x" + antibranch
163                 ibranches[branch] = antibranch
164             else:
165                 antibranch = ibranches[branch]
166             #document.warning(antibranch)
167             document.body[i] = "\\begin_inset Branch " + antibranch
168
169         # remove "inverted" key
170         del document.body[i+1]
171         i += 1
172
173     # now we need to add the new branches to the header
174     for old, new in ibranches.iteritems():
175         i = find_token(document.header, "\\branch " + old, 0)
176         if i == -1:
177             document.warning("Can't find branch %s even though we found it before!" % (old))
178             continue
179         j = find_token(document.header, "\\end_branch", i)
180         if j == -1:
181             document.warning("Malformed LyX document! Can't find end of branch " + old)
182             continue
183         # ourbranches[old] - 1 inverts the selection status of the old branch
184         lines = ["\\branch " + new,
185                  "\\selected " + str(ourbranches[old] - 1)]
186         # these are the old lines telling us color, etc.
187         lines += document.header[i+2 : j+1]
188         document.header[i:i] = lines
189
190
191 def revert_beamer_article_styles(document):
192     " Include (scr)article styles in beamer article "
193
194     beamer_articles = ["article-beamer", "scrarticle-beamer"]
195     if document.textclass not in beamer_articles:
196         return
197
198     inclusion = "article.layout"
199     if document.textclass == "scrarticle-beamer":
200         inclusion = "scrartcl.layout"
201
202     while True:
203         i = find_token(document.header, "\\begin_local_layout", 0)
204         if i == -1:
205             k = find_token(document.header, "\\language", 0)
206             if k == -1:
207                 # this should not happen
208                 document.warning("Malformed LyX document! No \\language header found!")
209                 break
210             document.header[k-1 : k-1] = ["\\begin_local_layout", "\\end_local_layout"]
211             i = find_token(document.header, "\\begin_local_layout", 0)
212         if i != -1:
213             j = find_end_of(document.header, i, "\\begin_local_layout", "\\end_local_layout")
214             if j == -1:
215                 # this should not happen
216                 break
217
218             document.header[i+1 : i+1] = ["### Inserted by lyx2lyx (more [scr]article styles) ###",
219                                           "Input " + inclusion,
220                                           "Input beamer.layout",
221                                           "Provides geometry 0",
222                                           "Provides hyperref 0",
223                                           "DefaultFont",
224                                           "     Family                Roman",
225                                           "     Series                Medium",
226                                           "     Shape                 Up",
227                                           "     Size                  Normal",
228                                           "     Color                 None",
229                                           "EndFont",
230                                           "Preamble",
231                                           "     \\usepackage{beamerarticle,pgf}",
232                                           "     % this default might be overridden by plain title style",
233                                           "     \\newcommand\makebeamertitle{\\frame{\\maketitle}}%",
234                                           "     \\AtBeginDocument{",
235                                           "             \\let\\origtableofcontents=\\tableofcontents",
236                                           "             \\def\\tableofcontents{\\@ifnextchar[{\\origtableofcontents}{\\gobbletableofcontents}}",
237                                           "             \\def\\gobbletableofcontents#1{\\origtableofcontents}",
238                                           "     }",
239                                           "EndPreamble",
240                                           "### End of insertion by lyx2lyx (more [scr]article styles) ###"]
241         return
242
243
244 def convert_beamer_article_styles(document):
245     " Remove included (scr)article styles in beamer article "
246
247     beamer_articles = ["article-beamer", "scrarticle-beamer"]
248     if document.textclass not in beamer_articles:
249         return
250
251     while True:
252         i = find_token(document.header, "\\begin_local_layout", 0)
253         if i == -1:
254             return
255
256         j = find_end_of(document.header, i, "\\begin_local_layout", "\\end_local_layout")
257         if j == -1:
258             # this should not happen
259             break
260
261         k = find_token(document.header, "### Inserted by lyx2lyx (more [scr]article styles) ###", i, j)
262         if k != -1:
263             l = find_token(document.header, "### End of insertion by lyx2lyx (more [scr]article styles) ###", i, j)
264             if l == -1:
265                 # this should not happen
266                 document.warning("End of lyx2lyx local layout insertion not found!")
267                 break
268
269             document.header[k : l + 1] = []
270
271         return
272
273
274 def revert_bosnian(document):
275     "Set the document language to English but assure Bosnian output"
276
277     if document.language == "bosnian":
278         document.language = "english"
279         i = find_token(document.header, "\\language bosnian", 0)
280         if i != -1:
281             document.header[i] = "\\language english"
282         j = find_token(document.header, "\\language_package default", 0)
283         if j != -1:
284             document.header[j] = "\\language_package babel"
285         k = find_token(document.header, "\\options", 0)
286         if k != -1:
287             document.header[k] = document.header[k].replace("\\options", "\\options bosnian,")
288         else:
289             l = find_token(document.header, "\\use_default_options", 0)
290             document.header.insert(l + 1, "\\options bosnian")
291
292
293 def revert_friulan(document):
294     "Set the document language to English but assure Friulan output"
295
296     if document.language == "friulan":
297         document.language = "english"
298         i = find_token(document.header, "\\language friulan", 0)
299         if i != -1:
300             document.header[i] = "\\language english"
301         j = find_token(document.header, "\\language_package default", 0)
302         if j != -1:
303             document.header[j] = "\\language_package babel"
304         k = find_token(document.header, "\\options", 0)
305         if k != -1:
306             document.header[k] = document.header[k].replace("\\options", "\\options friulan,")
307         else:
308             l = find_token(document.header, "\\use_default_options", 0)
309             document.header.insert(l + 1, "\\options friulan")
310
311
312 def revert_macedonian(document):
313     "Set the document language to English but assure Macedonian output"
314
315     if document.language == "macedonian":
316         document.language = "english"
317         i = find_token(document.header, "\\language macedonian", 0)
318         if i != -1:
319             document.header[i] = "\\language english"
320         j = find_token(document.header, "\\language_package default", 0)
321         if j != -1:
322             document.header[j] = "\\language_package babel"
323         k = find_token(document.header, "\\options", 0)
324         if k != -1:
325             document.header[k] = document.header[k].replace("\\options", "\\options macedonian,")
326         else:
327             l = find_token(document.header, "\\use_default_options", 0)
328             document.header.insert(l + 1, "\\options macedonian")
329
330
331 def revert_piedmontese(document):
332     "Set the document language to English but assure Piedmontese output"
333
334     if document.language == "piedmontese":
335         document.language = "english"
336         i = find_token(document.header, "\\language piedmontese", 0)
337         if i != -1:
338             document.header[i] = "\\language english"
339         j = find_token(document.header, "\\language_package default", 0)
340         if j != -1:
341             document.header[j] = "\\language_package babel"
342         k = find_token(document.header, "\\options", 0)
343         if k != -1:
344             document.header[k] = document.header[k].replace("\\options", "\\options piedmontese,")
345         else:
346             l = find_token(document.header, "\\use_default_options", 0)
347             document.header.insert(l + 1, "\\options piedmontese")
348
349
350 def revert_romansh(document):
351     "Set the document language to English but assure Romansh output"
352
353     if document.language == "romansh":
354         document.language = "english"
355         i = find_token(document.header, "\\language romansh", 0)
356         if i != -1:
357             document.header[i] = "\\language english"
358         j = find_token(document.header, "\\language_package default", 0)
359         if j != -1:
360             document.header[j] = "\\language_package babel"
361         k = find_token(document.header, "\\options", 0)
362         if k != -1:
363             document.header[k] = document.header[k].replace("\\options", "\\options romansh,")
364         else:
365             l = find_token(document.header, "\\use_default_options", 0)
366             document.header.insert(l + 1, "\\options romansh")
367
368
369 def revert_amharic(document):
370     "Set the document language to English but assure Amharic output"
371
372     if document.language == "amharic":
373         document.language = "english"
374         i = find_token(document.header, "\\language amharic", 0)
375         if i != -1:
376             document.header[i] = "\\language english"
377         j = find_token(document.header, "\\language_package default", 0)
378         if j != -1:
379             document.header[j] = "\\language_package default"
380         add_to_preamble(document, ["\\AtBeginDocument{\setotherlanguage{amharic}}"])
381         document.body[2 : 2] = ["\\begin_layout Standard",
382                                 "\\begin_inset ERT", "status open", "",
383                                 "\\begin_layout Plain Layout", "", "",
384                                 "\\backslash",
385                                 "resetdefaultlanguage{amharic}",
386                                 "\\end_layout", "", "\\end_inset", "", "",
387                                 "\\end_layout", ""]
388
389
390 def revert_asturian(document):
391     "Set the document language to English but assure Asturian output"
392
393     if document.language == "asturian":
394         document.language = "english"
395         i = find_token(document.header, "\\language asturian", 0)
396         if i != -1:
397             document.header[i] = "\\language english"
398         j = find_token(document.header, "\\language_package default", 0)
399         if j != -1:
400             document.header[j] = "\\language_package default"
401         add_to_preamble(document, ["\\AtBeginDocument{\setotherlanguage{asturian}}"])
402         document.body[2 : 2] = ["\\begin_layout Standard",
403                                 "\\begin_inset ERT", "status open", "",
404                                 "\\begin_layout Plain Layout", "", "",
405                                 "\\backslash",
406                                 "resetdefaultlanguage{asturian}",
407                                 "\\end_layout", "", "\\end_inset", "", "",
408                                 "\\end_layout", ""]
409
410
411 def revert_kannada(document):
412     "Set the document language to English but assure Kannada output"
413
414     if document.language == "kannada":
415         document.language = "english"
416         i = find_token(document.header, "\\language kannada", 0)
417         if i != -1:
418             document.header[i] = "\\language english"
419         j = find_token(document.header, "\\language_package default", 0)
420         if j != -1:
421             document.header[j] = "\\language_package default"
422         add_to_preamble(document, ["\\AtBeginDocument{\setotherlanguage{kannada}}"])
423         document.body[2 : 2] = ["\\begin_layout Standard",
424                                 "\\begin_inset ERT", "status open", "",
425                                 "\\begin_layout Plain Layout", "", "",
426                                 "\\backslash",
427                                 "resetdefaultlanguage{kannada}",
428                                 "\\end_layout", "", "\\end_inset", "", "",
429                                 "\\end_layout", ""]
430
431
432 def revert_khmer(document):
433     "Set the document language to English but assure Khmer output"
434
435     if document.language == "khmer":
436         document.language = "english"
437         i = find_token(document.header, "\\language khmer", 0)
438         if i != -1:
439             document.header[i] = "\\language english"
440         j = find_token(document.header, "\\language_package default", 0)
441         if j != -1:
442             document.header[j] = "\\language_package default"
443         add_to_preamble(document, ["\\AtBeginDocument{\setotherlanguage{khmer}}"])
444         document.body[2 : 2] = ["\\begin_layout Standard",
445                                 "\\begin_inset ERT", "status open", "",
446                                 "\\begin_layout Plain Layout", "", "",
447                                 "\\backslash",
448                                 "resetdefaultlanguage{khmer}",
449                                 "\\end_layout", "", "\\end_inset", "", "",
450                                 "\\end_layout", ""]
451
452
453 def revert_urdu(document):
454     "Set the document language to English but assure Urdu output"
455
456     if document.language == "urdu":
457         document.language = "english"
458         i = find_token(document.header, "\\language urdu", 0)
459         if i != -1:
460             document.header[i] = "\\language english"
461         j = find_token(document.header, "\\language_package default", 0)
462         if j != -1:
463             document.header[j] = "\\language_package default"
464         add_to_preamble(document, ["\\AtBeginDocument{\setotherlanguage{urdu}}"])
465         document.body[2 : 2] = ["\\begin_layout Standard",
466                                 "\\begin_inset ERT", "status open", "",
467                                 "\\begin_layout Plain Layout", "", "",
468                                 "\\backslash",
469                                 "resetdefaultlanguage{urdu}",
470                                 "\\end_layout", "", "\\end_inset", "", "",
471                                 "\\end_layout", ""]
472
473
474 def revert_syriac(document):
475     "Set the document language to English but assure Syriac output"
476
477     if document.language == "syriac":
478         document.language = "english"
479         i = find_token(document.header, "\\language syriac", 0)
480         if i != -1:
481             document.header[i] = "\\language english"
482         j = find_token(document.header, "\\language_package default", 0)
483         if j != -1:
484             document.header[j] = "\\language_package default"
485         add_to_preamble(document, ["\\AtBeginDocument{\setotherlanguage{syriac}}"])
486         document.body[2 : 2] = ["\\begin_layout Standard",
487                                 "\\begin_inset ERT", "status open", "",
488                                 "\\begin_layout Plain Layout", "", "",
489                                 "\\backslash",
490                                 "resetdefaultlanguage{syriac}",
491                                 "\\end_layout", "", "\\end_inset", "", "",
492                                 "\\end_layout", ""]
493
494
495 ##
496 # Conversion hub
497 #
498
499 supported_versions = ["2.3.0", "2.3"]
500 convert = [
501            [509, [convert_microtype]],
502            [510, [convert_dateinset]],
503            [511, [convert_ibranches]],
504            [512, [convert_beamer_article_styles]],
505            [513, []],
506            [514, []],
507            [515, []],
508            [516, [convert_inputenc]],
509           ]
510
511 revert =  [
512            [516, []],
513            [514, [revert_urdu, revert_syriac]],
514            [513, [revert_amharic, revert_asturian, revert_kannada, revert_khmer]],
515            [512, [revert_bosnian, revert_friulan, revert_macedonian, revert_piedmontese, revert_romansh]],
516            [511, [revert_beamer_article_styles]],
517            [510, [revert_ibranches]],
518            [509, []],
519            [508, [revert_microtype]]
520           ]
521
522
523 if __name__ == "__main__":
524     pass