]> git.lyx.org Git - features.git/blob - lib/lyx2lyx/lyx_1_6.py
cb692336f6d397fbf73418551456e235baedf1ee
[features.git] / lib / lyx2lyx / lyx_1_6.py
1 # This file is part of lyx2lyx
2 # -*- coding: utf-8 -*-
3 # Copyright (C) 2007 José Matos <jamatos@lyx.org>
4 #
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19 """ Convert files to the file format generated by lyx 1.6"""
20
21 import re
22 import unicodedata
23 import sys, os
24
25 from parser_tools import find_token, find_end_of, find_tokens, get_value
26
27 ####################################################################
28 # Private helper functions
29
30 def find_end_of_inset(lines, i):
31     " Find end of inset, where lines[i] is included."
32     return find_end_of(lines, i, "\\begin_inset", "\\end_inset")
33
34 def wrap_into_ert(string, src, dst):
35     " Wrap a something into an ERT"
36     return string.replace(src, '\n\\begin_inset ERT\nstatus collapsed\n\\begin_layout Standard\n' 
37       + dst + '\n\\end_layout\n\\end_inset\n')
38
39
40 ####################################################################
41
42 def fix_wrong_tables(document):
43     i = 0
44     while True:
45         i = find_token(document.body, "\\begin_inset Tabular", i)
46         if i == -1:
47             return
48         j = find_end_of_inset(document.body, i + 1)
49         if j == -1:
50             document.warning("Malformed LyX document: Could not find end of tabular.")
51             continue
52
53         m = i + 1
54         nrows = int(document.body[i+1].split('"')[3])
55         ncols = int(document.body[i+1].split('"')[5])
56
57         for l in range(nrows):
58             prev_multicolumn = 0
59             for k in range(ncols):
60                 m = find_token(document.body, '<cell', m)
61
62                 if document.body[m].find('multicolumn') != -1:
63                     multicol_cont = int(document.body[m].split('"')[1])
64
65                     if multicol_cont == 2 and (k == 0 or prev_multicolumn == 0):
66                         document.body[m] = document.body[m][:5] + document.body[m][21:]
67                         prev_multicolumn = 0
68                     else:
69                         prev_multicolumn = multicol_cont
70                 else:
71                     prev_multicolumn = 0
72
73         i = j + 1
74
75
76 def close_begin_deeper(document):
77     i = 0
78     depth = 0
79     while True:
80         i = find_tokens(document.body, ["\\begin_deeper", "\\end_deeper"], i)
81
82         if i == -1:
83             break
84
85         if document.body[i][:13] == "\\begin_deeper":
86             depth += 1
87         else:
88             depth -= 1
89
90         i += 1
91
92     document.body[-2:-2] = ['\\end_deeper' for i in range(depth)]
93
94
95 def long_charstyle_names(document):
96     i = 0
97     while True:
98         i = find_token(document.body, "\\begin_inset CharStyle", i)
99         if i == -1:
100             return
101         document.body[i] = document.body[i].replace("CharStyle ", "CharStyle CharStyle:")
102         i += 1
103
104 def revert_long_charstyle_names(document):
105     i = 0
106     while True:
107         i = find_token(document.body, "\\begin_inset CharStyle", i)
108         if i == -1:
109             return
110         document.body[i] = document.body[i].replace("CharStyle CharStyle:", "CharStyle")
111         i += 1
112
113
114 def axe_show_label(document):
115     i = 0
116     while True:
117         i = find_token(document.body, "\\begin_inset CharStyle", i)
118         if i == -1:
119             return
120         if document.body[i + 1].find("show_label") != -1:
121             if document.body[i + 1].find("true") != -1:
122                 document.body[i + 1] = "status open"
123                 del document.body[ i + 2]
124             else:
125                 if document.body[i + 1].find("false") != -1:
126                     document.body[i + 1] = "status collapsed"
127                     del document.body[ i + 2]
128                 else:
129                     document.warning("Malformed LyX document: show_label neither false nor true.")
130         else:
131             document.warning("Malformed LyX document: show_label missing in CharStyle.")
132             
133         i += 1
134
135
136 def revert_show_label(document):
137     i = 0
138     while True:
139         i = find_token(document.body, "\\begin_inset CharStyle", i)
140         if i == -1:
141             return
142         if document.body[i + 1].find("status open") != -1:
143             document.body.insert(i + 1, "show_label true")
144         else:
145             if document.body[i + 1].find("status collapsed") != -1:
146                 document.body.insert(i + 1, "show_label false")
147             else:
148                 document.warning("Malformed LyX document: no legal status line in CharStyle.")
149         i += 1
150
151 def revert_begin_modules(document):
152     i = 0
153     while True:
154         i = find_token(document.header, "\\begin_modules", i)
155         if i == -1:
156             return
157         j = find_end_of(document.header, i, "\\begin_modules", "\\end_modules")
158         if j == -1:
159             # this should not happen
160             break
161         document.header[i : j + 1] = []
162
163 def convert_flex(document):
164     "Convert CharStyle to Flex"
165     i = 0
166     while True:
167         i = find_token(document.body, "\\begin_inset CharStyle", i)
168         if i == -1:
169             return
170         document.body[i] = document.body[i].replace('\\begin_inset CharStyle', '\\begin_inset Flex')
171
172 def revert_flex(document):
173     "Convert Flex to CharStyle"
174     i = 0
175     while True:
176         i = find_token(document.body, "\\begin_inset Flex", i)
177         if i == -1:
178             return
179         document.body[i] = document.body[i].replace('\\begin_inset Flex', '\\begin_inset CharStyle')
180
181
182 #  Discard PDF options for hyperref
183 def revert_pdf_options(document):
184         "Revert PDF options for hyperref."
185         i = 0
186         i = find_token(document.header, "\\use_hyperref", i)
187         if i != -1:
188             del document.header[i]
189         i = find_token(document.header, "\\pdf_store_options", i)
190         if i != -1:
191             del document.header[i]
192         i = find_token(document.header, "\\pdf_title", 0)
193         if i != -1:
194             del document.header[i]
195         i = find_token(document.header, "\\pdf_author", 0)
196         if i != -1:
197             del document.header[i]
198         i = find_token(document.header, "\\pdf_subject", 0)
199         if i != -1:
200             del document.header[i]
201         i = find_token(document.header, "\\pdf_keywords", 0)
202         if i != -1:
203             del document.header[i]
204         i = find_token(document.header, "\\pdf_bookmarks", 0)
205         if i != -1:
206             del document.header[i]
207         i = find_token(document.header, "\\pdf_bookmarksnumbered", i)
208         if i != -1:
209             del document.header[i]
210         i = find_token(document.header, "\\pdf_bookmarksopen", i)
211         if i != -1:
212             del document.header[i]
213         i = find_token(document.header, "\\pdf_bookmarksopenlevel", i)
214         if i != -1:
215             del document.header[i]
216         i = find_token(document.header, "\\pdf_breaklinks", i)
217         if i != -1:
218             del document.header[i]
219         i = find_token(document.header, "\\pdf_pdfborder", i)
220         if i != -1:
221             del document.header[i]
222         i = find_token(document.header, "\\pdf_colorlinks", i)
223         if i != -1:
224             del document.header[i]
225         i = find_token(document.header, "\\pdf_backref", i)
226         if i != -1:
227             del document.header[i]
228         i = find_token(document.header, "\\pdf_pagebackref", i)
229         if i != -1:
230             del document.header[i]
231         i = find_token(document.header, "\\pdf_pagemode", 0)
232         if i != -1:
233             del document.header[i]
234         i = find_token(document.header, "\\pdf_quoted_options", 0)
235         if i != -1:
236             del document.header[i]
237
238
239 def remove_inzip_options(document):
240     "Remove inzipName and embed options from the Graphics inset"
241     i = 0
242     while 1:
243         i = find_token(document.body, "\\begin_inset Graphics", i)
244         if i == -1:
245             return
246         j = find_end_of_inset(document.body, i + 1)
247         if j == -1:
248             # should not happen
249             document.warning("Malformed LyX document: Could not find end of graphics inset.")
250         # If there's a inzip param, just remove that
251         k = find_token(document.body, "\tinzipName", i + 1, j)
252         if k != -1:
253             del document.body[k]
254             # embed option must follow the inzipName option
255             del document.body[k+1]
256         i = i + 1
257
258
259 def convert_inset_command(document):
260     """
261         Convert:
262             \begin_inset LatexCommand cmd 
263         to 
264             \begin_inset CommandInset InsetType
265             LatexCommand cmd
266     """
267     i = 0
268     while 1:
269         i = find_token(document.body, "\\begin_inset LatexCommand", i)
270         if i == -1:
271             return
272         line = document.body[i]
273         r = re.compile(r'\\begin_inset LatexCommand (.*)$')
274         m = r.match(line)
275         cmdName = m.group(1)
276         insetName = ""
277         #this is adapted from factory.cpp
278         if cmdName[0:4].lower() == "cite":
279             insetName = "citation"
280         elif cmdName == "url" or cmdName == "htmlurl":
281             insetName = "url"
282         elif cmdName[-3:] == "ref":
283             insetName = "ref"
284         elif cmdName == "tableofcontents":
285             insetName = "toc"
286         elif cmdName == "printnomenclature":
287             insetName = "nomencl_print"
288         elif cmdName == "printindex":
289             insetName = "index_print"
290         else:
291             insetName = cmdName
292         insertion = ["\\begin_inset CommandInset " + insetName, "LatexCommand " + cmdName]
293         document.body[i : i+1] = insertion
294
295
296 def revert_inset_command(document):
297     """
298         Convert:
299             \begin_inset CommandInset InsetType
300             LatexCommand cmd
301         to 
302             \begin_inset LatexCommand cmd 
303         Some insets may end up being converted to insets earlier versions of LyX
304         will not be able to recognize. Not sure what to do about that.
305     """
306     i = 0
307     while 1:
308         i = find_token(document.body, "\\begin_inset CommandInset", i)
309         if i == -1:
310             return
311         nextline = document.body[i+1]
312         r = re.compile(r'LatexCommand\s+(.*)$')
313         m = r.match(nextline)
314         if not m:
315             document.warning("Malformed LyX document: Missing LatexCommand in " + document.body[i] + ".")
316             continue
317         cmdName = m.group(1)
318         insertion = ["\\begin_inset LatexCommand " + cmdName]
319         document.body[i : i+2] = insertion
320
321
322 def convert_wrapfig_options(document):
323     "Convert optional options for wrap floats (wrapfig)."
324     # adds the tokens "lines", "placement", and "overhang"
325     i = 0
326     while True:
327         i = find_token(document.body, "\\begin_inset Wrap figure", i)
328         if i == -1:
329             return
330         document.body.insert(i + 1, "lines 0")
331         j = find_token(document.body, "placement", i)
332         # placement can be already set or not; if not, set it
333         if j == i+2:
334             document.body.insert(i + 3, "overhang 0col%")
335         else:
336            document.body.insert(i + 2, "placement o")
337            document.body.insert(i + 3, "overhang 0col%")
338         i = i + 1
339
340
341 def revert_wrapfig_options(document):
342     "Revert optional options for wrap floats (wrapfig)."
343     i = 0
344     while True:
345         i = find_token(document.body, "lines", i)
346         if i == -1:
347             return
348         j = find_token(document.body, "overhang", i+1)
349         if j != i + 2 and j != -1:
350             document.warning("Malformed LyX document: Couldn't find overhang parameter of wrap float.")
351         if j == -1:
352             return
353         del document.body[i]
354         del document.body[j-1]
355         i = i + 1
356
357
358 def convert_latexcommand_index(document):
359     "Convert from LatexCommand form to collapsable form."
360     i = 0 
361     while True:
362         i = find_token(document.body, "\\begin_inset CommandInset index", i)
363         if i == -1:
364             return
365         if document.body[i + 1] != "LatexCommand index": # Might also be index_print
366             return
367         fullcontent = document.body[i + 2][6:].strip('"')
368         document.body[i:i + 2] = ["\\begin_inset Index",
369           "status collapsed",
370           "\\begin_layout Standard"]
371         # Put here the conversions needed from LaTeX string to LyXText.
372         # Here we do a minimal conversion to prevent crashes and data loss.
373         # Manual patch-up may be needed.
374         # Umlauted characters (most common ones, can be extended):
375         fullcontent = fullcontent.replace(r'\\\"a', u'ä').replace(r'\\\"o', u'ö').replace(r'\\\"u', u'ü')
376         # Generic, \" -> ":
377         fullcontent = wrap_into_ert(fullcontent, r'\"', '"')
378         #fullcontent = fullcontent.replace(r'\"', '\n\\begin_inset ERT\nstatus collapsed\n\\begin_layout standard\n"\n\\end_layout\n\\end_inset\n')
379         # Math:
380         r = re.compile('^(.*?)(\$.*?\$)(.*)')
381         g = fullcontent
382         while r.match(g):
383           m = r.match(g)
384           s = m.group(1)
385           f = m.group(2).replace('\\\\', '\\')
386           g = m.group(3)
387           if s:
388             # this is non-math!
389             s = wrap_into_ert(s, r'\\', '\\backslash')
390             s = wrap_into_ert(s, '{', '{')
391             s = wrap_into_ert(s, '}', '}')
392             document.body.insert(i + 3, s)
393             i += 1
394           document.body.insert(i + 3, "\\begin_inset Formula " + f)
395           document.body.insert(i + 4, "\\end_inset")
396           i += 2
397         # Generic, \\ -> \backslash:
398         g = wrap_into_ert(g, r'\\', '\\backslash{}')
399         g = wrap_into_ert(g, '{', '{')
400         g = wrap_into_ert(g, '}', '}')
401         document.body.insert(i + 3, g)
402         document.body[i + 4] = "\\end_layout"
403         i = i + 5
404
405
406 def revert_latexcommand_index(document):
407     "Revert from collapsable form toLatexCommand form."
408     i = 0
409     while True:
410         i = find_token(document.body, "\\begin_inset Index", i)
411         if i == -1:
412           return
413         j = find_end_of_inset(document.body, i + 1)
414         if j == -1:
415           return
416         del document.body[j - 1]
417         del document.body[j - 2] # \end_layout
418         document.body[i] =  "\\begin_inset CommandInset index"
419         document.body[i + 1] =  "LatexCommand index"
420         # clean up multiline stuff
421         content = ""
422         for k in range(i + 3, j - 2):
423           line = document.body[k]
424           if line.startswith("\\begin_inset ERT"):
425             line = line[16:]
426           if line.startswith("\\begin_inset Formula"):
427             line = line[20:]
428           if line.startswith("\\begin_layout Standard"):
429             line = line[22:]
430           if line.startswith("\\end_layout"):
431             line = line[11:]
432           if line.startswith("\\end_inset"):
433             line = line[10:]
434           if line.startswith("status collapsed"):
435             line = line[16:]
436           content = content + line;
437         document.body[i + 3] = "name " + '"' + content + '"'
438         for k in range(i + 4, j - 2):
439           del document.body[i + 4]
440         document.body.insert(i + 4, "")
441         del document.body[i + 2] # \begin_layout standard
442         i = i + 5
443
444
445 def revert_wraptable(document):
446     "Revert wrap table to wrap figure."
447     i = 0
448     while True:
449         i = find_token(document.body, "\\begin_inset Wrap table", i)
450         if i == -1:
451             return
452         document.body[i] = document.body[i].replace('\\begin_inset Wrap table', '\\begin_inset Wrap figure')
453         i = i + 1
454
455
456 def revert_vietnamese(document):
457     "Set language Vietnamese to English"
458     # Set document language from Vietnamese to English
459     i = 0
460     if document.language == "vietnamese":
461         document.language = "english"
462         i = find_token(document.header, "\\language", 0)
463         if i != -1:
464             document.header[i] = "\\language english"
465     j = 0
466     while True:
467         j = find_token(document.body, "\\lang vietnamese", j)
468         if j == -1:
469             return
470         document.body[j] = document.body[j].replace("\\lang vietnamese", "\\lang english")
471         j = j + 1
472
473
474 def revert_japanese(document):
475     "Set language japanese-plain to japanese"
476     # Set document language from japanese-plain to japanese
477     i = 0
478     if document.language == "japanese-plain":
479         document.language = "japanese"
480         i = find_token(document.header, "\\language", 0)
481         if i != -1:
482             document.header[i] = "\\language japanese"
483     j = 0
484     while True:
485         j = find_token(document.body, "\\lang japanese-plain", j)
486         if j == -1:
487             return
488         document.body[j] = document.body[j].replace("\\lang japanese-plain", "\\lang japanese")
489         j = j + 1
490
491
492 def revert_japanese_encoding(document):
493     "Set input encoding form EUC-JP-plain to EUC-JP etc."
494     # Set input encoding form EUC-JP-plain to EUC-JP etc.
495     i = 0
496     i = find_token(document.header, "\\inputencoding EUC-JP-plain", 0)
497     if i != -1:
498         document.header[i] = "\\inputencoding EUC-JP"
499     j = 0
500     j = find_token(document.header, "\\inputencoding JIS-plain", 0)
501     if j != -1:
502         document.header[j] = "\\inputencoding JIS"
503     k = 0
504     k = find_token(document.header, "\\inputencoding SJIS-plain", 0)
505     if k != -1: # convert to UTF8 since there is currently no SJIS encoding 
506         document.header[k] = "\\inputencoding UTF8"
507
508
509 def revert_inset_info(document):
510     'Replace info inset with its content'
511     i = 0
512     while 1:
513         i = find_token(document.body, '\\begin_inset Info', i)
514         if i == -1:
515             return
516         j = find_end_of_inset(document.body, i + 1)
517         if j == -1:
518             # should not happen
519             document.warning("Malformed LyX document: Could not find end of Info inset.")
520         type = 'unknown'
521         arg = ''
522         for k in range(i, j+1):
523             if document.body[k].startswith("arg"):
524                 arg = document.body[k][3:].strip().strip('"')
525             if document.body[k].startswith("type"):
526                 type = document.body[k][4:].strip().strip('"')
527         # I think there is a newline after \\end_inset, which should be removed.
528         if document.body[j + 1].strip() == "":
529             document.body[i : (j + 2)] = [type + ':' + arg]
530         else:
531             document.body[i : (j + 1)] = [type + ':' + arg]
532
533
534 def convert_pdf_options(document):
535     # Set the pdfusetitle tag, delete the pdf_store_options,
536     # set quotes for bookmarksopenlevel"
537     has_hr = get_value(document.header, "\\use_hyperref", 0, default = "0")
538     if has_hr == "1":
539         k = find_token(document.header, "\\use_hyperref", 0)
540         document.header.insert(k + 1, "\\pdf_pdfusetitle true")
541     k = find_token(document.header, "\\pdf_store_options", 0)
542     if k != -1:
543         del document.header[k]
544     i = find_token(document.header, "\\pdf_bookmarksopenlevel", k)
545     if i == -1: return
546     document.header[i] = document.header[i].replace('"', '')
547
548
549 def revert_pdf_options_2(document):
550     # reset the pdfusetitle tag, set quotes for bookmarksopenlevel"
551     k = find_token(document.header, "\\use_hyperref", 0)
552     i = find_token(document.header, "\\pdf_pdfusetitle", k)
553     if i != -1:
554         del document.header[i]
555     i = find_token(document.header, "\\pdf_bookmarksopenlevel", k)
556     if i == -1: return
557     values = document.header[i].split()
558     values[1] = ' "' + values[1] + '"'
559     document.header[i] = ''.join(values)
560
561
562 def convert_htmlurl(document):
563     'Convert "htmlurl" to "href" insets for docbook'
564     if document.backend != "docbook":
565       return
566     i = 0
567     while True:
568       i = find_token(document.body, "\\begin_inset CommandInset url", i)
569       if i == -1:
570         return
571       document.body[i] = "\\begin_inset CommandInset href"
572       document.body[i + 1] = "LatexCommand href"
573       i = i + 1
574
575
576 def convert_url(document):
577     'Convert url insets to url charstyles'
578     if document.backend == "docbook":
579       return
580     i = 0
581     while True:
582       i = find_token(document.body, "\\begin_inset CommandInset url", i)
583       if i == -1:
584         break
585       n = find_token(document.body, "name", i)
586       if n == i + 2:
587         # place the URL name in typewriter before the new URL insert
588         # grab the name 'bla' from the e.g. the line 'name "bla"',
589         # therefore start with the 6th character
590         name = document.body[n][6:-1]
591         newname = [name + " "]
592         document.body[i:i] = newname
593         i = i + 1
594       j = find_token(document.body, "target", i)
595       if j == -1:
596         document.warning("Malformed LyX document: Can't find target for url inset")
597         i = j
598         continue
599       target = document.body[j][8:-1]
600       k = find_token(document.body, "\\end_inset", j)
601       if k == -1:
602         document.warning("Malformed LyX document: Can't find end of url inset")
603         i = k
604         continue
605       newstuff = ["\\begin_inset Flex URL",
606         "status collapsed", "", 
607         "\\begin_layout Standard",
608         "",
609         target,
610         "\\end_layout",
611         ""]
612       document.body[i:k] = newstuff
613       i = k
614
615
616 def revert_href(document):
617     'Reverts hyperlink insets (href) to url insets (url)'
618     i = 0
619     while True:
620       i = find_token(document.body, "\\begin_inset CommandInset href", i)
621       if i == -1:
622           return
623       document.body[i : i + 2] = \
624         ["\\begin_inset CommandInset url", "LatexCommand url"]
625       i = i + 2
626
627
628 def convert_include(document):
629   'Converts include insets to new format.'
630   i = 0
631   r = re.compile(r'\\begin_inset Include\s+\\([^{]+){([^}]*)}(?:\[(.*)\])?')
632   while True:
633     i = find_token(document.body, "\\begin_inset Include", i)
634     if i == -1:
635       return
636     line = document.body[i]
637     previewline = document.body[i + 1]
638     m = r.match(line)
639     if m == None:
640       document.warning("Unable to match line " + str(i) + " of body!")
641       i += 1
642       continue
643     cmd = m.group(1)
644     fn  = m.group(2)
645     opt = m.group(3)
646     insertion = ["\\begin_inset CommandInset include", 
647        "LatexCommand " + cmd, previewline,
648        "filename \"" + fn + "\""]
649     newlines = 2
650     if opt:
651       insertion.append("lstparams " + '"' + opt + '"')
652       newlines += 1
653     document.body[i : i + 2] = insertion
654     i += newlines
655
656
657 def revert_include(document):
658   'Reverts include insets to old format.'
659   i = 0
660   r1 = re.compile('LatexCommand (.+)')
661   r2 = re.compile('filename (.+)')
662   r3 = re.compile('options (.*)')
663   while True:
664     i = find_token(document.body, "\\begin_inset CommandInset include", i)
665     if i == -1:
666       return
667     previewline = document.body[i + 1]
668     m = r1.match(document.body[i + 2])
669     if m == None:
670       document.warning("Malformed LyX document: No LatexCommand line for `" +
671         document.body[i] + "' on line " + str(i) + ".")
672       i += 1
673       continue
674     cmd = m.group(1)
675     m = r2.match(document.body[i + 3])
676     if m == None:
677       document.warning("Malformed LyX document: No filename line for `" + \
678         document.body[i] + "' on line " + str(i) + ".")
679       i += 2
680       continue
681     fn = m.group(1)
682     options = ""
683     numlines = 4
684     if (cmd == "lstinputlisting"):
685       m = r3.match(document.body[i + 4])
686       if m != None:
687         options = m.group(1)
688         numlines = 5
689     newline = "\\begin_inset Include \\" + cmd + "{" + fn + "}"
690     if options:
691       newline += ("[" + options + "]")
692     insertion = [newline, previewline]
693     document.body[i : i + numlines] = insertion
694     i += 2
695
696
697 def revert_albanian(document):
698     "Set language Albanian to English"
699     i = 0
700     if document.language == "albanian":
701         document.language = "english"
702         i = find_token(document.header, "\\language", 0)
703         if i != -1:
704             document.header[i] = "\\language english"
705     j = 0
706     while True:
707         j = find_token(document.body, "\\lang albanian", j)
708         if j == -1:
709             return
710         document.body[j] = document.body[j].replace("\\lang albanian", "\\lang english")
711         j = j + 1
712
713
714 def revert_lowersorbian(document):
715     "Set language lower Sorbian to English"
716     i = 0
717     if document.language == "lowersorbian":
718         document.language = "english"
719         i = find_token(document.header, "\\language", 0)
720         if i != -1:
721             document.header[i] = "\\language english"
722     j = 0
723     while True:
724         j = find_token(document.body, "\\lang lowersorbian", j)
725         if j == -1:
726             return
727         document.body[j] = document.body[j].replace("\\lang lowersorbian", "\\lang english")
728         j = j + 1
729
730
731 def revert_uppersorbian(document):
732     "Set language uppersorbian to usorbian as this was used in LyX 1.5"
733     i = 0
734     if document.language == "uppersorbian":
735         document.language = "usorbian"
736         i = find_token(document.header, "\\language", 0)
737         if i != -1:
738             document.header[i] = "\\language usorbian"
739     j = 0
740     while True:
741         j = find_token(document.body, "\\lang uppersorbian", j)
742         if j == -1:
743             return
744         document.body[j] = document.body[j].replace("\\lang uppersorbian", "\\lang usorbian")
745         j = j + 1
746
747
748 def convert_usorbian(document):
749     "Set language usorbian to uppersorbian"
750     i = 0
751     if document.language == "usorbian":
752         document.language = "uppersorbian"
753         i = find_token(document.header, "\\language", 0)
754         if i != -1:
755             document.header[i] = "\\language uppersorbian"
756     j = 0
757     while True:
758         j = find_token(document.body, "\\lang usorbian", j)
759         if j == -1:
760             return
761         document.body[j] = document.body[j].replace("\\lang usorbian", "\\lang uppersorbian")
762         j = j + 1
763
764
765 def revert_macro_optional_params(document):
766     "Convert macro definitions with optional parameters into ERTs"
767     # Stub to convert macro definitions with one or more optional parameters
768     # into uninterpreted ERT insets
769
770
771 def revert_hyperlinktype(document):
772     'Reverts hyperlink type'
773     i = 0
774     j = 0
775     while True:
776       i = find_token(document.body, "target", i)
777       if i == -1:
778           return
779       j = find_token(document.body, "type", i)
780       if j == -1:
781           return
782       if j == i + 1:
783           del document.body[j]
784       i = i + 1
785
786
787 def revert_pagebreak(document):
788     'Reverts pagebreak to ERT'
789     i = 0
790     while True:
791       i = find_token(document.body, "\\pagebreak", i)
792       if i == -1:
793           return
794       document.body[i] = '\\begin_inset ERT\nstatus collapsed\n\n' \
795       '\\begin_layout Standard\n\n\n\\backslash\n' \
796       'pagebreak{}\n\\end_layout\n\n\\end_inset\n\n'
797       i = i + 1
798
799
800 def revert_linebreak(document):
801     'Reverts linebreak to ERT'
802     i = 0
803     while True:
804       i = find_token(document.body, "\\linebreak", i)
805       if i == -1:
806           return
807       document.body[i] = '\\begin_inset ERT\nstatus collapsed\n\n' \
808       '\\begin_layout Standard\n\n\n\\backslash\n' \
809       'linebreak{}\n\\end_layout\n\n\\end_inset\n\n'
810       i = i + 1
811
812
813 def revert_latin(document):
814     "Set language Latin to English"
815     i = 0
816     if document.language == "latin":
817         document.language = "english"
818         i = find_token(document.header, "\\language", 0)
819         if i != -1:
820             document.header[i] = "\\language english"
821     j = 0
822     while True:
823         j = find_token(document.body, "\\lang latin", j)
824         if j == -1:
825             return
826         document.body[j] = document.body[j].replace("\\lang latin", "\\lang english")
827         j = j + 1
828
829
830 def revert_samin(document):
831     "Set language North Sami to English"
832     i = 0
833     if document.language == "samin":
834         document.language = "english"
835         i = find_token(document.header, "\\language", 0)
836         if i != -1:
837             document.header[i] = "\\language english"
838     j = 0
839     while True:
840         j = find_token(document.body, "\\lang samin", j)
841         if j == -1:
842             return
843         document.body[j] = document.body[j].replace("\\lang samin", "\\lang english")
844         j = j + 1
845
846
847 def convert_serbocroatian(document):
848     "Set language Serbocroatian to Croatian as this was really Croatian in LyX 1.5"
849     i = 0
850     if document.language == "serbocroatian":
851         document.language = "croatian"
852         i = find_token(document.header, "\\language", 0)
853         if i != -1:
854             document.header[i] = "\\language croatian"
855     j = 0
856     while True:
857         j = find_token(document.body, "\\lang serbocroatian", j)
858         if j == -1:
859             return
860         document.body[j] = document.body[j].replace("\\lang serbocroatian", "\\lang croatian")
861         j = j + 1
862
863
864 def convert_framed_notes(document):
865     "Convert framed notes to boxes. "
866     i = 0
867     while 1:
868         i = find_tokens(document.body, ["\\begin_inset Note Framed", "\\begin_inset Note Shaded"], i)
869
870         if i == -1:
871             return
872         document.body[i] = document.body[i].replace("\\begin_inset Note", "\\begin_inset Box")
873         document.body.insert(i + 1, 'position "t"\nhor_pos "c"\nhas_inner_box 0\ninner_pos "t"\n' \
874         'use_parbox 0\nwidth "100col%"\nspecial "none"\nheight "1in"\n' \
875         'height_special "totalheight"')
876         i = i + 1
877
878
879 def revert_framed_notes(document):
880     "Revert framed boxes to notes. "
881     i = 0
882     while 1:
883         i = find_tokens(document.body, ["\\begin_inset Box Framed", "\\begin_inset Box Shaded"], i)
884
885         if i == -1:
886             return
887         j = find_end_of_inset(document.body, i + 1)
888         if j == -1:
889             # should not happen
890             document.warning("Malformed LyX document: Could not find end of Box inset.")
891         k = find_token(document.body, "status", i + 1, j)
892         if k == -1:
893             document.warning("Malformed LyX document: Missing `status' tag in Box inset.")
894             return
895         status = document.body[k]
896         l = find_token(document.body, "\\begin_layout Standard", i + 1, j)
897         if l == -1:
898             document.warning("Malformed LyX document: Missing `\\begin_layout Standard' in Box inset.")
899             return
900         m = find_token(document.body, "\\end_layout", i + 1, j)
901         if m == -1:
902             document.warning("Malformed LyX document: Missing `\\end_layout' in Box inset.")
903             return
904         ibox = find_token(document.body, "has_inner_box 1", i + 1, k)
905         pbox = find_token(document.body, "use_parbox 1", i + 1, k)
906         if ibox == -1 and pbox == -1:
907             document.body[i] = document.body[i].replace("\\begin_inset Box", "\\begin_inset Note")
908             del document.body[i+1:k]
909         else:
910             document.body[i] = document.body[i].replace("\\begin_inset Box Shaded", "\\begin_inset Box Frameless")
911             document.body.insert(l + 1, "\\begin_inset Note Shaded\n" + status + "\n\\begin_layout Standard\n")
912             document.body.insert(m + 1, "\\end_layout\n\\end_inset")
913         i = i + 1
914
915
916 def revert_bahasam(document):
917     "Set language Bahasa Malaysia to Bahasa Indonesia"
918     i = 0
919     if document.language == "bahasam":
920         document.language = "bahasa"
921         i = find_token(document.header, "\\language", 0)
922         if i != -1:
923             document.header[i] = "\\language bahasa"
924     j = 0
925     while True:
926         j = find_token(document.body, "\\lang bahasam", j)
927         if j == -1:
928             return
929         document.body[j] = document.body[j].replace("\\lang bahasam", "\\lang bahasa")
930         j = j + 1
931
932
933 def revert_interlingua(document):
934     "Set language Interlingua to English"
935     i = 0
936     if document.language == "interlingua":
937         document.language = "english"
938         i = find_token(document.header, "\\language", 0)
939         if i != -1:
940             document.header[i] = "\\language english"
941     j = 0
942     while True:
943         j = find_token(document.body, "\\lang interlingua", j)
944         if j == -1:
945             return
946         document.body[j] = document.body[j].replace("\\lang interlingua", "\\lang english")
947         j = j + 1
948
949
950 ##
951 # Conversion hub
952 #
953
954 supported_versions = ["1.6.0","1.6"]
955 convert = [[277, [fix_wrong_tables]],
956            [278, [close_begin_deeper]],
957            [279, [long_charstyle_names]],
958            [280, [axe_show_label]],
959            [281, []],
960            [282, []],
961            [283, [convert_flex]],
962            [284, []],
963            [285, []],
964            [286, []],
965            [287, [convert_wrapfig_options]],
966            [288, [convert_inset_command]],
967            [289, [convert_latexcommand_index]],
968            [290, []],
969            [291, []],
970            [292, []],
971            [293, []],
972            [294, [convert_pdf_options]],
973            [295, [convert_htmlurl, convert_url]],
974            [296, [convert_include]],
975            [297, [convert_usorbian]],
976            [298, []],
977            [299, []],
978            [300, []],
979            [301, []],
980            [302, []],
981            [303, [convert_serbocroatian]],
982            [304, [convert_framed_notes]],
983            [305, []],
984            [306, []]
985           ]
986
987 revert =  [[305, [revert_interlingua]],
988            [304, [revert_bahasam]],
989            [303, [revert_framed_notes]],
990            [302, []],
991            [301, [revert_latin, revert_samin]],
992            [300, [revert_linebreak]],
993            [299, [revert_pagebreak]],
994            [298, [revert_hyperlinktype]],
995            [297, [revert_macro_optional_params]],
996            [296, [revert_albanian, revert_lowersorbian, revert_uppersorbian]],
997            [295, [revert_include]],
998            [294, [revert_href]],
999            [293, [revert_pdf_options_2]],
1000            [292, [revert_inset_info]],
1001            [291, [revert_japanese, revert_japanese_encoding]],
1002            [290, [revert_vietnamese]],
1003            [289, [revert_wraptable]],
1004            [288, [revert_latexcommand_index]],
1005            [287, [revert_inset_command]],
1006            [286, [revert_wrapfig_options]],
1007            [285, [revert_pdf_options]],
1008            [284, [remove_inzip_options]],
1009            [283, []],
1010            [282, [revert_flex]],
1011            [281, []],
1012            [280, [revert_begin_modules]],
1013            [279, [revert_show_label]],
1014            [278, [revert_long_charstyle_names]],
1015            [277, []],
1016            [276, []]
1017           ]
1018
1019
1020 if __name__ == "__main__":
1021     pass