1 # This file is part of lyx2lyx
2 # -*- coding: utf-8 -*-
3 # Copyright (C) 2007-2008 The LyX Team <lyx-devel@lists.lyx.org>
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.
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.
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.
19 """ Convert files to the file format generated by lyx 1.6"""
25 from parser_tools import find_token, find_end_of, find_tokens, get_value, get_value_string
27 ####################################################################
28 # Private helper functions
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")
36 # document.body[i] = wrap_insert_ert(...)
37 # wrap_into_ert may returns a multiline string, which should NOT appear
38 # in document.body. Insetad, do something like this:
39 # subst = wrap_inset_ert(...)
40 # subst = subst.split('\n')
41 # document.body[i:i+1] = subst
43 # where the last statement resets the counter to accord with the added
45 def wrap_into_ert(string, src, dst):
46 " Wrap a something into an ERT"
47 return string.replace(src, '\n\\begin_inset ERT\nstatus collapsed\n\\begin_layout Standard\n'
48 + dst + '\n\\end_layout\n\\end_inset\n')
50 def add_to_preamble(document, text):
51 """ Add text to the preamble if it is not already there.
52 Only the first line is checked!"""
54 if find_token(document.preamble, text[0], 0) != -1:
57 document.preamble.extend(text)
59 # Convert a LyX length into a LaTeX length
61 units = {"text%":"\\backslash\ntextwidth", "col%":"\\backslash\ncolumnwidth",
62 "page%":"\\backslash\npagewidth", "line%":"\\backslash\nlinewidth",
63 "theight%":"\\backslash\ntextheight", "pheight%":"\\backslash\npageheight"}
65 # Convert LyX units to LaTeX units
66 for unit in units.keys():
67 if len.find(unit) != -1:
68 len = '%f' % (len2value(len) / 100)
69 len = len.strip('0') + units[unit]
74 # Return the value of len without the unit in numerical form.
76 result = re.search('([+-]?[0-9.]+)', len)
78 return float(result.group(1))
82 # Unfortunately, this doesn't really work, since Standard isn't always default.
83 # But it's as good as we can do right now.
84 def find_default_layout(document, start, end):
85 l = find_token(document.body, "\\begin_layout Standard", start, end)
87 l = find_token(document.body, "\\begin_layout PlainLayout", start, end)
89 l = find_token(document.body, "\\begin_layout Plain Layout", start, end)
92 def get_option(document, m, option, default):
93 l = document.body[m].find(option)
96 val = document.body[m][l:].split('"')[1]
99 def remove_option(document, m, option):
100 l = document.body[m].find(option)
102 val = document.body[m][l:].split('"')[1]
103 document.body[m] = document.body[m][:l-1] + document.body[m][l+len(option + '="' + val + '"'):]
106 def set_option(document, m, option, value):
107 l = document.body[m].find(option)
109 oldval = document.body[m][l:].split('"')[1]
110 l = l + len(option + '="')
111 document.body[m] = document.body[m][:l] + value + document.body[m][l+len(oldval):]
113 document.body[m] = document.body[m][:-1] + ' ' + option + '="' + value + '">'
117 def read_unicodesymbols():
118 " Read the unicodesymbols list of unicode characters and corresponding commands."
119 pathname = os.path.abspath(os.path.dirname(sys.argv[0]))
120 fp = open(os.path.join(pathname.strip('lyx2lyx'), 'unicodesymbols'))
122 # Two backslashes, followed by some non-word character, and then a character
123 # in brackets. The idea is to check for constructs like: \"{u}, which is how
124 # they are written in the unicodesymbols file; but they can also be written
126 r = re.compile(r'\\\\(\W)\{(\w)\}')
127 for line in fp.readlines():
128 if line[0] != '#' and line.strip() != "" and line.find("\\") != -1:
129 line=line.replace(' "',' ') # remove all quotation marks with spaces before
130 line=line.replace('" ',' ') # remove all quotation marks with spaces after
131 line=line.replace(r'\"','"') # replace \" by " (for characters with diaeresis)
133 [ucs4,command,dead] = line.split(None,2)
134 spec_chars.append([command, unichr(eval(ucs4))])
140 # If the character is a double-quote, then we need to escape it, too,
141 # since it is done that way in the LyX file.
142 if m.group(1) == "\"":
144 command += m.group(1) + m.group(2)
145 spec_chars.append([command, unichr(eval(ucs4))])
151 '''Takes a string, possibly multi-line, and returns the result of
152 converting LaTeX constructs into LyX constructs. Returns a list of
153 lines, suitable for insertion into document.body.'''
155 mathre = re.compile('^(.*?)(\$.*?\$)(.*)')
158 # Convert LaTeX to Unicode
159 reps = read_unicodesymbols()
162 data = data.replace(rep[0], rep[1])
164 # There seems to be a character in the unicodesymbols file
165 # that causes problems, namely, 0x2109.
168 data = wrap_into_ert(data, r'\"', '"')
170 lines = data.split('\n')
172 #document.warning("LINE: " + line)
173 #document.warning(str(i) + ":" + document.body[i])
174 #document.warning("LAST: " + document.body[-1])
178 g = wrap_into_ert(g, '\\', '\\backslash')
179 g = wrap_into_ert(g, '{', '{')
180 g = wrap_into_ert(g, '}', '}')
181 subst = g.split('\n')
186 f = m.group(2).replace('\\\\', '\\')
190 s = wrap_into_ert(s, '\\', '\\backslash')
191 s = wrap_into_ert(s, '{', '{')
192 s = wrap_into_ert(s, '}', '}')
193 subst = s.split('\n')
195 retval.append("\\begin_inset Formula " + f)
196 retval.append("\\end_inset")
198 # Generic, \\ -> \backslash:
199 g = wrap_into_ert(g, r'\\', '\\backslash')
200 g = wrap_into_ert(g, '{', '{')
201 g = wrap_into_ert(g, '}', '}')
202 subst = g.split('\n')
207 ####################################################################
209 def convert_ltcaption(document):
212 i = find_token(document.body, "\\begin_inset Tabular", i)
215 j = find_end_of_inset(document.body, i + 1)
217 document.warning("Malformed LyX document: Could not find end of tabular.")
220 nrows = int(document.body[i+1].split('"')[3])
221 ncols = int(document.body[i+1].split('"')[5])
224 for k in range(nrows):
225 m = find_token(document.body, "<row", m)
228 for k in range(ncols):
229 m = find_token(document.body, "<cell", m)
231 mend = find_token(document.body, "</cell>", m + 1)
232 # first look for caption insets
233 mcap = find_token(document.body, "\\begin_inset Caption", m + 1, mend)
234 # then look for ERT captions
236 mcap = find_token(document.body, "caption", m + 1, mend)
238 mcap = find_token(document.body, "\\backslash", mcap - 1, mcap)
241 if caption == 'true':
243 set_option(document, r, 'caption', 'true')
244 set_option(document, m, 'multicolumn', '1')
245 set_option(document, m, 'bottomline', 'false')
246 set_option(document, m, 'topline', 'false')
247 set_option(document, m, 'rightline', 'false')
248 set_option(document, m, 'leftline', 'false')
249 #j = find_end_of_inset(document.body, j + 1)
251 set_option(document, m, 'multicolumn', '2')
258 #FIXME Use of wrap_into_ert can confuse lyx2lyx
259 def revert_ltcaption(document):
262 i = find_token(document.body, "\\begin_inset Tabular", i)
265 j = find_end_of_inset(document.body, i + 1)
267 document.warning("Malformed LyX document: Could not find end of tabular.")
271 nrows = int(document.body[i+1].split('"')[3])
272 ncols = int(document.body[i+1].split('"')[5])
274 for k in range(nrows):
275 m = find_token(document.body, "<row", m)
276 caption = get_option(document, m, 'caption', 'false')
277 if caption == 'true':
278 remove_option(document, m, 'caption')
279 for k in range(ncols):
280 m = find_token(document.body, "<cell", m)
281 remove_option(document, m, 'multicolumn')
283 m = find_token(document.body, "\\begin_inset Caption", m)
286 m = find_end_of_inset(document.body, m + 1)
287 document.body[m] += wrap_into_ert("","","\\backslash\n\\backslash\n%")
293 def convert_tablines(document):
296 i = find_token(document.body, "\\begin_inset Tabular", i)
298 # LyX 1.3 inserted an extra space between \begin_inset
299 # and Tabular so let us try if this is the case and fix it.
300 i = find_token(document.body, "\\begin_inset Tabular", i)
304 document.body[i] = "\\begin_inset Tabular"
305 j = find_end_of_inset(document.body, i + 1)
307 document.warning("Malformed LyX document: Could not find end of tabular.")
311 nrows = int(document.body[i+1].split('"')[3])
312 ncols = int(document.body[i+1].split('"')[5])
315 for k in range(ncols):
316 m = find_token(document.body, "<column", m)
317 left = get_option(document, m, 'leftline', 'false')
318 right = get_option(document, m, 'rightline', 'false')
319 col_info.append([left, right])
320 remove_option(document, m, 'leftline')
321 remove_option(document, m, 'rightline')
325 for k in range(nrows):
326 m = find_token(document.body, "<row", m)
327 top = get_option(document, m, 'topline', 'false')
328 bottom = get_option(document, m, 'bottomline', 'false')
329 row_info.append([top, bottom])
330 remove_option(document, m, 'topline')
331 remove_option(document, m, 'bottomline')
336 for k in range(nrows*ncols):
337 m = find_token(document.body, "<cell", m)
338 mc_info.append(get_option(document, m, 'multicolumn', '0'))
341 for l in range(nrows):
342 for k in range(ncols):
343 m = find_token(document.body, '<cell', m)
344 if mc_info[l*ncols + k] == '0':
345 r = set_option(document, m, 'topline', row_info[l][0])
346 r = set_option(document, m, 'bottomline', row_info[l][1])
347 r = set_option(document, m, 'leftline', col_info[k][0])
348 r = set_option(document, m, 'rightline', col_info[k][1])
349 elif mc_info[l*ncols + k] == '1':
351 while s < ncols and mc_info[l*ncols + s] == '2':
353 if s < ncols and mc_info[l*ncols + s] != '1':
354 r = set_option(document, m, 'rightline', col_info[k][1])
355 if k > 0 and mc_info[l*ncols + k - 1] == '0':
356 r = set_option(document, m, 'leftline', col_info[k][0])
361 def revert_tablines(document):
364 i = find_token(document.body, "\\begin_inset Tabular", i)
367 j = find_end_of_inset(document.body, i + 1)
369 document.warning("Malformed LyX document: Could not find end of tabular.")
373 nrows = int(document.body[i+1].split('"')[3])
374 ncols = int(document.body[i+1].split('"')[5])
377 for k in range(nrows*ncols):
378 m = find_token(document.body, "<cell", m)
379 top = get_option(document, m, 'topline', 'false')
380 bottom = get_option(document, m, 'bottomline', 'false')
381 left = get_option(document, m, 'leftline', 'false')
382 right = get_option(document, m, 'rightline', 'false')
383 lines.append([top, bottom, left, right])
386 # we will want to ignore longtable captions
389 for k in range(nrows):
390 m = find_token(document.body, "<row", m)
391 caption = get_option(document, m, 'caption', 'false')
392 caption_info.append([caption])
397 for k in range(ncols):
398 m = find_token(document.body, "<column", m)
400 for l in range(nrows):
401 left = lines[l*ncols + k][2]
402 if left == 'false' and caption_info[l] == 'false':
404 set_option(document, m, 'leftline', left)
406 for l in range(nrows):
407 right = lines[l*ncols + k][3]
408 if right == 'false' and caption_info[l] == 'false':
410 set_option(document, m, 'rightline', right)
414 for k in range(nrows):
415 m = find_token(document.body, "<row", m)
417 for l in range(ncols):
418 top = lines[k*ncols + l][0]
421 if caption_info[k] == 'false':
423 set_option(document, m, 'topline', top)
425 for l in range(ncols):
426 bottom = lines[k*ncols + l][1]
427 if bottom == 'false':
429 if caption_info[k] == 'false':
431 set_option(document, m, 'bottomline', bottom)
437 def fix_wrong_tables(document):
440 i = find_token(document.body, "\\begin_inset Tabular", i)
443 j = find_end_of_inset(document.body, i + 1)
445 document.warning("Malformed LyX document: Could not find end of tabular.")
449 nrows = int(document.body[i+1].split('"')[3])
450 ncols = int(document.body[i+1].split('"')[5])
452 for l in range(nrows):
454 for k in range(ncols):
455 m = find_token(document.body, '<cell', m)
457 if document.body[m].find('multicolumn') != -1:
458 multicol_cont = int(document.body[m].split('"')[1])
460 if multicol_cont == 2 and (k == 0 or prev_multicolumn == 0):
461 document.body[m] = document.body[m][:5] + document.body[m][21:]
464 prev_multicolumn = multicol_cont
471 def close_begin_deeper(document):
475 i = find_tokens(document.body, ["\\begin_deeper", "\\end_deeper"], i)
480 if document.body[i][:13] == "\\begin_deeper":
487 document.body[-2:-2] = ['\\end_deeper' for i in range(depth)]
490 def long_charstyle_names(document):
493 i = find_token(document.body, "\\begin_inset CharStyle", i)
496 document.body[i] = document.body[i].replace("CharStyle ", "CharStyle CharStyle:")
499 def revert_long_charstyle_names(document):
502 i = find_token(document.body, "\\begin_inset CharStyle", i)
505 document.body[i] = document.body[i].replace("CharStyle CharStyle:", "CharStyle")
509 def axe_show_label(document):
512 i = find_token(document.body, "\\begin_inset CharStyle", i)
515 if document.body[i + 1].find("show_label") != -1:
516 if document.body[i + 1].find("true") != -1:
517 document.body[i + 1] = "status open"
518 del document.body[ i + 2]
520 if document.body[i + 1].find("false") != -1:
521 document.body[i + 1] = "status collapsed"
522 del document.body[ i + 2]
524 document.warning("Malformed LyX document: show_label neither false nor true.")
526 document.warning("Malformed LyX document: show_label missing in CharStyle.")
531 def revert_show_label(document):
534 i = find_token(document.body, "\\begin_inset CharStyle", i)
537 if document.body[i + 1].find("status open") != -1:
538 document.body.insert(i + 1, "show_label true")
540 if document.body[i + 1].find("status collapsed") != -1:
541 document.body.insert(i + 1, "show_label false")
543 document.warning("Malformed LyX document: no legal status line in CharStyle.")
546 def revert_begin_modules(document):
549 i = find_token(document.header, "\\begin_modules", i)
552 j = find_end_of(document.header, i, "\\begin_modules", "\\end_modules")
554 # this should not happen
556 document.header[i : j + 1] = []
558 def convert_flex(document):
559 "Convert CharStyle to Flex"
562 i = find_token(document.body, "\\begin_inset CharStyle", i)
565 document.body[i] = document.body[i].replace('\\begin_inset CharStyle', '\\begin_inset Flex')
567 def revert_flex(document):
568 "Convert Flex to CharStyle"
571 i = find_token(document.body, "\\begin_inset Flex", i)
574 document.body[i] = document.body[i].replace('\\begin_inset Flex', '\\begin_inset CharStyle')
577 # Discard PDF options for hyperref
578 def revert_pdf_options(document):
579 "Revert PDF options for hyperref."
580 # store the PDF options and delete the entries from the Lyx file
588 bookmarksnumbered = ""
590 bookmarksopenlevel = ""
598 i = find_token(document.header, "\\use_hyperref", i)
600 hyperref = get_value(document.header, "\\use_hyperref", i) == 'true'
601 del document.header[i]
602 i = find_token(document.header, "\\pdf_store_options", i)
604 del document.header[i]
605 i = find_token(document.header, "\\pdf_title", 0)
607 title = get_value_string(document.header, '\\pdf_title', 0, 0, True)
608 title = ' pdftitle={' + title + '}'
609 del document.header[i]
610 i = find_token(document.header, "\\pdf_author", 0)
612 author = get_value_string(document.header, '\\pdf_author', 0, 0, True)
614 author = ' pdfauthor={' + author + '}'
616 author = ',\n pdfauthor={' + author + '}'
617 del document.header[i]
618 i = find_token(document.header, "\\pdf_subject", 0)
620 subject = get_value_string(document.header, '\\pdf_subject', 0, 0, True)
621 if title == "" and author == "":
622 subject = ' pdfsubject={' + subject + '}'
624 subject = ',\n pdfsubject={' + subject + '}'
625 del document.header[i]
626 i = find_token(document.header, "\\pdf_keywords", 0)
628 keywords = get_value_string(document.header, '\\pdf_keywords', 0, 0, True)
629 if title == "" and author == "" and subject == "":
630 keywords = ' pdfkeywords={' + keywords + '}'
632 keywords = ',\n pdfkeywords={' + keywords + '}'
633 del document.header[i]
634 i = find_token(document.header, "\\pdf_bookmarks", 0)
636 bookmarks = get_value_string(document.header, '\\pdf_bookmarks', 0)
637 bookmarks = ',\n bookmarks=' + bookmarks
638 del document.header[i]
639 i = find_token(document.header, "\\pdf_bookmarksnumbered", i)
641 bookmarksnumbered = get_value_string(document.header, '\\pdf_bookmarksnumbered', 0)
642 bookmarksnumbered = ',\n bookmarksnumbered=' + bookmarksnumbered
643 del document.header[i]
644 i = find_token(document.header, "\\pdf_bookmarksopen", i)
646 bookmarksopen = get_value_string(document.header, '\\pdf_bookmarksopen', 0)
647 bookmarksopen = ',\n bookmarksopen=' + bookmarksopen
648 del document.header[i]
649 i = find_token(document.header, "\\pdf_bookmarksopenlevel", i)
651 bookmarksopenlevel = get_value_string(document.header, '\\pdf_bookmarksopenlevel', 0, 0, True)
652 bookmarksopenlevel = ',\n bookmarksopenlevel=' + bookmarksopenlevel
653 del document.header[i]
654 i = find_token(document.header, "\\pdf_breaklinks", i)
656 breaklinks = get_value_string(document.header, '\\pdf_breaklinks', 0)
657 breaklinks = ',\n breaklinks=' + breaklinks
658 del document.header[i]
659 i = find_token(document.header, "\\pdf_pdfborder", i)
661 pdfborder = get_value_string(document.header, '\\pdf_pdfborder', 0)
662 if pdfborder == 'true':
663 pdfborder = ',\n pdfborder={0 0 0}'
665 pdfborder = ',\n pdfborder={0 0 1}'
666 del document.header[i]
667 i = find_token(document.header, "\\pdf_colorlinks", i)
669 colorlinks = get_value_string(document.header, '\\pdf_colorlinks', 0)
670 colorlinks = ',\n colorlinks=' + colorlinks
671 del document.header[i]
672 i = find_token(document.header, "\\pdf_backref", i)
674 backref = get_value_string(document.header, '\\pdf_backref', 0)
675 backref = ',\n backref=' + backref
676 del document.header[i]
677 i = find_token(document.header, "\\pdf_pagebackref", i)
679 pagebackref = get_value_string(document.header, '\\pdf_pagebackref', 0)
680 pagebackref = ',\n pagebackref=' + pagebackref
681 del document.header[i]
682 i = find_token(document.header, "\\pdf_pagemode", 0)
684 pagemode = get_value_string(document.header, '\\pdf_pagemode', 0)
685 pagemode = ',\n pdfpagemode=' + pagemode
686 del document.header[i]
687 i = find_token(document.header, "\\pdf_quoted_options", 0)
689 otheroptions = get_value_string(document.header, '\\pdf_quoted_options', 0, 0, True)
690 if title == "" and author == "" and subject == "" and keywords == "":
691 otheroptions = ' ' + otheroptions
693 otheroptions = ',\n ' + otheroptions
694 del document.header[i]
696 # write to the preamble when hyperref was used
698 # preamble write preparations
699 # bookmark numbers are only output when they are turned on
700 if bookmarksopen == ',\n bookmarksopen=true':
701 bookmarksopen = bookmarksopen + bookmarksopenlevel
702 if bookmarks == ',\n bookmarks=true':
703 bookmarks = bookmarks + bookmarksnumbered + bookmarksopen
705 bookmarks = bookmarks
706 # hypersetup is only output when there are things to be set up
707 setupstart = '\\hypersetup{%\n'
709 if otheroptions == "" and title == "" and author == ""\
710 and subject == "" and keywords == "":
714 add_to_preamble(document,
715 ['% Commands inserted by lyx2lyx for PDF properties',
716 '\\usepackage[unicode=true'
735 def remove_inzip_options(document):
736 "Remove inzipName and embed options from the Graphics inset"
739 i = find_token(document.body, "\\begin_inset Graphics", i)
742 j = find_end_of_inset(document.body, i + 1)
745 document.warning("Malformed LyX document: Could not find end of graphics inset.")
746 # If there's a inzip param, just remove that
747 k = find_token(document.body, "\tinzipName", i + 1, j)
750 # embed option must follow the inzipName option
751 del document.body[k+1]
755 def convert_inset_command(document):
758 \begin_inset LatexCommand cmd
760 \begin_inset CommandInset InsetType
765 i = find_token(document.body, "\\begin_inset LatexCommand", i)
768 line = document.body[i]
769 r = re.compile(r'\\begin_inset LatexCommand (.*)$')
773 #this is adapted from factory.cpp
774 if cmdName[0:4].lower() == "cite":
775 insetName = "citation"
776 elif cmdName == "url" or cmdName == "htmlurl":
778 elif cmdName[-3:] == "ref":
780 elif cmdName == "tableofcontents":
782 elif cmdName == "printnomenclature":
783 insetName = "nomencl_print"
784 elif cmdName == "printindex":
785 insetName = "index_print"
788 insertion = ["\\begin_inset CommandInset " + insetName, "LatexCommand " + cmdName]
789 document.body[i : i+1] = insertion
792 def revert_inset_command(document):
795 \begin_inset CommandInset InsetType
798 \begin_inset LatexCommand cmd
799 Some insets may end up being converted to insets earlier versions of LyX
800 will not be able to recognize. Not sure what to do about that.
804 i = find_token(document.body, "\\begin_inset CommandInset", i)
807 nextline = document.body[i+1]
808 r = re.compile(r'LatexCommand\s+(.*)$')
809 m = r.match(nextline)
811 document.warning("Malformed LyX document: Missing LatexCommand in " + document.body[i] + ".")
814 insertion = ["\\begin_inset LatexCommand " + cmdName]
815 document.body[i : i+2] = insertion
818 def convert_wrapfig_options(document):
819 "Convert optional options for wrap floats (wrapfig)."
820 # adds the tokens "lines", "placement", and "overhang"
823 i = find_token(document.body, "\\begin_inset Wrap figure", i)
826 document.body.insert(i + 1, "lines 0")
827 j = find_token(document.body, "placement", i)
828 # placement can be already set or not; if not, set it
830 document.body.insert(i + 3, "overhang 0col%")
832 document.body.insert(i + 2, "placement o")
833 document.body.insert(i + 3, "overhang 0col%")
837 def revert_wrapfig_options(document):
838 "Revert optional options for wrap floats (wrapfig)."
841 i = find_token(document.body, "\\begin_inset Wrap figure", i)
844 j = find_end_of_inset(document.body, i)
846 document.warning("Can't find end of Wrap inset at line " + str(i))
849 k = find_default_layout(document, i, j)
851 document.warning("Can't find default layout for Wrap figure!")
854 # Options should be between i and k now
855 l = find_token(document.body, "lines", i, k)
857 document.warning("Can't find lines option for Wrap figure!")
860 m = find_token(document.body, "overhang", i + 1, k)
862 document.warning("Malformed LyX document: Couldn't find overhang parameter of wrap float!")
865 # Do these in reverse order
871 def convert_latexcommand_index(document):
872 "Convert from LatexCommand form to collapsable form."
874 r1 = re.compile('name "(.*)"')
876 i = find_token(document.body, "\\begin_inset CommandInset index", i)
879 if document.body[i + 1] != "LatexCommand index": # Might also be index_print
881 m = r1.match(document.body[i + 2])
883 document.warning("Unable to match: " + document.body[i+2])
886 fullcontent = m.group(1)
887 #document.warning(fullcontent)
888 document.body[i:i + 3] = ["\\begin_inset Index",
890 "\\begin_layout Standard"]
892 # We are now on the blank line preceding "\end_inset"
893 # We will write the content here, into the inset.
895 linelist = latex2lyx(fullcontent)
896 document.body[i+1:i+1] = linelist
899 document.body.insert(i + 1, "\\end_layout")
903 def revert_latexcommand_index(document):
904 "Revert from collapsable form to LatexCommand form."
907 i = find_token(document.body, "\\begin_inset Index", i)
910 j = find_end_of_inset(document.body, i + 1)
913 del document.body[j - 1]
914 del document.body[j - 2] # \end_layout
915 document.body[i] = "\\begin_inset CommandInset index"
916 document.body[i + 1] = "LatexCommand index"
917 # clean up multiline stuff
920 for k in range(i + 3, j - 2):
921 line = document.body[k]
922 if line.startswith("\\begin_inset ERT"):
923 ert_end = find_end_of_inset(document.body, k + 1)
925 if line.startswith("\\begin_inset Formula"):
927 if line.startswith("\\begin_layout Standard"):
929 if line.startswith("\\begin_layout Plain Layout"):
931 if line.startswith("\\end_layout"):
933 if line.startswith("\\end_inset"):
935 if line.startswith("status collapsed"):
937 if line.startswith("status open"):
939 # a lossless reversion is not possible
940 # try at least to handle some common insets and settings
941 # do not replace inside ERTs
943 # Do the LyX text --> LaTeX conversion
944 for rep in replacements:
945 line = line.replace(rep[1], rep[0])
946 line = line.replace(r'\backslash', r'\textbackslash{}')
947 line = line.replace(r'\series bold', r'\bfseries{}').replace(r'\series default', r'\mdseries{}')
948 line = line.replace(r'\shape italic', r'\itshape{}').replace(r'\shape smallcaps', r'\scshape{}')
949 line = line.replace(r'\shape slanted', r'\slshape{}').replace(r'\shape default', r'\upshape{}')
950 line = line.replace(r'\emph on', r'\em{}').replace(r'\emph default', r'\em{}')
951 line = line.replace(r'\noun on', r'\scshape{}').replace(r'\noun default', r'\upshape{}')
952 line = line.replace(r'\bar under', r'\underbar{').replace(r'\bar default', r'}')
953 line = line.replace(r'\family sans', r'\sffamily{}').replace(r'\family default', r'\normalfont{}')
954 line = line.replace(r'\family typewriter', r'\ttfamily{}').replace(r'\family roman', r'\rmfamily{}')
955 line = line.replace(r'\InsetSpace ', r'').replace(r'\SpecialChar ', r'')
957 line = line.replace(r'\backslash', r'\\')
958 content = content + line;
959 document.body[i + 3] = "name " + '"' + content + '"'
960 for k in range(i + 4, j - 2):
961 del document.body[i + 4]
962 document.body.insert(i + 4, "")
963 del document.body[i + 2] # \begin_layout standard
967 def revert_wraptable(document):
968 "Revert wrap table to wrap figure."
971 i = find_token(document.body, "\\begin_inset Wrap table", i)
974 document.body[i] = document.body[i].replace('\\begin_inset Wrap table', '\\begin_inset Wrap figure')
978 def revert_vietnamese(document):
979 "Set language Vietnamese to English"
980 # Set document language from Vietnamese to English
982 if document.language == "vietnamese":
983 document.language = "english"
984 i = find_token(document.header, "\\language", 0)
986 document.header[i] = "\\language english"
989 j = find_token(document.body, "\\lang vietnamese", j)
992 document.body[j] = document.body[j].replace("\\lang vietnamese", "\\lang english")
996 def revert_japanese(document):
997 "Set language japanese-plain to japanese"
998 # Set document language from japanese-plain to japanese
1000 if document.language == "japanese-plain":
1001 document.language = "japanese"
1002 i = find_token(document.header, "\\language", 0)
1004 document.header[i] = "\\language japanese"
1007 j = find_token(document.body, "\\lang japanese-plain", j)
1010 document.body[j] = document.body[j].replace("\\lang japanese-plain", "\\lang japanese")
1014 def revert_japanese_encoding(document):
1015 "Set input encoding form EUC-JP-plain to EUC-JP etc."
1016 # Set input encoding form EUC-JP-plain to EUC-JP etc.
1018 i = find_token(document.header, "\\inputencoding EUC-JP-plain", 0)
1020 document.header[i] = "\\inputencoding EUC-JP"
1022 j = find_token(document.header, "\\inputencoding JIS-plain", 0)
1024 document.header[j] = "\\inputencoding JIS"
1026 k = find_token(document.header, "\\inputencoding SJIS-plain", 0)
1027 if k != -1: # convert to UTF8 since there is currently no SJIS encoding
1028 document.header[k] = "\\inputencoding UTF8"
1031 def revert_inset_info(document):
1032 'Replace info inset with its content'
1035 i = find_token(document.body, '\\begin_inset Info', i)
1038 j = find_end_of_inset(document.body, i + 1)
1041 document.warning("Malformed LyX document: Could not find end of Info inset.")
1044 for k in range(i, j+1):
1045 if document.body[k].startswith("arg"):
1046 arg = document.body[k][3:].strip().strip('"')
1047 if document.body[k].startswith("type"):
1048 type = document.body[k][4:].strip().strip('"')
1049 # I think there is a newline after \\end_inset, which should be removed.
1050 if document.body[j + 1].strip() == "":
1051 document.body[i : (j + 2)] = [type + ':' + arg]
1053 document.body[i : (j + 1)] = [type + ':' + arg]
1056 def convert_pdf_options(document):
1057 # Set the pdfusetitle tag, delete the pdf_store_options,
1058 # set quotes for bookmarksopenlevel"
1059 has_hr = get_value(document.header, "\\use_hyperref", 0, default = "0")
1061 k = find_token(document.header, "\\use_hyperref", 0)
1062 document.header.insert(k + 1, "\\pdf_pdfusetitle true")
1063 k = find_token(document.header, "\\pdf_store_options", 0)
1065 del document.header[k]
1066 i = find_token(document.header, "\\pdf_bookmarksopenlevel", k)
1068 document.header[i] = document.header[i].replace('"', '')
1071 def revert_pdf_options_2(document):
1072 # reset the pdfusetitle tag, set quotes for bookmarksopenlevel"
1073 k = find_token(document.header, "\\use_hyperref", 0)
1074 i = find_token(document.header, "\\pdf_pdfusetitle", k)
1076 del document.header[i]
1077 i = find_token(document.header, "\\pdf_bookmarksopenlevel", k)
1079 values = document.header[i].split()
1080 values[1] = ' "' + values[1] + '"'
1081 document.header[i] = ''.join(values)
1084 def convert_htmlurl(document):
1085 'Convert "htmlurl" to "href" insets for docbook'
1086 if document.backend != "docbook":
1090 i = find_token(document.body, "\\begin_inset CommandInset url", i)
1093 document.body[i] = "\\begin_inset CommandInset href"
1094 document.body[i + 1] = "LatexCommand href"
1098 def convert_url(document):
1099 'Convert url insets to url charstyles'
1100 if document.backend == "docbook":
1104 i = find_token(document.body, "\\begin_inset CommandInset url", i)
1107 n = find_token(document.body, "name", i)
1109 # place the URL name in typewriter before the new URL insert
1110 # grab the name 'bla' from the e.g. the line 'name "bla"',
1111 # therefore start with the 6th character
1112 name = document.body[n][6:-1]
1113 newname = [name + " "]
1114 document.body[i:i] = newname
1116 j = find_token(document.body, "target", i)
1118 document.warning("Malformed LyX document: Can't find target for url inset")
1121 target = document.body[j][8:-1]
1122 k = find_token(document.body, "\\end_inset", j)
1124 document.warning("Malformed LyX document: Can't find end of url inset")
1127 newstuff = ["\\begin_inset Flex URL",
1128 "status collapsed", "",
1129 "\\begin_layout Standard",
1134 document.body[i:k] = newstuff
1137 def convert_ams_classes(document):
1138 tc = document.textclass
1139 if (tc != "amsart" and tc != "amsart-plain" and
1140 tc != "amsart-seq" and tc != "amsbook"):
1142 if tc == "amsart-plain":
1143 document.textclass = "amsart"
1144 document.set_textclass()
1145 document.add_module("Theorems (Starred)")
1147 if tc == "amsart-seq":
1148 document.textclass = "amsart"
1149 document.set_textclass()
1150 document.add_module("Theorems (AMS)")
1152 #Now we want to see if any of the environments in the extended theorems
1153 #module were used in this document. If so, we'll add that module, too.
1154 layouts = ["Criterion", "Algorithm", "Axiom", "Condition", "Note", \
1155 "Notation", "Summary", "Acknowledgement", "Conclusion", "Fact", \
1158 r = re.compile(r'^\\begin_layout (.*?)\*?\s*$')
1161 i = find_token(document.body, "\\begin_layout", i)
1164 m = r.match(document.body[i])
1166 document.warning("Weirdly formed \\begin_layout at line %d of body!" % i)
1170 if layouts.count(m) != 0:
1171 document.add_module("Theorems (AMS-Extended)")
1175 def revert_href(document):
1176 'Reverts hyperlink insets (href) to url insets (url)'
1179 i = find_token(document.body, "\\begin_inset CommandInset href", i)
1182 document.body[i : i + 2] = \
1183 ["\\begin_inset CommandInset url", "LatexCommand url"]
1186 def revert_url(document):
1187 'Reverts Flex URL insets to old-style URL insets'
1190 i = find_token(document.body, "\\begin_inset Flex URL", i)
1193 j = find_end_of_inset(document.body, i)
1195 document.warning("Can't find end of inset in revert_url!")
1197 k = find_default_layout(document, i, j)
1199 document.warning("Can't find default layout in revert_url!")
1202 l = find_end_of(document.body, k, "\\begin_layout", "\\end_layout")
1203 if l == -1 or l >= j:
1204 document.warning("Can't find end of default layout in revert_url!")
1207 # OK, so the inset's data is between lines k and l.
1208 data = " ".join(document.body[k+1:l])
1210 newinset = ["\\begin_inset LatexCommand url", "target \"" + data + "\"",\
1212 document.body[i:j+1] = newinset
1213 i = i + len(newinset)
1216 def convert_include(document):
1217 'Converts include insets to new format.'
1219 r = re.compile(r'\\begin_inset Include\s+\\([^{]+){([^}]*)}(?:\[(.*)\])?')
1221 i = find_token(document.body, "\\begin_inset Include", i)
1224 line = document.body[i]
1225 previewline = document.body[i + 1]
1228 document.warning("Unable to match line " + str(i) + " of body!")
1234 insertion = ["\\begin_inset CommandInset include",
1235 "LatexCommand " + cmd, previewline,
1236 "filename \"" + fn + "\""]
1239 insertion.append("lstparams " + '"' + opt + '"')
1241 document.body[i : i + 2] = insertion
1245 def revert_include(document):
1246 'Reverts include insets to old format.'
1248 r0 = re.compile('preview.*')
1249 r1 = re.compile('LatexCommand (.+)')
1250 r2 = re.compile('filename "(.+)"')
1251 r3 = re.compile('lstparams "(.*)"')
1253 i = find_token(document.body, "\\begin_inset CommandInset include", i)
1257 if r0.match(document.body[nextline]):
1258 previewline = document.body[nextline]
1262 m = r1.match(document.body[nextline])
1264 document.warning("Malformed LyX document: No LatexCommand line for `" +
1265 document.body[i] + "' on line " + str(i) + ".")
1270 m = r2.match(document.body[nextline])
1272 document.warning("Malformed LyX document: No filename line for `" + \
1273 document.body[i] + "' on line " + str(i) + ".")
1279 if (cmd == "lstinputlisting"):
1280 m = r3.match(document.body[nextline])
1282 options = m.group(1)
1285 newline = "\\begin_inset Include \\" + cmd + "{" + fn + "}"
1287 newline += ("[" + options + "]")
1288 insertion = [newline]
1289 if previewline != "":
1290 insertion.append(previewline)
1291 document.body[i : nextline] = insertion
1295 def revert_albanian(document):
1296 "Set language Albanian to English"
1298 if document.language == "albanian":
1299 document.language = "english"
1300 i = find_token(document.header, "\\language", 0)
1302 document.header[i] = "\\language english"
1305 j = find_token(document.body, "\\lang albanian", j)
1308 document.body[j] = document.body[j].replace("\\lang albanian", "\\lang english")
1312 def revert_lowersorbian(document):
1313 "Set language lower Sorbian to English"
1315 if document.language == "lowersorbian":
1316 document.language = "english"
1317 i = find_token(document.header, "\\language", 0)
1319 document.header[i] = "\\language english"
1322 j = find_token(document.body, "\\lang lowersorbian", j)
1325 document.body[j] = document.body[j].replace("\\lang lowersorbian", "\\lang english")
1329 def revert_uppersorbian(document):
1330 "Set language uppersorbian to usorbian as this was used in LyX 1.5"
1332 if document.language == "uppersorbian":
1333 document.language = "usorbian"
1334 i = find_token(document.header, "\\language", 0)
1336 document.header[i] = "\\language usorbian"
1339 j = find_token(document.body, "\\lang uppersorbian", j)
1342 document.body[j] = document.body[j].replace("\\lang uppersorbian", "\\lang usorbian")
1346 def convert_usorbian(document):
1347 "Set language usorbian to uppersorbian"
1349 if document.language == "usorbian":
1350 document.language = "uppersorbian"
1351 i = find_token(document.header, "\\language", 0)
1353 document.header[i] = "\\language uppersorbian"
1356 j = find_token(document.body, "\\lang usorbian", j)
1359 document.body[j] = document.body[j].replace("\\lang usorbian", "\\lang uppersorbian")
1363 def revert_macro_optional_params(document):
1364 "Convert macro definitions with optional parameters into ERTs"
1365 # Stub to convert macro definitions with one or more optional parameters
1366 # into uninterpreted ERT insets
1369 def revert_hyperlinktype(document):
1370 'Reverts hyperlink type'
1374 i = find_token(document.body, "target", i)
1377 j = find_token(document.body, "type", i)
1381 del document.body[j]
1385 def revert_pagebreak(document):
1386 'Reverts pagebreak to ERT'
1389 i = find_token(document.body, "\\pagebreak", i)
1392 document.body[i] = '\\begin_inset ERT\nstatus collapsed\n\n' \
1393 '\\begin_layout Standard\n\n\n\\backslash\n' \
1394 'pagebreak{}\n\\end_layout\n\n\\end_inset\n\n'
1398 def revert_linebreak(document):
1399 'Reverts linebreak to ERT'
1402 i = find_token(document.body, "\\linebreak", i)
1405 document.body[i] = '\\begin_inset ERT\nstatus collapsed\n\n' \
1406 '\\begin_layout Standard\n\n\n\\backslash\n' \
1407 'linebreak{}\n\\end_layout\n\n\\end_inset\n\n'
1411 def revert_latin(document):
1412 "Set language Latin to English"
1414 if document.language == "latin":
1415 document.language = "english"
1416 i = find_token(document.header, "\\language", 0)
1418 document.header[i] = "\\language english"
1421 j = find_token(document.body, "\\lang latin", j)
1424 document.body[j] = document.body[j].replace("\\lang latin", "\\lang english")
1428 def revert_samin(document):
1429 "Set language North Sami to English"
1431 if document.language == "samin":
1432 document.language = "english"
1433 i = find_token(document.header, "\\language", 0)
1435 document.header[i] = "\\language english"
1438 j = find_token(document.body, "\\lang samin", j)
1441 document.body[j] = document.body[j].replace("\\lang samin", "\\lang english")
1445 def convert_serbocroatian(document):
1446 "Set language Serbocroatian to Croatian as this was really Croatian in LyX 1.5"
1448 if document.language == "serbocroatian":
1449 document.language = "croatian"
1450 i = find_token(document.header, "\\language", 0)
1452 document.header[i] = "\\language croatian"
1455 j = find_token(document.body, "\\lang serbocroatian", j)
1458 document.body[j] = document.body[j].replace("\\lang serbocroatian", "\\lang croatian")
1462 def convert_framed_notes(document):
1463 "Convert framed notes to boxes. "
1466 i = find_tokens(document.body, ["\\begin_inset Note Framed", "\\begin_inset Note Shaded"], i)
1469 subst = [document.body[i].replace("\\begin_inset Note", "\\begin_inset Box"),
1478 'height_special "totalheight"']
1479 document.body[i:i+1] = subst
1483 def convert_module_names(document):
1484 modulemap = { 'Braille' : 'braille', 'Endnote' : 'endnotes', 'Foot to End' : 'foottoend',\
1485 'Hanging' : 'hanging', 'Linguistics' : 'linguistics', 'Logical Markup' : 'logicalmkup', \
1486 'Theorems (AMS-Extended)' : 'theorems-ams-extended', 'Theorems (AMS)' : 'theorems-ams', \
1487 'Theorems (Order By Chapter)' : 'theorems-chap', 'Theorems (Order By Section)' : 'theorems-sec', \
1488 'Theorems (Starred)' : 'theorems-starred', 'Theorems' : 'theorems-std' }
1489 modlist = document.get_module_list()
1490 if len(modlist) == 0:
1494 if modulemap.has_key(mod):
1495 newmodlist.append(modulemap[mod])
1497 document.warning("Can't find module %s in the module map!" % mod)
1498 newmodlist.append(mod)
1499 document.set_module_list(newmodlist)
1502 def revert_module_names(document):
1503 modulemap = { 'braille' : 'Braille', 'endnotes' : 'Endnote', 'foottoend' : 'Foot to End',\
1504 'hanging' : 'Hanging', 'linguistics' : 'Linguistics', 'logicalmkup' : 'Logical Markup', \
1505 'theorems-ams-extended' : 'Theorems (AMS-Extended)', 'theorems-ams' : 'Theorems (AMS)', \
1506 'theorems-chap' : 'Theorems (Order By Chapter)', 'theorems-sec' : 'Theorems (Order By Section)', \
1507 'theorems-starred' : 'Theorems (Starred)', 'theorems-std' : 'Theorems'}
1508 modlist = document.get_module_list()
1509 if len(modlist) == 0:
1513 if modulemap.has_key(mod):
1514 newmodlist.append(modulemap[mod])
1516 document.warning("Can't find module %s in the module map!" % mod)
1517 newmodlist.append(mod)
1518 document.set_module_list(newmodlist)
1521 def revert_colsep(document):
1522 i = find_token(document.header, "\\columnsep", 0)
1525 colsepline = document.header[i]
1526 r = re.compile(r'\\columnsep (.*)')
1527 m = r.match(colsepline)
1529 document.warning("Malformed column separation line!")
1532 del document.header[i]
1533 #it seems to be safe to add the package even if it is already used
1534 pretext = ["\\usepackage{geometry}", "\\geometry{columnsep=" + colsep + "}"]
1536 add_to_preamble(document, pretext)
1539 def revert_framed_notes(document):
1540 "Revert framed boxes to notes. "
1543 i = find_tokens(document.body, ["\\begin_inset Box Framed", "\\begin_inset Box Shaded"], i)
1547 j = find_end_of_inset(document.body, i + 1)
1550 document.warning("Malformed LyX document: Could not find end of Box inset.")
1551 k = find_token(document.body, "status", i + 1, j)
1553 document.warning("Malformed LyX document: Missing `status' tag in Box inset.")
1555 status = document.body[k]
1556 l = find_default_layout(document, i + 1, j)
1558 document.warning("Malformed LyX document: Missing `\\begin_layout' in Box inset.")
1560 m = find_token(document.body, "\\end_layout", i + 1, j)
1562 document.warning("Malformed LyX document: Missing `\\end_layout' in Box inset.")
1564 ibox = find_token(document.body, "has_inner_box 1", i + 1, k)
1565 pbox = find_token(document.body, "use_parbox 1", i + 1, k)
1566 if ibox == -1 and pbox == -1:
1567 document.body[i] = document.body[i].replace("\\begin_inset Box", "\\begin_inset Note")
1568 del document.body[i+1:k]
1570 document.body[i] = document.body[i].replace("\\begin_inset Box Shaded", "\\begin_inset Box Frameless")
1571 subst1 = [document.body[l],
1572 "\\begin_inset Note Shaded",
1574 '\\begin_layout Standard']
1575 document.body[l:l + 1] = subst1
1576 subst2 = [document.body[m], "\\end_layout", "\\end_inset"]
1577 document.body[m:m + 1] = subst2
1581 def revert_slash(document):
1582 'Revert \\SpecialChar \\slash{} to ERT'
1583 r = re.compile(r'\\SpecialChar \\slash{}')
1585 while i < len(document.body):
1586 m = r.match(document.body[i])
1588 subst = ['\\begin_inset ERT',
1589 'status collapsed', '',
1590 '\\begin_layout Standard',
1591 '', '', '\\backslash',
1595 document.body[i: i+1] = subst
1601 def revert_nobreakdash(document):
1602 'Revert \\SpecialChar \\nobreakdash- to ERT'
1604 while i < len(document.body):
1605 line = document.body[i]
1606 r = re.compile(r'\\SpecialChar \\nobreakdash-')
1609 subst = ['\\begin_inset ERT',
1610 'status collapsed', '',
1611 '\\begin_layout Standard', '', '',
1616 document.body[i:i+1] = subst
1618 j = find_token(document.header, "\\use_amsmath", 0)
1620 document.warning("Malformed LyX document: Missing '\\use_amsmath'.")
1622 document.header[j] = "\\use_amsmath 2"
1627 #Returns number of lines added/removed
1628 def revert_nocite_key(body, start, end):
1629 'key "..." -> \nocite{...}'
1630 r = re.compile(r'^key "(.*)"')
1634 m = r.match(body[i])
1636 body[i:i+1] = ["\\backslash", "nocite{" + m.group(1) + "}"]
1637 j += 1 # because we added a line
1638 i += 2 # skip that line
1641 j -= 1 # because we deleted a line
1642 # no need to change i, since it now points to the next line
1646 def revert_nocite(document):
1647 "Revert LatexCommand nocite to ERT"
1650 i = find_token(document.body, "\\begin_inset CommandInset citation", i)
1653 if (document.body[i+1] != "LatexCommand nocite"):
1654 # note that we already incremented i
1657 insetEnd = find_end_of_inset(document.body, i)
1659 #this should not happen
1660 document.warning("End of CommandInset citation not found in revert_nocite!")
1663 paramLocation = i + 2 #start of the inset's parameters
1665 document.body[i:i+2] = \
1666 ["\\begin_inset ERT", "status collapsed", "", "\\begin_layout Standard"]
1667 # that added two lines
1670 #print insetEnd, document.body[i: insetEnd + 1]
1671 insetEnd += revert_nocite_key(document.body, paramLocation, insetEnd)
1672 #print insetEnd, document.body[i: insetEnd + 1]
1673 document.body.insert(insetEnd, "\\end_layout")
1674 document.body.insert(insetEnd + 1, "")
1678 def revert_btprintall(document):
1679 "Revert (non-bibtopic) btPrintAll option to ERT \nocite{*}"
1680 i = find_token(document.header, '\\use_bibtopic', 0)
1682 document.warning("Malformed lyx document: Missing '\\use_bibtopic'.")
1684 if get_value(document.header, '\\use_bibtopic', 0) == "false":
1686 while i < len(document.body):
1687 i = find_token(document.body, "\\begin_inset CommandInset bibtex", i)
1690 j = find_end_of_inset(document.body, i + 1)
1692 #this should not happen
1693 document.warning("End of CommandInset bibtex not found in revert_btprintall!")
1694 j = len(document.body)
1695 # this range isn't really right, but it should be OK, since we shouldn't
1696 # see more than one matching line in each inset
1698 for k in range(i, j):
1699 if (document.body[k] == 'btprint "btPrintAll"'):
1700 del document.body[k]
1701 subst = ["\\begin_inset ERT",
1702 "status collapsed", "",
1703 "\\begin_layout Standard", "",
1708 document.body[i:i] = subst
1709 addlines = addedlines + len(subst) - 1
1713 def revert_bahasam(document):
1714 "Set language Bahasa Malaysia to Bahasa Indonesia"
1716 if document.language == "bahasam":
1717 document.language = "bahasa"
1718 i = find_token(document.header, "\\language", 0)
1720 document.header[i] = "\\language bahasa"
1723 j = find_token(document.body, "\\lang bahasam", j)
1726 document.body[j] = document.body[j].replace("\\lang bahasam", "\\lang bahasa")
1730 def revert_interlingua(document):
1731 "Set language Interlingua to English"
1733 if document.language == "interlingua":
1734 document.language = "english"
1735 i = find_token(document.header, "\\language", 0)
1737 document.header[i] = "\\language english"
1740 j = find_token(document.body, "\\lang interlingua", j)
1743 document.body[j] = document.body[j].replace("\\lang interlingua", "\\lang english")
1747 def revert_serbianlatin(document):
1748 "Set language Serbian-Latin to Croatian"
1750 if document.language == "serbian-latin":
1751 document.language = "croatian"
1752 i = find_token(document.header, "\\language", 0)
1754 document.header[i] = "\\language croatian"
1757 j = find_token(document.body, "\\lang serbian-latin", j)
1760 document.body[j] = document.body[j].replace("\\lang serbian-latin", "\\lang croatian")
1764 def revert_rotfloat(document):
1765 " Revert sideways custom floats. "
1768 # whitespace intended (exclude \\begin_inset FloatList)
1769 i = find_token(document.body, "\\begin_inset Float ", i)
1772 line = document.body[i]
1773 r = re.compile(r'\\begin_inset Float (.*)$')
1776 document.warning("Unable to match line " + str(i) + " of body!")
1779 floattype = m.group(1)
1780 if floattype == "figure" or floattype == "table":
1783 j = find_end_of_inset(document.body, i)
1785 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_rotfloat.")
1789 if get_value(document.body, 'sideways', i, j) == "false":
1792 l = find_default_layout(document, i + 1, j)
1794 document.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
1796 subst = ['\\begin_layout Standard',
1797 '\\begin_inset ERT',
1798 'status collapsed', '',
1799 '\\begin_layout Standard', '', '',
1801 'end{sideways' + floattype + '}',
1802 '\\end_layout', '', '\\end_inset']
1803 document.body[j : j+1] = subst
1804 addedLines = len(subst) - 1
1805 del document.body[i+1 : l]
1806 addedLines -= (l-1) - (i+1)
1807 subst = ['\\begin_inset ERT', 'status collapsed', '',
1808 '\\begin_layout Standard', '', '', '\\backslash',
1809 'begin{sideways' + floattype + '}',
1810 '\\end_layout', '', '\\end_inset', '',
1812 document.body[i : i+1] = subst
1813 addedLines += len(subst) - 1
1814 if floattype == "algorithm":
1815 add_to_preamble(document,
1816 ['% Commands inserted by lyx2lyx for sideways algorithm float',
1817 '\\usepackage{rotfloat}',
1818 '\\floatstyle{ruled}',
1819 '\\newfloat{algorithm}{tbp}{loa}',
1820 '\\floatname{algorithm}{Algorithm}'])
1822 document.warning("Cannot create preamble definition for custom float" + floattype + ".")
1826 def revert_widesideways(document):
1827 " Revert wide sideways floats. "
1830 # whitespace intended (exclude \\begin_inset FloatList)
1831 i = find_token(document.body, '\\begin_inset Float ', i)
1834 line = document.body[i]
1835 r = re.compile(r'\\begin_inset Float (.*)$')
1838 document.warning("Unable to match line " + str(i) + " of body!")
1841 floattype = m.group(1)
1842 if floattype != "figure" and floattype != "table":
1845 j = find_end_of_inset(document.body, i)
1847 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_widesideways.")
1850 if get_value(document.body, 'sideways', i, j) == "false" or \
1851 get_value(document.body, 'wide', i, j) == "false":
1854 l = find_default_layout(document, i + 1, j)
1856 document.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
1858 subst = ['\\begin_layout Standard', '\\begin_inset ERT',
1859 'status collapsed', '',
1860 '\\begin_layout Standard', '', '', '\\backslash',
1861 'end{sideways' + floattype + '*}',
1862 '\\end_layout', '', '\\end_inset']
1863 document.body[j : j+1] = subst
1864 addedLines = len(subst) - 1
1865 del document.body[i+1:l-1]
1866 addedLines -= (l-1) - (i+1)
1867 subst = ['\\begin_inset ERT', 'status collapsed', '',
1868 '\\begin_layout Standard', '', '', '\\backslash',
1869 'begin{sideways' + floattype + '*}', '\\end_layout', '',
1870 '\\end_inset', '', '\\end_layout', '']
1871 document.body[i : i+1] = subst
1872 addedLines += len(subst) - 1
1873 add_to_preamble(document, ['\\usepackage{rotfloat}\n'])
1877 def revert_inset_embedding(document, type):
1878 ' Remove embed tag from certain type of insets'
1881 i = find_token(document.body, "\\begin_inset %s" % type, i)
1884 j = find_end_of_inset(document.body, i)
1886 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_inset_embedding.")
1889 k = find_token(document.body, "\tembed", i, j)
1891 k = find_token(document.body, "embed", i, j)
1893 del document.body[k]
1897 def revert_external_embedding(document):
1898 ' Remove embed tag from external inset '
1899 revert_inset_embedding(document, 'External')
1902 def convert_subfig(document):
1903 " Convert subfigures to subfloats. "
1906 i = find_token(document.body, '\\begin_inset Graphics', i)
1909 endInset = find_end_of_inset(document.body, i)
1911 document.warning("Malformed lyx document: Missing '\\end_inset' in convert_subfig.")
1914 k = find_token(document.body, '\tsubcaption', i, endInset)
1918 l = find_token(document.body, '\tsubcaptionText', i, endInset)
1920 document.warning("Malformed lyx document: Can't find subcaptionText!")
1923 caption = document.body[l][16:].strip('"')
1924 del document.body[l]
1925 del document.body[k]
1927 subst = ['\\begin_inset Float figure', 'wide false', 'sideways false',
1928 'status open', '', '\\begin_layout Plain Layout', '\\begin_inset Caption',
1929 '', '\\begin_layout Plain Layout'] + latex2lyx(caption) + \
1930 [ '\\end_layout', '', '\\end_inset', '',
1931 '\\end_layout', '', '\\begin_layout Plain Layout']
1932 document.body[i : i] = subst
1933 addedLines += len(subst)
1934 endInset += addedLines
1935 subst = ['', '\\end_inset', '', '\\end_layout']
1936 document.body[endInset : endInset] = subst
1937 addedLines += len(subst)
1941 def revert_subfig(document):
1942 " Revert subfloats. "
1945 # whitespace intended (exclude \\begin_inset FloatList)
1946 i = find_tokens(document.body, ['\\begin_inset Float ', '\\begin_inset Wrap'], i)
1952 j = find_end_of_inset(document.body, i)
1954 document.warning("Malformed lyx document: Missing '\\end_inset' (float) at line " + str(i + len(document.header)) + ".\n\t" + document.body[i])
1955 # document.warning(document.body[i-1] + "\n" + document.body[i+1])
1957 continue # this will get us back to the outer loop, since j == -1
1958 # look for embedded float (= subfloat)
1959 # whitespace intended (exclude \\begin_inset FloatList)
1960 k = find_token(document.body, '\\begin_inset Float ', i + 1, j)
1963 l = find_end_of_inset(document.body, k)
1965 document.warning("Malformed lyx document: Missing '\\end_inset' (embedded float).")
1968 continue # escape to the outer loop
1969 m = find_default_layout(document, k + 1, l)
1971 cap = find_token(document.body, '\\begin_inset Caption', k + 1, l)
1976 capend = find_end_of_inset(document.body, cap)
1978 document.warning("Malformed lyx document: Missing '\\end_inset' (caption).")
1982 lbl = find_token(document.body, '\\begin_inset CommandInset label', cap, capend)
1984 lblend = find_end_of_inset(document.body, lbl + 1)
1986 document.warning("Malformed lyx document: Missing '\\end_inset' (label).")
1988 for line in document.body[lbl:lblend + 1]:
1989 if line.startswith('name '):
1990 label = line.split()[1].strip('"')
1997 opt = find_token(document.body, '\\begin_inset OptArg', cap, capend)
1999 optend = find_end_of_inset(document.body, opt)
2001 document.warning("Malformed lyx document: Missing '\\end_inset' (OptArg).")
2003 optc = find_default_layout(document, opt, optend)
2005 document.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
2007 optcend = find_end_of(document.body, optc, "\\begin_layout", "\\end_layout")
2008 for line in document.body[optc:optcend]:
2009 if not line.startswith('\\'):
2010 shortcap += line.strip()
2014 for line in document.body[cap:capend]:
2015 if line in document.body[lbl:lblend]:
2017 elif line in document.body[opt:optend]:
2019 elif not line.startswith('\\'):
2020 caption += line.strip()
2022 caption += "\\backslash\nlabel{" + label + "}"
2023 subst = '\\begin_layout Plain Layout\n\\begin_inset ERT\nstatus collapsed\n\n' \
2024 '\\begin_layout Plain Layout\n\n}\n\\end_layout\n\n\\end_inset\n\n' \
2025 '\\end_layout\n\n\\begin_layout Plain Layout\n'
2026 subst = subst.split('\n')
2027 document.body[l : l+1] = subst
2028 addedLines = len(subst) - 1
2029 # this is before l and so is unchanged by the multiline insertion
2031 del document.body[cap:capend+1]
2032 addedLines -= (capend + 1 - cap)
2033 del document.body[k+1:m-1]
2034 addedLines -= (m - 1 - (k + 1))
2035 insertion = '\\begin_inset ERT\nstatus collapsed\n\n' \
2036 '\\begin_layout Plain Layout\n\n\\backslash\n' \
2038 if len(shortcap) > 0:
2039 insertion = insertion + "[" + shortcap + "]"
2040 if len(caption) > 0:
2041 insertion = insertion + "[" + caption + "]"
2042 insertion = insertion + '{%\n\\end_layout\n\n\\end_inset\n\n\\end_layout\n'
2043 insertion = insertion.split('\n')
2044 document.body[k : k + 1] = insertion
2045 addedLines += len(insertion) - 1
2046 add_to_preamble(document, ['\\usepackage{subfig}\n'])
2050 def revert_wrapplacement(document):
2051 " Revert placement options wrap floats (wrapfig). "
2054 i = find_token(document.body, "\\begin_inset Wrap figure", i)
2057 e = find_end_of_inset(document.body, i)
2058 j = find_token(document.body, "placement", i + 1, e)
2060 document.warning("Malformed LyX document: Couldn't find placement parameter of wrap float.")
2063 r = re.compile("placement (o|i|l|r)")
2064 m = r.match(document.body[j])
2066 document.warning("Malformed LyX document: Placement option isn't O|I|R|L!")
2067 document.body[j] = "placement " + m.group(1).lower()
2071 def remove_extra_embedded_files(document):
2072 " Remove \extra_embedded_files from buffer params "
2073 i = find_token(document.header, '\\extra_embedded_files', 0)
2076 document.header.pop(i)
2079 def convert_spaceinset(document):
2080 " Convert '\\InsetSpace foo' to '\\begin_inset Space foo\n\\end_inset' "
2082 while i < len(document.body):
2083 m = re.match(r'(.*)\\InsetSpace (.*)', document.body[i])
2087 subst = [before, "\\begin_inset Space " + after, "\\end_inset"]
2088 document.body[i: i+1] = subst
2094 def revert_spaceinset(document):
2095 " Revert '\\begin_inset Space foo\n\\end_inset' to '\\InsetSpace foo' "
2098 i = find_token(document.body, "\\begin_inset Space", i)
2101 j = find_end_of_inset(document.body, i)
2103 document.warning("Malformed LyX document: Could not find end of space inset.")
2105 document.body[i] = document.body[i].replace('\\begin_inset Space', '\\InsetSpace')
2106 del document.body[j]
2109 def convert_hfill(document):
2110 " Convert hfill to space inset "
2113 i = find_token(document.body, "\\hfill", i)
2116 subst = document.body[i].replace('\\hfill', \
2117 '\n\\begin_inset Space \\hfill{}\n\\end_inset')
2118 subst = subst.split('\n')
2119 document.body[i : i+1] = subst
2123 def revert_hfills(document):
2124 ' Revert \\hfill commands '
2125 hfill = re.compile(r'\\hfill')
2126 dotfill = re.compile(r'\\dotfill')
2127 hrulefill = re.compile(r'\\hrulefill')
2130 i = find_token(document.body, "\\InsetSpace", i)
2133 if hfill.search(document.body[i]):
2134 document.body[i] = \
2135 document.body[i].replace('\\InsetSpace \\hfill{}', '\\hfill')
2138 if dotfill.search(document.body[i]):
2139 subst = document.body[i].replace('\\InsetSpace \\dotfill{}', \
2140 '\\begin_inset ERT\nstatus collapsed\n\n' \
2141 '\\begin_layout Standard\n\n\n\\backslash\n' \
2142 'dotfill{}\n\\end_layout\n\n\\end_inset\n\n')
2143 subst = subst.split('\n')
2144 document.body[i : i+1] = subst
2147 if hrulefill.search(document.body[i]):
2148 subst = document.body[i].replace('\\InsetSpace \\hrulefill{}', \
2149 '\\begin_inset ERT\nstatus collapsed\n\n' \
2150 '\\begin_layout Standard\n\n\n\\backslash\n' \
2151 'hrulefill{}\n\\end_layout\n\n\\end_inset\n\n')
2152 subst = subst.split('\n')
2153 document.body[i : i+1] = subst
2158 def revert_hspace(document):
2159 ' Revert \\InsetSpace \\hspace{} to ERT '
2161 hspace = re.compile(r'\\hspace{}')
2162 hstar = re.compile(r'\\hspace\*{}')
2164 i = find_token(document.body, "\\InsetSpace \\hspace", i)
2167 length = get_value(document.body, '\\length', i+1)
2169 document.warning("Malformed lyx document: Missing '\\length' in Space inset.")
2171 del document.body[i+1]
2173 if hstar.search(document.body[i]):
2174 subst = document.body[i].replace('\\InsetSpace \\hspace*{}', \
2175 '\\begin_inset ERT\nstatus collapsed\n\n' \
2176 '\\begin_layout Standard\n\n\n\\backslash\n' \
2177 'hspace*{' + length + '}\n\\end_layout\n\n\\end_inset\n\n')
2178 subst = subst.split('\n')
2179 document.body[i : i+1] = subst
2180 addedLines += len(subst) - 1
2183 if hspace.search(document.body[i]):
2184 subst = document.body[i].replace('\\InsetSpace \\hspace{}', \
2185 '\\begin_inset ERT\nstatus collapsed\n\n' \
2186 '\\begin_layout Standard\n\n\n\\backslash\n' \
2187 'hspace{' + length + '}\n\\end_layout\n\n\\end_inset\n\n')
2188 subst = subst.split('\n')
2189 document.body[i : i+1] = subst
2190 addedLines += len(subst) - 1
2196 def revert_protected_hfill(document):
2197 ' Revert \\begin_inset Space \\hspace*{\\fill} to ERT '
2200 i = find_token(document.body, '\\begin_inset Space \\hspace*{\\fill}', i)
2203 j = find_end_of_inset(document.body, i)
2205 document.warning("Malformed LyX document: Could not find end of space inset.")
2207 del document.body[j]
2208 subst = document.body[i].replace('\\begin_inset Space \\hspace*{\\fill}', \
2209 '\\begin_inset ERT\nstatus collapsed\n\n' \
2210 '\\begin_layout Standard\n\n\n\\backslash\n' \
2211 'hspace*{\n\\backslash\nfill}\n\\end_layout\n\n\\end_inset\n\n')
2212 subst = subst.split('\n')
2213 document.body[i : i+1] = subst
2217 def revert_leftarrowfill(document):
2218 ' Revert \\begin_inset Space \\leftarrowfill{} to ERT '
2221 i = find_token(document.body, '\\begin_inset Space \\leftarrowfill{}', i)
2224 j = find_end_of_inset(document.body, i)
2226 document.warning("Malformed LyX document: Could not find end of space inset.")
2228 del document.body[j]
2229 subst = document.body[i].replace('\\begin_inset Space \\leftarrowfill{}', \
2230 '\\begin_inset ERT\nstatus collapsed\n\n' \
2231 '\\begin_layout Standard\n\n\n\\backslash\n' \
2232 'leftarrowfill{}\n\\end_layout\n\n\\end_inset\n\n')
2233 subst = subst.split('\n')
2234 document.body[i : i+1] = subst
2238 def revert_rightarrowfill(document):
2239 ' Revert \\begin_inset Space \\rightarrowfill{} to ERT '
2242 i = find_token(document.body, '\\begin_inset Space \\rightarrowfill{}', i)
2245 j = find_end_of_inset(document.body, i)
2247 document.warning("Malformed LyX document: Could not find end of space inset.")
2249 del document.body[j]
2250 subst = document.body[i].replace('\\begin_inset Space \\rightarrowfill{}', \
2251 '\\begin_inset ERT\nstatus collapsed\n\n' \
2252 '\\begin_layout Standard\n\n\n\\backslash\n' \
2253 'rightarrowfill{}\n\\end_layout\n\n\\end_inset\n\n')
2254 subst = subst.split('\n')
2255 document.body[i : i+1] = subst
2259 def revert_upbracefill(document):
2260 ' Revert \\begin_inset Space \\upbracefill{} to ERT '
2263 i = find_token(document.body, '\\begin_inset Space \\upbracefill{}', i)
2266 j = find_end_of_inset(document.body, i)
2268 document.warning("Malformed LyX document: Could not find end of space inset.")
2270 del document.body[j]
2271 subst = document.body[i].replace('\\begin_inset Space \\upbracefill{}', \
2272 '\\begin_inset ERT\nstatus collapsed\n\n' \
2273 '\\begin_layout Standard\n\n\n\\backslash\n' \
2274 'upbracefill{}\n\\end_layout\n\n\\end_inset\n\n')
2275 subst = subst.split('\n')
2276 document.body[i : i+1] = subst
2280 def revert_downbracefill(document):
2281 ' Revert \\begin_inset Space \\downbracefill{} to ERT '
2284 i = find_token(document.body, '\\begin_inset Space \\downbracefill{}', i)
2287 j = find_end_of_inset(document.body, i)
2289 document.warning("Malformed LyX document: Could not find end of space inset.")
2291 del document.body[j]
2292 subst = document.body[i].replace('\\begin_inset Space \\downbracefill{}', \
2293 '\\begin_inset ERT\nstatus collapsed\n\n' \
2294 '\\begin_layout Standard\n\n\n\\backslash\n' \
2295 'downbracefill{}\n\\end_layout\n\n\\end_inset\n\n')
2296 subst = subst.split('\n')
2297 document.body[i : i+1] = subst
2301 def revert_local_layout(document):
2302 ' Revert local layout headers.'
2305 i = find_token(document.header, "\\begin_local_layout", i)
2308 j = find_end_of(document.header, i, "\\begin_local_layout", "\\end_local_layout")
2310 # this should not happen
2312 document.header[i : j + 1] = []
2315 def convert_pagebreaks(document):
2316 ' Convert inline Newpage insets to new format '
2319 i = find_token(document.body, '\\newpage', i)
2322 document.body[i:i+1] = ['\\begin_inset Newpage newpage',
2326 i = find_token(document.body, '\\pagebreak', i)
2329 document.body[i:i+1] = ['\\begin_inset Newpage pagebreak',
2333 i = find_token(document.body, '\\clearpage', i)
2336 document.body[i:i+1] = ['\\begin_inset Newpage clearpage',
2340 i = find_token(document.body, '\\cleardoublepage', i)
2343 document.body[i:i+1] = ['\\begin_inset Newpage cleardoublepage',
2347 def revert_pagebreaks(document):
2348 ' Revert \\begin_inset Newpage to previous inline format '
2351 i = find_token(document.body, '\\begin_inset Newpage', i)
2354 j = find_end_of_inset(document.body, i)
2356 document.warning("Malformed LyX document: Could not find end of Newpage inset.")
2358 del document.body[j]
2359 document.body[i] = document.body[i].replace('\\begin_inset Newpage newpage', '\\newpage')
2360 document.body[i] = document.body[i].replace('\\begin_inset Newpage pagebreak', '\\pagebreak')
2361 document.body[i] = document.body[i].replace('\\begin_inset Newpage clearpage', '\\clearpage')
2362 document.body[i] = document.body[i].replace('\\begin_inset Newpage cleardoublepage', '\\cleardoublepage')
2365 def convert_linebreaks(document):
2366 ' Convert inline Newline insets to new format '
2369 i = find_token(document.body, '\\newline', i)
2372 document.body[i:i+1] = ['\\begin_inset Newline newline',
2376 i = find_token(document.body, '\\linebreak', i)
2379 document.body[i:i+1] = ['\\begin_inset Newline linebreak',
2383 def revert_linebreaks(document):
2384 ' Revert \\begin_inset Newline to previous inline format '
2387 i = find_token(document.body, '\\begin_inset Newline', i)
2390 j = find_end_of_inset(document.body, i)
2392 document.warning("Malformed LyX document: Could not find end of Newline inset.")
2394 del document.body[j]
2395 document.body[i] = document.body[i].replace('\\begin_inset Newline newline', '\\newline')
2396 document.body[i] = document.body[i].replace('\\begin_inset Newline linebreak', '\\linebreak')
2399 def convert_japanese_plain(document):
2400 ' Set language japanese-plain to japanese '
2402 if document.language == "japanese-plain":
2403 document.language = "japanese"
2404 i = find_token(document.header, "\\language", 0)
2406 document.header[i] = "\\language japanese"
2409 j = find_token(document.body, "\\lang japanese-plain", j)
2412 document.body[j] = document.body[j].replace("\\lang japanese-plain", "\\lang japanese")
2416 def revert_pdfpages(document):
2417 ' Revert pdfpages external inset to ERT '
2420 i = find_token(document.body, "\\begin_inset External", i)
2423 j = find_end_of_inset(document.body, i)
2425 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_pdfpages.")
2428 if get_value(document.body, 'template', i, j) == "PDFPages":
2429 filename = get_value(document.body, 'filename', i, j)
2431 r = re.compile(r'\textra PDFLaTeX \"(.*)\"$')
2432 for k in range(i, j):
2433 m = r.match(document.body[k])
2436 angle = get_value(document.body, 'rotateAngle', i, j)
2437 width = get_value(document.body, 'width', i, j)
2438 height = get_value(document.body, 'height', i, j)
2439 scale = get_value(document.body, 'scale', i, j)
2440 keepAspectRatio = find_token(document.body, "\tkeepAspectRatio", i, j)
2444 options += ",angle=" + angle
2446 options += "angle=" + angle
2449 options += ",width=" + convert_len(width)
2451 options += "width=" + convert_len(width)
2454 options += ",height=" + convert_len(height)
2456 options += "height=" + convert_len(height)
2459 options += ",scale=" + scale
2461 options += "scale=" + scale
2462 if keepAspectRatio != '':
2464 options += ",keepaspectratio"
2466 options += "keepaspectratio"
2468 options = '[' + options + ']'
2469 del document.body[i+1:j+1]
2470 document.body[i:i+1] = ['\\begin_inset ERT',
2473 '\\begin_layout Standard',
2476 'includepdf' + options + '{' + filename + '}',
2480 add_to_preamble(document, ['\\usepackage{pdfpages}\n'])
2486 def revert_mexican(document):
2487 ' Set language Spanish(Mexico) to Spanish '
2489 if document.language == "spanish-mexico":
2490 document.language = "spanish"
2491 i = find_token(document.header, "\\language", 0)
2493 document.header[i] = "\\language spanish"
2496 j = find_token(document.body, "\\lang spanish-mexico", j)
2499 document.body[j] = document.body[j].replace("\\lang spanish-mexico", "\\lang spanish")
2503 def remove_embedding(document):
2504 ' Remove embed tag from all insets '
2505 revert_inset_embedding(document, 'Graphics')
2506 revert_inset_embedding(document, 'External')
2507 revert_inset_embedding(document, 'CommandInset include')
2508 revert_inset_embedding(document, 'CommandInset bibtex')
2511 def revert_master(document):
2512 ' Remove master param '
2513 i = find_token(document.header, "\\master", 0)
2515 del document.header[i]
2518 def revert_graphics_group(document):
2519 ' Revert group information from graphics insets '
2522 i = find_token(document.body, "\\begin_inset Graphics", i)
2525 j = find_end_of_inset(document.body, i)
2527 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_graphics_group.")
2530 k = find_token(document.body, " groupId", i, j)
2534 del document.body[k]
2538 def update_apa_styles(document):
2539 ' Replace obsolete styles '
2541 if document.textclass != "apa":
2544 obsoletedby = { "Acknowledgments": "Acknowledgements",
2545 "Section*": "Section",
2546 "Subsection*": "Subsection",
2547 "Subsubsection*": "Subsubsection",
2548 "Paragraph*": "Paragraph",
2549 "Subparagraph*": "Subparagraph"}
2552 i = find_token(document.body, "\\begin_layout", i)
2556 layout = document.body[i][14:]
2557 if layout in obsoletedby:
2558 document.body[i] = "\\begin_layout " + obsoletedby[layout]
2563 def convert_paper_sizes(document):
2564 ' exchange size options legalpaper and executivepaper to correct order '
2565 # routine is needed to fix http://bugzilla.lyx.org/show_bug.cgi?id=4868
2568 i = find_token(document.header, "\\papersize executivepaper", 0)
2570 document.header[i] = "\\papersize legalpaper"
2572 j = find_token(document.header, "\\papersize legalpaper", 0)
2574 document.header[j] = "\\papersize executivepaper"
2577 def revert_paper_sizes(document):
2578 ' exchange size options legalpaper and executivepaper to correct order '
2581 i = find_token(document.header, "\\papersize executivepaper", 0)
2583 document.header[i] = "\\papersize legalpaper"
2585 j = find_token(document.header, "\\papersize legalpaper", 0)
2587 document.header[j] = "\\papersize executivepaper"
2590 def convert_InsetSpace(document):
2591 " Convert '\\begin_inset Space foo' to '\\begin_inset space foo'"
2594 i = find_token(document.body, "\\begin_inset Space", i)
2597 document.body[i] = document.body[i].replace('\\begin_inset Space', '\\begin_inset space')
2600 def revert_InsetSpace(document):
2601 " Revert '\\begin_inset space foo' to '\\begin_inset Space foo'"
2604 i = find_token(document.body, "\\begin_inset space", i)
2607 document.body[i] = document.body[i].replace('\\begin_inset space', '\\begin_inset Space')
2610 def convert_display_enum(document):
2611 " Convert 'display foo' to 'display false/true'"
2614 i = find_token(document.body, "\tdisplay", i)
2617 val = get_value(document.body, 'display', i)
2619 document.body[i] = document.body[i].replace('none', 'false')
2620 if val == "default":
2621 document.body[i] = document.body[i].replace('default', 'true')
2622 if val == "monochrome":
2623 document.body[i] = document.body[i].replace('monochrome', 'true')
2624 if val == "grayscale":
2625 document.body[i] = document.body[i].replace('grayscale', 'true')
2627 document.body[i] = document.body[i].replace('color', 'true')
2628 if val == "preview":
2629 document.body[i] = document.body[i].replace('preview', 'true')
2633 def revert_display_enum(document):
2634 " Revert 'display false/true' to 'display none/color'"
2637 i = find_token(document.body, "\tdisplay", i)
2640 val = get_value(document.body, 'display', i)
2642 document.body[i] = document.body[i].replace('false', 'none')
2644 document.body[i] = document.body[i].replace('true', 'default')
2648 def remove_fontsCJK(document):
2649 ' Remove font_cjk param '
2650 i = find_token(document.header, "\\font_cjk", 0)
2652 del document.header[i]
2655 def convert_plain_layout(document):
2656 " Convert 'PlainLayout' to 'Plain Layout'"
2659 i = find_token(document.body, '\\begin_layout PlainLayout', i)
2662 document.body[i] = document.body[i].replace('\\begin_layout PlainLayout', \
2663 '\\begin_layout Plain Layout')
2667 def revert_plain_layout(document):
2668 " Convert 'PlainLayout' to 'Plain Layout'"
2671 i = find_token(document.body, '\\begin_layout Plain Layout', i)
2674 document.body[i] = document.body[i].replace('\\begin_layout Plain Layout', \
2675 '\\begin_layout PlainLayout')
2679 def revert_plainlayout(document):
2680 " Convert 'PlainLayout' to 'Plain Layout'"
2683 i = find_token(document.body, '\\begin_layout PlainLayout', i)
2686 # This will be incorrect for some document classes, since Standard is not always
2687 # the default. But (a) it is probably the best we can do and (b) it will actually
2688 # work, in fact, since an unknown layout will be converted to default.
2689 document.body[i] = document.body[i].replace('\\begin_layout PlainLayout', \
2690 '\\begin_layout Standard')
2694 def revert_polytonicgreek(document):
2695 "Set language polytonic Greek to Greek"
2697 if document.language == "polutonikogreek":
2698 document.language = "greek"
2699 i = find_token(document.header, "\\language", 0)
2701 document.header[i] = "\\language greek"
2704 j = find_token(document.body, "\\lang polutonikogreek", j)
2707 document.body[j] = document.body[j].replace("\\lang polutonikogreek", "\\lang greek")
2715 supported_versions = ["1.6.0","1.6"]
2716 convert = [[277, [fix_wrong_tables]],
2717 [278, [close_begin_deeper]],
2718 [279, [long_charstyle_names]],
2719 [280, [axe_show_label]],
2722 [283, [convert_flex]],
2726 [287, [convert_wrapfig_options]],
2727 [288, [convert_inset_command]],
2728 [289, [convert_latexcommand_index]],
2733 [294, [convert_pdf_options]],
2734 [295, [convert_htmlurl, convert_url]],
2735 [296, [convert_include]],
2736 [297, [convert_usorbian]],
2742 [303, [convert_serbocroatian]],
2743 [304, [convert_framed_notes]],
2750 [311, [convert_ams_classes]],
2752 [313, [convert_module_names]],
2755 [316, [convert_subfig]],
2758 [319, [convert_spaceinset, convert_hfill]],
2760 [321, [convert_tablines]],
2761 [322, [convert_plain_layout]],
2762 [323, [convert_pagebreaks]],
2763 [324, [convert_linebreaks]],
2764 [325, [convert_japanese_plain]],
2767 [328, [remove_embedding, remove_extra_embedded_files, remove_inzip_options]],
2770 [331, [convert_ltcaption]],
2772 [333, [update_apa_styles]],
2773 [334, [convert_paper_sizes]],
2774 [335, [convert_InsetSpace]],
2776 [337, [convert_display_enum]],
2780 revert = [[337, [revert_polytonicgreek]],
2781 [336, [revert_display_enum]],
2782 [335, [remove_fontsCJK]],
2783 [334, [revert_InsetSpace]],
2784 [333, [revert_paper_sizes]],
2786 [331, [revert_graphics_group]],
2787 [330, [revert_ltcaption]],
2788 [329, [revert_leftarrowfill, revert_rightarrowfill, revert_upbracefill, revert_downbracefill]],
2789 [328, [revert_master]],
2791 [326, [revert_mexican]],
2792 [325, [revert_pdfpages]],
2794 [323, [revert_linebreaks]],
2795 [322, [revert_pagebreaks]],
2796 [321, [revert_local_layout, revert_plain_layout]],
2797 [320, [revert_tablines]],
2798 [319, [revert_protected_hfill]],
2799 [318, [revert_spaceinset, revert_hfills, revert_hspace]],
2800 [317, [remove_extra_embedded_files]],
2801 [316, [revert_wrapplacement]],
2802 [315, [revert_subfig]],
2803 [314, [revert_colsep, revert_plainlayout]],
2805 [312, [revert_module_names]],
2806 [311, [revert_rotfloat, revert_widesideways]],
2807 [310, [revert_external_embedding]],
2808 [309, [revert_btprintall]],
2809 [308, [revert_nocite]],
2810 [307, [revert_serbianlatin]],
2811 [306, [revert_slash, revert_nobreakdash]],
2812 [305, [revert_interlingua]],
2813 [304, [revert_bahasam]],
2814 [303, [revert_framed_notes]],
2816 [301, [revert_latin, revert_samin]],
2817 [300, [revert_linebreak]],
2818 [299, [revert_pagebreak]],
2819 [298, [revert_hyperlinktype]],
2820 [297, [revert_macro_optional_params]],
2821 [296, [revert_albanian, revert_lowersorbian, revert_uppersorbian]],
2822 [295, [revert_include]],
2823 [294, [revert_href, revert_url]],
2824 [293, [revert_pdf_options_2]],
2825 [292, [revert_inset_info]],
2826 [291, [revert_japanese, revert_japanese_encoding]],
2827 [290, [revert_vietnamese]],
2828 [289, [revert_wraptable]],
2829 [288, [revert_latexcommand_index]],
2830 [287, [revert_inset_command]],
2831 [286, [revert_wrapfig_options]],
2832 [285, [revert_pdf_options]],
2833 [284, [remove_inzip_options]],
2835 [282, [revert_flex]],
2837 [280, [revert_begin_modules]],
2838 [279, [revert_show_label]],
2839 [278, [revert_long_charstyle_names]],
2845 if __name__ == "__main__":