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 '''Converts LaTeX commands, such as: \"u, to unicode characters, and
152 escapes backslashes, etc, into ERT. line may well be a multi-line
153 string when it is returned.
154 NOTE: If we want to convert \label{} into an InsetLabel, then this
155 is the place to do it.'''
158 line = wrap_into_ert(line, '\\', '\\backslash')
159 line = wrap_into_ert(line, '{', '{')
160 line = wrap_into_ert(line, '}', '}')
165 '''Takes a string, possibly multi-line, and returns the result of
166 converting LaTeX constructs into LyX constructs. Returns a list of
167 lines, suitable for insertion into document.body.'''
169 mathre = re.compile('^(.*?)(\$.*?\$)(.*)')
172 # Convert LaTeX to Unicode
173 reps = read_unicodesymbols()
176 data = data.replace(rep[0], rep[1])
178 # There seems to be a character in the unicodesymbols file
179 # that causes problems, namely, 0x2109.
182 data = wrap_into_ert(data, r'\"', '"')
184 lines = data.split('\n')
186 #document.warning("LINE: " + line)
187 #document.warning(str(i) + ":" + document.body[i])
188 #document.warning("LAST: " + document.body[-1])
193 f = m.group(2).replace('\\\\', '\\')
198 subst = s.split('\n')
200 retval.append("\\begin_inset Formula " + f)
201 retval.append("\\end_inset")
203 # Handle whatever is left, which is just text
205 subst = g.split('\n')
210 ####################################################################
212 def convert_ltcaption(document):
215 i = find_token(document.body, "\\begin_inset Tabular", i)
218 j = find_end_of_inset(document.body, i + 1)
220 document.warning("Malformed LyX document: Could not find end of tabular.")
223 nrows = int(document.body[i+1].split('"')[3])
224 ncols = int(document.body[i+1].split('"')[5])
227 for k in range(nrows):
228 m = find_token(document.body, "<row", m)
231 for k in range(ncols):
232 m = find_token(document.body, "<cell", m)
234 mend = find_token(document.body, "</cell>", m + 1)
235 # first look for caption insets
236 mcap = find_token(document.body, "\\begin_inset Caption", m + 1, mend)
237 # then look for ERT captions
239 mcap = find_token(document.body, "caption", m + 1, mend)
241 mcap = find_token(document.body, "\\backslash", mcap - 1, mcap)
244 if caption == 'true':
246 set_option(document, r, 'caption', 'true')
247 set_option(document, m, 'multicolumn', '1')
248 set_option(document, m, 'bottomline', 'false')
249 set_option(document, m, 'topline', 'false')
250 set_option(document, m, 'rightline', 'false')
251 set_option(document, m, 'leftline', 'false')
252 #j = find_end_of_inset(document.body, j + 1)
254 set_option(document, m, 'multicolumn', '2')
261 #FIXME Use of wrap_into_ert can confuse lyx2lyx
262 def revert_ltcaption(document):
265 i = find_token(document.body, "\\begin_inset Tabular", i)
268 j = find_end_of_inset(document.body, i + 1)
270 document.warning("Malformed LyX document: Could not find end of tabular.")
274 nrows = int(document.body[i+1].split('"')[3])
275 ncols = int(document.body[i+1].split('"')[5])
277 for k in range(nrows):
278 m = find_token(document.body, "<row", m)
279 caption = get_option(document, m, 'caption', 'false')
280 if caption == 'true':
281 remove_option(document, m, 'caption')
282 for k in range(ncols):
283 m = find_token(document.body, "<cell", m)
284 remove_option(document, m, 'multicolumn')
286 m = find_token(document.body, "\\begin_inset Caption", m)
289 m = find_end_of_inset(document.body, m + 1)
290 document.body[m] += wrap_into_ert("","","\\backslash\n\\backslash\n%")
296 def convert_tablines(document):
299 i = find_token(document.body, "\\begin_inset Tabular", i)
301 # LyX 1.3 inserted an extra space between \begin_inset
302 # and Tabular so let us try if this is the case and fix it.
303 i = find_token(document.body, "\\begin_inset Tabular", i)
307 document.body[i] = "\\begin_inset Tabular"
308 j = find_end_of_inset(document.body, i + 1)
310 document.warning("Malformed LyX document: Could not find end of tabular.")
314 nrows = int(document.body[i+1].split('"')[3])
315 ncols = int(document.body[i+1].split('"')[5])
318 for k in range(ncols):
319 m = find_token(document.body, "<column", m)
320 left = get_option(document, m, 'leftline', 'false')
321 right = get_option(document, m, 'rightline', 'false')
322 col_info.append([left, right])
323 remove_option(document, m, 'leftline')
324 remove_option(document, m, 'rightline')
328 for k in range(nrows):
329 m = find_token(document.body, "<row", m)
330 top = get_option(document, m, 'topline', 'false')
331 bottom = get_option(document, m, 'bottomline', 'false')
332 row_info.append([top, bottom])
333 remove_option(document, m, 'topline')
334 remove_option(document, m, 'bottomline')
339 for k in range(nrows*ncols):
340 m = find_token(document.body, "<cell", m)
341 mc_info.append(get_option(document, m, 'multicolumn', '0'))
344 for l in range(nrows):
345 for k in range(ncols):
346 m = find_token(document.body, '<cell', m)
347 if mc_info[l*ncols + k] == '0':
348 r = set_option(document, m, 'topline', row_info[l][0])
349 r = set_option(document, m, 'bottomline', row_info[l][1])
350 r = set_option(document, m, 'leftline', col_info[k][0])
351 r = set_option(document, m, 'rightline', col_info[k][1])
352 elif mc_info[l*ncols + k] == '1':
354 while s < ncols and mc_info[l*ncols + s] == '2':
356 if s < ncols and mc_info[l*ncols + s] != '1':
357 r = set_option(document, m, 'rightline', col_info[k][1])
358 if k > 0 and mc_info[l*ncols + k - 1] == '0':
359 r = set_option(document, m, 'leftline', col_info[k][0])
364 def revert_tablines(document):
367 i = find_token(document.body, "\\begin_inset Tabular", i)
370 j = find_end_of_inset(document.body, i + 1)
372 document.warning("Malformed LyX document: Could not find end of tabular.")
376 nrows = int(document.body[i+1].split('"')[3])
377 ncols = int(document.body[i+1].split('"')[5])
380 for k in range(nrows*ncols):
381 m = find_token(document.body, "<cell", m)
382 top = get_option(document, m, 'topline', 'false')
383 bottom = get_option(document, m, 'bottomline', 'false')
384 left = get_option(document, m, 'leftline', 'false')
385 right = get_option(document, m, 'rightline', 'false')
386 lines.append([top, bottom, left, right])
389 # we will want to ignore longtable captions
392 for k in range(nrows):
393 m = find_token(document.body, "<row", m)
394 caption = get_option(document, m, 'caption', 'false')
395 caption_info.append([caption])
400 for k in range(ncols):
401 m = find_token(document.body, "<column", m)
403 for l in range(nrows):
404 left = lines[l*ncols + k][2]
405 if left == 'false' and caption_info[l] == 'false':
407 set_option(document, m, 'leftline', left)
409 for l in range(nrows):
410 right = lines[l*ncols + k][3]
411 if right == 'false' and caption_info[l] == 'false':
413 set_option(document, m, 'rightline', right)
417 for k in range(nrows):
418 m = find_token(document.body, "<row", m)
420 for l in range(ncols):
421 top = lines[k*ncols + l][0]
424 if caption_info[k] == 'false':
426 set_option(document, m, 'topline', top)
428 for l in range(ncols):
429 bottom = lines[k*ncols + l][1]
430 if bottom == 'false':
432 if caption_info[k] == 'false':
434 set_option(document, m, 'bottomline', bottom)
440 def fix_wrong_tables(document):
443 i = find_token(document.body, "\\begin_inset Tabular", i)
446 j = find_end_of_inset(document.body, i + 1)
448 document.warning("Malformed LyX document: Could not find end of tabular.")
452 nrows = int(document.body[i+1].split('"')[3])
453 ncols = int(document.body[i+1].split('"')[5])
455 for l in range(nrows):
457 for k in range(ncols):
458 m = find_token(document.body, '<cell', m)
460 if document.body[m].find('multicolumn') != -1:
461 multicol_cont = int(document.body[m].split('"')[1])
463 if multicol_cont == 2 and (k == 0 or prev_multicolumn == 0):
464 document.body[m] = document.body[m][:5] + document.body[m][21:]
467 prev_multicolumn = multicol_cont
474 def close_begin_deeper(document):
478 i = find_tokens(document.body, ["\\begin_deeper", "\\end_deeper"], i)
483 if document.body[i][:13] == "\\begin_deeper":
490 document.body[-2:-2] = ['\\end_deeper' for i in range(depth)]
493 def long_charstyle_names(document):
496 i = find_token(document.body, "\\begin_inset CharStyle", i)
499 document.body[i] = document.body[i].replace("CharStyle ", "CharStyle CharStyle:")
502 def revert_long_charstyle_names(document):
505 i = find_token(document.body, "\\begin_inset CharStyle", i)
508 document.body[i] = document.body[i].replace("CharStyle CharStyle:", "CharStyle")
512 def axe_show_label(document):
515 i = find_token(document.body, "\\begin_inset CharStyle", i)
518 if document.body[i + 1].find("show_label") != -1:
519 if document.body[i + 1].find("true") != -1:
520 document.body[i + 1] = "status open"
521 del document.body[ i + 2]
523 if document.body[i + 1].find("false") != -1:
524 document.body[i + 1] = "status collapsed"
525 del document.body[ i + 2]
527 document.warning("Malformed LyX document: show_label neither false nor true.")
529 document.warning("Malformed LyX document: show_label missing in CharStyle.")
534 def revert_show_label(document):
537 i = find_token(document.body, "\\begin_inset CharStyle", i)
540 if document.body[i + 1].find("status open") != -1:
541 document.body.insert(i + 1, "show_label true")
543 if document.body[i + 1].find("status collapsed") != -1:
544 document.body.insert(i + 1, "show_label false")
546 document.warning("Malformed LyX document: no legal status line in CharStyle.")
549 def revert_begin_modules(document):
552 i = find_token(document.header, "\\begin_modules", i)
555 j = find_end_of(document.header, i, "\\begin_modules", "\\end_modules")
557 # this should not happen
559 document.header[i : j + 1] = []
561 def convert_flex(document):
562 "Convert CharStyle to Flex"
565 i = find_token(document.body, "\\begin_inset CharStyle", i)
568 document.body[i] = document.body[i].replace('\\begin_inset CharStyle', '\\begin_inset Flex')
570 def revert_flex(document):
571 "Convert Flex to CharStyle"
574 i = find_token(document.body, "\\begin_inset Flex", i)
577 document.body[i] = document.body[i].replace('\\begin_inset Flex', '\\begin_inset CharStyle')
580 # Discard PDF options for hyperref
581 def revert_pdf_options(document):
582 "Revert PDF options for hyperref."
583 # store the PDF options and delete the entries from the Lyx file
591 bookmarksnumbered = ""
593 bookmarksopenlevel = ""
601 i = find_token(document.header, "\\use_hyperref", i)
603 hyperref = get_value(document.header, "\\use_hyperref", i) == 'true'
604 del document.header[i]
605 i = find_token(document.header, "\\pdf_store_options", i)
607 del document.header[i]
608 i = find_token(document.header, "\\pdf_title", 0)
610 title = get_value_string(document.header, '\\pdf_title', 0, 0, True)
611 title = ' pdftitle={' + title + '}'
612 del document.header[i]
613 i = find_token(document.header, "\\pdf_author", 0)
615 author = get_value_string(document.header, '\\pdf_author', 0, 0, True)
617 author = ' pdfauthor={' + author + '}'
619 author = ',\n pdfauthor={' + author + '}'
620 del document.header[i]
621 i = find_token(document.header, "\\pdf_subject", 0)
623 subject = get_value_string(document.header, '\\pdf_subject', 0, 0, True)
624 if title == "" and author == "":
625 subject = ' pdfsubject={' + subject + '}'
627 subject = ',\n pdfsubject={' + subject + '}'
628 del document.header[i]
629 i = find_token(document.header, "\\pdf_keywords", 0)
631 keywords = get_value_string(document.header, '\\pdf_keywords', 0, 0, True)
632 if title == "" and author == "" and subject == "":
633 keywords = ' pdfkeywords={' + keywords + '}'
635 keywords = ',\n pdfkeywords={' + keywords + '}'
636 del document.header[i]
637 i = find_token(document.header, "\\pdf_bookmarks", 0)
639 bookmarks = get_value_string(document.header, '\\pdf_bookmarks', 0)
640 bookmarks = ',\n bookmarks=' + bookmarks
641 del document.header[i]
642 i = find_token(document.header, "\\pdf_bookmarksnumbered", i)
644 bookmarksnumbered = get_value_string(document.header, '\\pdf_bookmarksnumbered', 0)
645 bookmarksnumbered = ',\n bookmarksnumbered=' + bookmarksnumbered
646 del document.header[i]
647 i = find_token(document.header, "\\pdf_bookmarksopen", i)
649 bookmarksopen = get_value_string(document.header, '\\pdf_bookmarksopen', 0)
650 bookmarksopen = ',\n bookmarksopen=' + bookmarksopen
651 del document.header[i]
652 i = find_token(document.header, "\\pdf_bookmarksopenlevel", i)
654 bookmarksopenlevel = get_value_string(document.header, '\\pdf_bookmarksopenlevel', 0, 0, True)
655 bookmarksopenlevel = ',\n bookmarksopenlevel=' + bookmarksopenlevel
656 del document.header[i]
657 i = find_token(document.header, "\\pdf_breaklinks", i)
659 breaklinks = get_value_string(document.header, '\\pdf_breaklinks', 0)
660 breaklinks = ',\n breaklinks=' + breaklinks
661 del document.header[i]
662 i = find_token(document.header, "\\pdf_pdfborder", i)
664 pdfborder = get_value_string(document.header, '\\pdf_pdfborder', 0)
665 if pdfborder == 'true':
666 pdfborder = ',\n pdfborder={0 0 0}'
668 pdfborder = ',\n pdfborder={0 0 1}'
669 del document.header[i]
670 i = find_token(document.header, "\\pdf_colorlinks", i)
672 colorlinks = get_value_string(document.header, '\\pdf_colorlinks', 0)
673 colorlinks = ',\n colorlinks=' + colorlinks
674 del document.header[i]
675 i = find_token(document.header, "\\pdf_backref", i)
677 backref = get_value_string(document.header, '\\pdf_backref', 0)
678 backref = ',\n backref=' + backref
679 del document.header[i]
680 i = find_token(document.header, "\\pdf_pagebackref", i)
682 pagebackref = get_value_string(document.header, '\\pdf_pagebackref', 0)
683 pagebackref = ',\n pagebackref=' + pagebackref
684 del document.header[i]
685 i = find_token(document.header, "\\pdf_pagemode", 0)
687 pagemode = get_value_string(document.header, '\\pdf_pagemode', 0)
688 pagemode = ',\n pdfpagemode=' + pagemode
689 del document.header[i]
690 i = find_token(document.header, "\\pdf_quoted_options", 0)
692 otheroptions = get_value_string(document.header, '\\pdf_quoted_options', 0, 0, True)
693 if title == "" and author == "" and subject == "" and keywords == "":
694 otheroptions = ' ' + otheroptions
696 otheroptions = ',\n ' + otheroptions
697 del document.header[i]
699 # write to the preamble when hyperref was used
701 # preamble write preparations
702 # bookmark numbers are only output when they are turned on
703 if bookmarksopen == ',\n bookmarksopen=true':
704 bookmarksopen = bookmarksopen + bookmarksopenlevel
705 if bookmarks == ',\n bookmarks=true':
706 bookmarks = bookmarks + bookmarksnumbered + bookmarksopen
708 bookmarks = bookmarks
709 # hypersetup is only output when there are things to be set up
710 setupstart = '\\hypersetup{%\n'
712 if otheroptions == "" and title == "" and author == ""\
713 and subject == "" and keywords == "":
717 add_to_preamble(document,
718 ['% Commands inserted by lyx2lyx for PDF properties',
719 '\\usepackage[unicode=true'
738 def remove_inzip_options(document):
739 "Remove inzipName and embed options from the Graphics inset"
742 i = find_token(document.body, "\\begin_inset Graphics", i)
745 j = find_end_of_inset(document.body, i + 1)
748 document.warning("Malformed LyX document: Could not find end of graphics inset.")
749 # If there's a inzip param, just remove that
750 k = find_token(document.body, "\tinzipName", i + 1, j)
753 # embed option must follow the inzipName option
754 del document.body[k+1]
758 def convert_inset_command(document):
761 \begin_inset LatexCommand cmd
763 \begin_inset CommandInset InsetType
768 i = find_token(document.body, "\\begin_inset LatexCommand", i)
771 line = document.body[i]
772 r = re.compile(r'\\begin_inset LatexCommand (.*)$')
776 #this is adapted from factory.cpp
777 if cmdName[0:4].lower() == "cite":
778 insetName = "citation"
779 elif cmdName == "url" or cmdName == "htmlurl":
781 elif cmdName[-3:] == "ref":
783 elif cmdName == "tableofcontents":
785 elif cmdName == "printnomenclature":
786 insetName = "nomencl_print"
787 elif cmdName == "printindex":
788 insetName = "index_print"
791 insertion = ["\\begin_inset CommandInset " + insetName, "LatexCommand " + cmdName]
792 document.body[i : i+1] = insertion
795 def revert_inset_command(document):
798 \begin_inset CommandInset InsetType
801 \begin_inset LatexCommand cmd
802 Some insets may end up being converted to insets earlier versions of LyX
803 will not be able to recognize. Not sure what to do about that.
807 i = find_token(document.body, "\\begin_inset CommandInset", i)
810 nextline = document.body[i+1]
811 r = re.compile(r'LatexCommand\s+(.*)$')
812 m = r.match(nextline)
814 document.warning("Malformed LyX document: Missing LatexCommand in " + document.body[i] + ".")
817 insertion = ["\\begin_inset LatexCommand " + cmdName]
818 document.body[i : i+2] = insertion
821 def convert_wrapfig_options(document):
822 "Convert optional options for wrap floats (wrapfig)."
823 # adds the tokens "lines", "placement", and "overhang"
826 i = find_token(document.body, "\\begin_inset Wrap figure", i)
829 document.body.insert(i + 1, "lines 0")
830 j = find_token(document.body, "placement", i)
831 # placement can be already set or not; if not, set it
833 document.body.insert(i + 3, "overhang 0col%")
835 document.body.insert(i + 2, "placement o")
836 document.body.insert(i + 3, "overhang 0col%")
840 def revert_wrapfig_options(document):
841 "Revert optional options for wrap floats (wrapfig)."
844 i = find_token(document.body, "\\begin_inset Wrap figure", i)
847 j = find_end_of_inset(document.body, i)
849 document.warning("Can't find end of Wrap inset at line " + str(i))
852 k = find_default_layout(document, i, j)
854 document.warning("Can't find default layout for Wrap figure!")
857 # Options should be between i and k now
858 l = find_token(document.body, "lines", i, k)
860 document.warning("Can't find lines option for Wrap figure!")
863 m = find_token(document.body, "overhang", i + 1, k)
865 document.warning("Malformed LyX document: Couldn't find overhang parameter of wrap float!")
868 # Do these in reverse order
874 def convert_latexcommand_index(document):
875 "Convert from LatexCommand form to collapsable form."
877 r1 = re.compile('name "(.*)"')
879 i = find_token(document.body, "\\begin_inset CommandInset index", i)
882 if document.body[i + 1] != "LatexCommand index": # Might also be index_print
884 m = r1.match(document.body[i + 2])
886 document.warning("Unable to match: " + document.body[i+2])
889 fullcontent = m.group(1)
890 #document.warning(fullcontent)
891 document.body[i:i + 3] = ["\\begin_inset Index",
893 "\\begin_layout Standard"]
895 # We are now on the blank line preceding "\end_inset"
896 # We will write the content here, into the inset.
898 linelist = latex2lyx(fullcontent)
899 document.body[i+1:i+1] = linelist
902 document.body.insert(i + 1, "\\end_layout")
906 def revert_latexcommand_index(document):
907 "Revert from collapsable form to LatexCommand form."
910 i = find_token(document.body, "\\begin_inset Index", i)
913 j = find_end_of_inset(document.body, i + 1)
916 del document.body[j - 1]
917 del document.body[j - 2] # \end_layout
918 document.body[i] = "\\begin_inset CommandInset index"
919 document.body[i + 1] = "LatexCommand index"
920 # clean up multiline stuff
923 for k in range(i + 3, j - 2):
924 line = document.body[k]
925 if line.startswith("\\begin_inset ERT"):
926 ert_end = find_end_of_inset(document.body, k + 1)
928 if line.startswith("\\begin_inset Formula"):
930 if line.startswith("\\begin_layout Standard"):
932 if line.startswith("\\begin_layout Plain Layout"):
934 if line.startswith("\\end_layout"):
936 if line.startswith("\\end_inset"):
938 if line.startswith("status collapsed"):
940 if line.startswith("status open"):
942 # a lossless reversion is not possible
943 # try at least to handle some common insets and settings
944 # do not replace inside ERTs
946 # Do the LyX text --> LaTeX conversion
947 for rep in replacements:
948 line = line.replace(rep[1], rep[0])
949 line = line.replace(r'\backslash', r'\textbackslash{}')
950 line = line.replace(r'\series bold', r'\bfseries{}').replace(r'\series default', r'\mdseries{}')
951 line = line.replace(r'\shape italic', r'\itshape{}').replace(r'\shape smallcaps', r'\scshape{}')
952 line = line.replace(r'\shape slanted', r'\slshape{}').replace(r'\shape default', r'\upshape{}')
953 line = line.replace(r'\emph on', r'\em{}').replace(r'\emph default', r'\em{}')
954 line = line.replace(r'\noun on', r'\scshape{}').replace(r'\noun default', r'\upshape{}')
955 line = line.replace(r'\bar under', r'\underbar{').replace(r'\bar default', r'}')
956 line = line.replace(r'\family sans', r'\sffamily{}').replace(r'\family default', r'\normalfont{}')
957 line = line.replace(r'\family typewriter', r'\ttfamily{}').replace(r'\family roman', r'\rmfamily{}')
958 line = line.replace(r'\InsetSpace ', r'').replace(r'\SpecialChar ', r'')
960 line = line.replace(r'\backslash', r'\\')
961 content = content + line;
962 document.body[i + 3] = "name " + '"' + content + '"'
963 for k in range(i + 4, j - 2):
964 del document.body[i + 4]
965 document.body.insert(i + 4, "")
966 del document.body[i + 2] # \begin_layout standard
970 def revert_wraptable(document):
971 "Revert wrap table to wrap figure."
974 i = find_token(document.body, "\\begin_inset Wrap table", i)
977 document.body[i] = document.body[i].replace('\\begin_inset Wrap table', '\\begin_inset Wrap figure')
981 def revert_vietnamese(document):
982 "Set language Vietnamese to English"
983 # Set document language from Vietnamese to English
985 if document.language == "vietnamese":
986 document.language = "english"
987 i = find_token(document.header, "\\language", 0)
989 document.header[i] = "\\language english"
992 j = find_token(document.body, "\\lang vietnamese", j)
995 document.body[j] = document.body[j].replace("\\lang vietnamese", "\\lang english")
999 def revert_japanese(document):
1000 "Set language japanese-plain to japanese"
1001 # Set document language from japanese-plain to japanese
1003 if document.language == "japanese-plain":
1004 document.language = "japanese"
1005 i = find_token(document.header, "\\language", 0)
1007 document.header[i] = "\\language japanese"
1010 j = find_token(document.body, "\\lang japanese-plain", j)
1013 document.body[j] = document.body[j].replace("\\lang japanese-plain", "\\lang japanese")
1017 def revert_japanese_encoding(document):
1018 "Set input encoding form EUC-JP-plain to EUC-JP etc."
1019 # Set input encoding form EUC-JP-plain to EUC-JP etc.
1021 i = find_token(document.header, "\\inputencoding EUC-JP-plain", 0)
1023 document.header[i] = "\\inputencoding EUC-JP"
1025 j = find_token(document.header, "\\inputencoding JIS-plain", 0)
1027 document.header[j] = "\\inputencoding JIS"
1029 k = find_token(document.header, "\\inputencoding SJIS-plain", 0)
1030 if k != -1: # convert to UTF8 since there is currently no SJIS encoding
1031 document.header[k] = "\\inputencoding UTF8"
1034 def revert_inset_info(document):
1035 'Replace info inset with its content'
1038 i = find_token(document.body, '\\begin_inset Info', i)
1041 j = find_end_of_inset(document.body, i + 1)
1044 document.warning("Malformed LyX document: Could not find end of Info inset.")
1047 for k in range(i, j+1):
1048 if document.body[k].startswith("arg"):
1049 arg = document.body[k][3:].strip().strip('"')
1050 if document.body[k].startswith("type"):
1051 type = document.body[k][4:].strip().strip('"')
1052 # I think there is a newline after \\end_inset, which should be removed.
1053 if document.body[j + 1].strip() == "":
1054 document.body[i : (j + 2)] = [type + ':' + arg]
1056 document.body[i : (j + 1)] = [type + ':' + arg]
1059 def convert_pdf_options(document):
1060 # Set the pdfusetitle tag, delete the pdf_store_options,
1061 # set quotes for bookmarksopenlevel"
1062 has_hr = get_value(document.header, "\\use_hyperref", 0, default = "0")
1064 k = find_token(document.header, "\\use_hyperref", 0)
1065 document.header.insert(k + 1, "\\pdf_pdfusetitle true")
1066 k = find_token(document.header, "\\pdf_store_options", 0)
1068 del document.header[k]
1069 i = find_token(document.header, "\\pdf_bookmarksopenlevel", k)
1071 document.header[i] = document.header[i].replace('"', '')
1074 def revert_pdf_options_2(document):
1075 # reset the pdfusetitle tag, set quotes for bookmarksopenlevel"
1076 k = find_token(document.header, "\\use_hyperref", 0)
1077 i = find_token(document.header, "\\pdf_pdfusetitle", k)
1079 del document.header[i]
1080 i = find_token(document.header, "\\pdf_bookmarksopenlevel", k)
1082 values = document.header[i].split()
1083 values[1] = ' "' + values[1] + '"'
1084 document.header[i] = ''.join(values)
1087 def convert_htmlurl(document):
1088 'Convert "htmlurl" to "href" insets for docbook'
1089 if document.backend != "docbook":
1093 i = find_token(document.body, "\\begin_inset CommandInset url", i)
1096 document.body[i] = "\\begin_inset CommandInset href"
1097 document.body[i + 1] = "LatexCommand href"
1101 def convert_url(document):
1102 'Convert url insets to url charstyles'
1103 if document.backend == "docbook":
1107 i = find_token(document.body, "\\begin_inset CommandInset url", i)
1110 n = find_token(document.body, "name", i)
1112 # place the URL name in typewriter before the new URL insert
1113 # grab the name 'bla' from the e.g. the line 'name "bla"',
1114 # therefore start with the 6th character
1115 name = document.body[n][6:-1]
1116 newname = [name + " "]
1117 document.body[i:i] = newname
1119 j = find_token(document.body, "target", i)
1121 document.warning("Malformed LyX document: Can't find target for url inset")
1124 target = document.body[j][8:-1]
1125 k = find_token(document.body, "\\end_inset", j)
1127 document.warning("Malformed LyX document: Can't find end of url inset")
1130 newstuff = ["\\begin_inset Flex URL",
1131 "status collapsed", "",
1132 "\\begin_layout Standard",
1137 document.body[i:k] = newstuff
1140 def convert_ams_classes(document):
1141 tc = document.textclass
1142 if (tc != "amsart" and tc != "amsart-plain" and
1143 tc != "amsart-seq" and tc != "amsbook"):
1145 if tc == "amsart-plain":
1146 document.textclass = "amsart"
1147 document.set_textclass()
1148 document.add_module("Theorems (Starred)")
1150 if tc == "amsart-seq":
1151 document.textclass = "amsart"
1152 document.set_textclass()
1153 document.add_module("Theorems (AMS)")
1155 #Now we want to see if any of the environments in the extended theorems
1156 #module were used in this document. If so, we'll add that module, too.
1157 layouts = ["Criterion", "Algorithm", "Axiom", "Condition", "Note", \
1158 "Notation", "Summary", "Acknowledgement", "Conclusion", "Fact", \
1161 r = re.compile(r'^\\begin_layout (.*?)\*?\s*$')
1164 i = find_token(document.body, "\\begin_layout", i)
1167 m = r.match(document.body[i])
1169 document.warning("Weirdly formed \\begin_layout at line %d of body!" % i)
1173 if layouts.count(m) != 0:
1174 document.add_module("Theorems (AMS-Extended)")
1178 def revert_href(document):
1179 'Reverts hyperlink insets (href) to url insets (url)'
1182 i = find_token(document.body, "\\begin_inset CommandInset href", i)
1185 document.body[i : i + 2] = \
1186 ["\\begin_inset CommandInset url", "LatexCommand url"]
1189 def revert_url(document):
1190 'Reverts Flex URL insets to old-style URL insets'
1193 i = find_token(document.body, "\\begin_inset Flex URL", i)
1196 j = find_end_of_inset(document.body, i)
1198 document.warning("Can't find end of inset in revert_url!")
1200 k = find_default_layout(document, i, j)
1202 document.warning("Can't find default layout in revert_url!")
1205 l = find_end_of(document.body, k, "\\begin_layout", "\\end_layout")
1206 if l == -1 or l >= j:
1207 document.warning("Can't find end of default layout in revert_url!")
1210 # OK, so the inset's data is between lines k and l.
1211 data = " ".join(document.body[k+1:l])
1213 newinset = ["\\begin_inset LatexCommand url", "target \"" + data + "\"",\
1215 document.body[i:j+1] = newinset
1216 i = i + len(newinset)
1219 def convert_include(document):
1220 'Converts include insets to new format.'
1222 r = re.compile(r'\\begin_inset Include\s+\\([^{]+){([^}]*)}(?:\[(.*)\])?')
1224 i = find_token(document.body, "\\begin_inset Include", i)
1227 line = document.body[i]
1228 previewline = document.body[i + 1]
1231 document.warning("Unable to match line " + str(i) + " of body!")
1237 insertion = ["\\begin_inset CommandInset include",
1238 "LatexCommand " + cmd, previewline,
1239 "filename \"" + fn + "\""]
1242 insertion.append("lstparams " + '"' + opt + '"')
1244 document.body[i : i + 2] = insertion
1248 def revert_include(document):
1249 'Reverts include insets to old format.'
1251 r0 = re.compile('preview.*')
1252 r1 = re.compile('LatexCommand (.+)')
1253 r2 = re.compile('filename "(.+)"')
1254 r3 = re.compile('lstparams "(.*)"')
1256 i = find_token(document.body, "\\begin_inset CommandInset include", i)
1260 if r0.match(document.body[nextline]):
1261 previewline = document.body[nextline]
1265 m = r1.match(document.body[nextline])
1267 document.warning("Malformed LyX document: No LatexCommand line for `" +
1268 document.body[i] + "' on line " + str(i) + ".")
1273 m = r2.match(document.body[nextline])
1275 document.warning("Malformed LyX document: No filename line for `" + \
1276 document.body[i] + "' on line " + str(i) + ".")
1282 if (cmd == "lstinputlisting"):
1283 m = r3.match(document.body[nextline])
1285 options = m.group(1)
1288 newline = "\\begin_inset Include \\" + cmd + "{" + fn + "}"
1290 newline += ("[" + options + "]")
1291 insertion = [newline]
1292 if previewline != "":
1293 insertion.append(previewline)
1294 document.body[i : nextline] = insertion
1298 def revert_albanian(document):
1299 "Set language Albanian to English"
1301 if document.language == "albanian":
1302 document.language = "english"
1303 i = find_token(document.header, "\\language", 0)
1305 document.header[i] = "\\language english"
1308 j = find_token(document.body, "\\lang albanian", j)
1311 document.body[j] = document.body[j].replace("\\lang albanian", "\\lang english")
1315 def revert_lowersorbian(document):
1316 "Set language lower Sorbian to English"
1318 if document.language == "lowersorbian":
1319 document.language = "english"
1320 i = find_token(document.header, "\\language", 0)
1322 document.header[i] = "\\language english"
1325 j = find_token(document.body, "\\lang lowersorbian", j)
1328 document.body[j] = document.body[j].replace("\\lang lowersorbian", "\\lang english")
1332 def revert_uppersorbian(document):
1333 "Set language uppersorbian to usorbian as this was used in LyX 1.5"
1335 if document.language == "uppersorbian":
1336 document.language = "usorbian"
1337 i = find_token(document.header, "\\language", 0)
1339 document.header[i] = "\\language usorbian"
1342 j = find_token(document.body, "\\lang uppersorbian", j)
1345 document.body[j] = document.body[j].replace("\\lang uppersorbian", "\\lang usorbian")
1349 def convert_usorbian(document):
1350 "Set language usorbian to uppersorbian"
1352 if document.language == "usorbian":
1353 document.language = "uppersorbian"
1354 i = find_token(document.header, "\\language", 0)
1356 document.header[i] = "\\language uppersorbian"
1359 j = find_token(document.body, "\\lang usorbian", j)
1362 document.body[j] = document.body[j].replace("\\lang usorbian", "\\lang uppersorbian")
1366 def revert_macro_optional_params(document):
1367 "Convert macro definitions with optional parameters into ERTs"
1368 # Stub to convert macro definitions with one or more optional parameters
1369 # into uninterpreted ERT insets
1372 def revert_hyperlinktype(document):
1373 'Reverts hyperlink type'
1377 i = find_token(document.body, "target", i)
1380 j = find_token(document.body, "type", i)
1384 del document.body[j]
1388 def revert_pagebreak(document):
1389 'Reverts pagebreak to ERT'
1392 i = find_token(document.body, "\\pagebreak", i)
1395 document.body[i] = '\\begin_inset ERT\nstatus collapsed\n\n' \
1396 '\\begin_layout Standard\n\n\n\\backslash\n' \
1397 'pagebreak{}\n\\end_layout\n\n\\end_inset\n\n'
1401 def revert_linebreak(document):
1402 'Reverts linebreak to ERT'
1405 i = find_token(document.body, "\\linebreak", i)
1408 document.body[i] = '\\begin_inset ERT\nstatus collapsed\n\n' \
1409 '\\begin_layout Standard\n\n\n\\backslash\n' \
1410 'linebreak{}\n\\end_layout\n\n\\end_inset\n\n'
1414 def revert_latin(document):
1415 "Set language Latin to English"
1417 if document.language == "latin":
1418 document.language = "english"
1419 i = find_token(document.header, "\\language", 0)
1421 document.header[i] = "\\language english"
1424 j = find_token(document.body, "\\lang latin", j)
1427 document.body[j] = document.body[j].replace("\\lang latin", "\\lang english")
1431 def revert_samin(document):
1432 "Set language North Sami to English"
1434 if document.language == "samin":
1435 document.language = "english"
1436 i = find_token(document.header, "\\language", 0)
1438 document.header[i] = "\\language english"
1441 j = find_token(document.body, "\\lang samin", j)
1444 document.body[j] = document.body[j].replace("\\lang samin", "\\lang english")
1448 def convert_serbocroatian(document):
1449 "Set language Serbocroatian to Croatian as this was really Croatian in LyX 1.5"
1451 if document.language == "serbocroatian":
1452 document.language = "croatian"
1453 i = find_token(document.header, "\\language", 0)
1455 document.header[i] = "\\language croatian"
1458 j = find_token(document.body, "\\lang serbocroatian", j)
1461 document.body[j] = document.body[j].replace("\\lang serbocroatian", "\\lang croatian")
1465 def convert_framed_notes(document):
1466 "Convert framed notes to boxes. "
1469 i = find_tokens(document.body, ["\\begin_inset Note Framed", "\\begin_inset Note Shaded"], i)
1472 subst = [document.body[i].replace("\\begin_inset Note", "\\begin_inset Box"),
1481 'height_special "totalheight"']
1482 document.body[i:i+1] = subst
1486 def convert_module_names(document):
1487 modulemap = { 'Braille' : 'braille', 'Endnote' : 'endnotes', 'Foot to End' : 'foottoend',\
1488 'Hanging' : 'hanging', 'Linguistics' : 'linguistics', 'Logical Markup' : 'logicalmkup', \
1489 'Theorems (AMS-Extended)' : 'theorems-ams-extended', 'Theorems (AMS)' : 'theorems-ams', \
1490 'Theorems (Order By Chapter)' : 'theorems-chap', 'Theorems (Order By Section)' : 'theorems-sec', \
1491 'Theorems (Starred)' : 'theorems-starred', 'Theorems' : 'theorems-std' }
1492 modlist = document.get_module_list()
1493 if len(modlist) == 0:
1497 if modulemap.has_key(mod):
1498 newmodlist.append(modulemap[mod])
1500 document.warning("Can't find module %s in the module map!" % mod)
1501 newmodlist.append(mod)
1502 document.set_module_list(newmodlist)
1505 def revert_module_names(document):
1506 modulemap = { 'braille' : 'Braille', 'endnotes' : 'Endnote', 'foottoend' : 'Foot to End',\
1507 'hanging' : 'Hanging', 'linguistics' : 'Linguistics', 'logicalmkup' : 'Logical Markup', \
1508 'theorems-ams-extended' : 'Theorems (AMS-Extended)', 'theorems-ams' : 'Theorems (AMS)', \
1509 'theorems-chap' : 'Theorems (Order By Chapter)', 'theorems-sec' : 'Theorems (Order By Section)', \
1510 'theorems-starred' : 'Theorems (Starred)', 'theorems-std' : 'Theorems'}
1511 modlist = document.get_module_list()
1512 if len(modlist) == 0:
1516 if modulemap.has_key(mod):
1517 newmodlist.append(modulemap[mod])
1519 document.warning("Can't find module %s in the module map!" % mod)
1520 newmodlist.append(mod)
1521 document.set_module_list(newmodlist)
1524 def revert_colsep(document):
1525 i = find_token(document.header, "\\columnsep", 0)
1528 colsepline = document.header[i]
1529 r = re.compile(r'\\columnsep (.*)')
1530 m = r.match(colsepline)
1532 document.warning("Malformed column separation line!")
1535 del document.header[i]
1536 #it seems to be safe to add the package even if it is already used
1537 pretext = ["\\usepackage{geometry}", "\\geometry{columnsep=" + colsep + "}"]
1539 add_to_preamble(document, pretext)
1542 def revert_framed_notes(document):
1543 "Revert framed boxes to notes. "
1546 i = find_tokens(document.body, ["\\begin_inset Box Framed", "\\begin_inset Box Shaded"], i)
1550 j = find_end_of_inset(document.body, i + 1)
1553 document.warning("Malformed LyX document: Could not find end of Box inset.")
1554 k = find_token(document.body, "status", i + 1, j)
1556 document.warning("Malformed LyX document: Missing `status' tag in Box inset.")
1558 status = document.body[k]
1559 l = find_default_layout(document, i + 1, j)
1561 document.warning("Malformed LyX document: Missing `\\begin_layout' in Box inset.")
1563 m = find_token(document.body, "\\end_layout", i + 1, j)
1565 document.warning("Malformed LyX document: Missing `\\end_layout' in Box inset.")
1567 ibox = find_token(document.body, "has_inner_box 1", i + 1, k)
1568 pbox = find_token(document.body, "use_parbox 1", i + 1, k)
1569 if ibox == -1 and pbox == -1:
1570 document.body[i] = document.body[i].replace("\\begin_inset Box", "\\begin_inset Note")
1571 del document.body[i+1:k]
1573 document.body[i] = document.body[i].replace("\\begin_inset Box Shaded", "\\begin_inset Box Frameless")
1574 subst1 = [document.body[l],
1575 "\\begin_inset Note Shaded",
1577 '\\begin_layout Standard']
1578 document.body[l:l + 1] = subst1
1579 subst2 = [document.body[m], "\\end_layout", "\\end_inset"]
1580 document.body[m:m + 1] = subst2
1584 def revert_slash(document):
1585 'Revert \\SpecialChar \\slash{} to ERT'
1586 r = re.compile(r'\\SpecialChar \\slash{}')
1588 while i < len(document.body):
1589 m = r.match(document.body[i])
1591 subst = ['\\begin_inset ERT',
1592 'status collapsed', '',
1593 '\\begin_layout Standard',
1594 '', '', '\\backslash',
1598 document.body[i: i+1] = subst
1604 def revert_nobreakdash(document):
1605 'Revert \\SpecialChar \\nobreakdash- to ERT'
1607 while i < len(document.body):
1608 line = document.body[i]
1609 r = re.compile(r'\\SpecialChar \\nobreakdash-')
1612 subst = ['\\begin_inset ERT',
1613 'status collapsed', '',
1614 '\\begin_layout Standard', '', '',
1619 document.body[i:i+1] = subst
1621 j = find_token(document.header, "\\use_amsmath", 0)
1623 document.warning("Malformed LyX document: Missing '\\use_amsmath'.")
1625 document.header[j] = "\\use_amsmath 2"
1630 #Returns number of lines added/removed
1631 def revert_nocite_key(body, start, end):
1632 'key "..." -> \nocite{...}'
1633 r = re.compile(r'^key "(.*)"')
1637 m = r.match(body[i])
1639 body[i:i+1] = ["\\backslash", "nocite{" + m.group(1) + "}"]
1640 j += 1 # because we added a line
1641 i += 2 # skip that line
1644 j -= 1 # because we deleted a line
1645 # no need to change i, since it now points to the next line
1649 def revert_nocite(document):
1650 "Revert LatexCommand nocite to ERT"
1653 i = find_token(document.body, "\\begin_inset CommandInset citation", i)
1656 if (document.body[i+1] != "LatexCommand nocite"):
1657 # note that we already incremented i
1660 insetEnd = find_end_of_inset(document.body, i)
1662 #this should not happen
1663 document.warning("End of CommandInset citation not found in revert_nocite!")
1666 paramLocation = i + 2 #start of the inset's parameters
1668 document.body[i:i+2] = \
1669 ["\\begin_inset ERT", "status collapsed", "", "\\begin_layout Standard"]
1670 # that added two lines
1673 #print insetEnd, document.body[i: insetEnd + 1]
1674 insetEnd += revert_nocite_key(document.body, paramLocation, insetEnd)
1675 #print insetEnd, document.body[i: insetEnd + 1]
1676 document.body.insert(insetEnd, "\\end_layout")
1677 document.body.insert(insetEnd + 1, "")
1681 def revert_btprintall(document):
1682 "Revert (non-bibtopic) btPrintAll option to ERT \nocite{*}"
1683 i = find_token(document.header, '\\use_bibtopic', 0)
1685 document.warning("Malformed lyx document: Missing '\\use_bibtopic'.")
1687 if get_value(document.header, '\\use_bibtopic', 0) == "false":
1689 while i < len(document.body):
1690 i = find_token(document.body, "\\begin_inset CommandInset bibtex", i)
1693 j = find_end_of_inset(document.body, i + 1)
1695 #this should not happen
1696 document.warning("End of CommandInset bibtex not found in revert_btprintall!")
1697 j = len(document.body)
1698 # this range isn't really right, but it should be OK, since we shouldn't
1699 # see more than one matching line in each inset
1701 for k in range(i, j):
1702 if (document.body[k] == 'btprint "btPrintAll"'):
1703 del document.body[k]
1704 subst = ["\\begin_inset ERT",
1705 "status collapsed", "",
1706 "\\begin_layout Standard", "",
1711 document.body[i:i] = subst
1712 addlines = addedlines + len(subst) - 1
1716 def revert_bahasam(document):
1717 "Set language Bahasa Malaysia to Bahasa Indonesia"
1719 if document.language == "bahasam":
1720 document.language = "bahasa"
1721 i = find_token(document.header, "\\language", 0)
1723 document.header[i] = "\\language bahasa"
1726 j = find_token(document.body, "\\lang bahasam", j)
1729 document.body[j] = document.body[j].replace("\\lang bahasam", "\\lang bahasa")
1733 def revert_interlingua(document):
1734 "Set language Interlingua to English"
1736 if document.language == "interlingua":
1737 document.language = "english"
1738 i = find_token(document.header, "\\language", 0)
1740 document.header[i] = "\\language english"
1743 j = find_token(document.body, "\\lang interlingua", j)
1746 document.body[j] = document.body[j].replace("\\lang interlingua", "\\lang english")
1750 def revert_serbianlatin(document):
1751 "Set language Serbian-Latin to Croatian"
1753 if document.language == "serbian-latin":
1754 document.language = "croatian"
1755 i = find_token(document.header, "\\language", 0)
1757 document.header[i] = "\\language croatian"
1760 j = find_token(document.body, "\\lang serbian-latin", j)
1763 document.body[j] = document.body[j].replace("\\lang serbian-latin", "\\lang croatian")
1767 def revert_rotfloat(document):
1768 " Revert sideways custom floats. "
1771 # whitespace intended (exclude \\begin_inset FloatList)
1772 i = find_token(document.body, "\\begin_inset Float ", i)
1775 line = document.body[i]
1776 r = re.compile(r'\\begin_inset Float (.*)$')
1779 document.warning("Unable to match line " + str(i) + " of body!")
1782 floattype = m.group(1)
1783 if floattype == "figure" or floattype == "table":
1786 j = find_end_of_inset(document.body, i)
1788 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_rotfloat.")
1792 if get_value(document.body, 'sideways', i, j) == "false":
1795 l = find_default_layout(document, i + 1, j)
1797 document.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
1799 subst = ['\\begin_layout Standard',
1800 '\\begin_inset ERT',
1801 'status collapsed', '',
1802 '\\begin_layout Standard', '', '',
1804 'end{sideways' + floattype + '}',
1805 '\\end_layout', '', '\\end_inset']
1806 document.body[j : j+1] = subst
1807 addedLines = len(subst) - 1
1808 del document.body[i+1 : l]
1809 addedLines -= (l-1) - (i+1)
1810 subst = ['\\begin_inset ERT', 'status collapsed', '',
1811 '\\begin_layout Standard', '', '', '\\backslash',
1812 'begin{sideways' + floattype + '}',
1813 '\\end_layout', '', '\\end_inset', '',
1815 document.body[i : i+1] = subst
1816 addedLines += len(subst) - 1
1817 if floattype == "algorithm":
1818 add_to_preamble(document,
1819 ['% Commands inserted by lyx2lyx for sideways algorithm float',
1820 '\\usepackage{rotfloat}',
1821 '\\floatstyle{ruled}',
1822 '\\newfloat{algorithm}{tbp}{loa}',
1823 '\\floatname{algorithm}{Algorithm}'])
1825 document.warning("Cannot create preamble definition for custom float" + floattype + ".")
1829 def revert_widesideways(document):
1830 " Revert wide sideways floats. "
1833 # whitespace intended (exclude \\begin_inset FloatList)
1834 i = find_token(document.body, '\\begin_inset Float ', i)
1837 line = document.body[i]
1838 r = re.compile(r'\\begin_inset Float (.*)$')
1841 document.warning("Unable to match line " + str(i) + " of body!")
1844 floattype = m.group(1)
1845 if floattype != "figure" and floattype != "table":
1848 j = find_end_of_inset(document.body, i)
1850 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_widesideways.")
1853 if get_value(document.body, 'sideways', i, j) == "false" or \
1854 get_value(document.body, 'wide', i, j) == "false":
1857 l = find_default_layout(document, i + 1, j)
1859 document.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
1861 subst = ['\\begin_layout Standard', '\\begin_inset ERT',
1862 'status collapsed', '',
1863 '\\begin_layout Standard', '', '', '\\backslash',
1864 'end{sideways' + floattype + '*}',
1865 '\\end_layout', '', '\\end_inset']
1866 document.body[j : j+1] = subst
1867 addedLines = len(subst) - 1
1868 del document.body[i+1:l-1]
1869 addedLines -= (l-1) - (i+1)
1870 subst = ['\\begin_inset ERT', 'status collapsed', '',
1871 '\\begin_layout Standard', '', '', '\\backslash',
1872 'begin{sideways' + floattype + '*}', '\\end_layout', '',
1873 '\\end_inset', '', '\\end_layout', '']
1874 document.body[i : i+1] = subst
1875 addedLines += len(subst) - 1
1876 add_to_preamble(document, ['\\usepackage{rotfloat}\n'])
1880 def revert_inset_embedding(document, type):
1881 ' Remove embed tag from certain type of insets'
1884 i = find_token(document.body, "\\begin_inset %s" % type, i)
1887 j = find_end_of_inset(document.body, i)
1889 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_inset_embedding.")
1892 k = find_token(document.body, "\tembed", i, j)
1894 k = find_token(document.body, "embed", i, j)
1896 del document.body[k]
1900 def revert_external_embedding(document):
1901 ' Remove embed tag from external inset '
1902 revert_inset_embedding(document, 'External')
1905 def convert_subfig(document):
1906 " Convert subfigures to subfloats. "
1909 i = find_token(document.body, '\\begin_inset Graphics', i)
1912 endInset = find_end_of_inset(document.body, i)
1914 document.warning("Malformed lyx document: Missing '\\end_inset' in convert_subfig.")
1917 k = find_token(document.body, '\tsubcaption', i, endInset)
1921 l = find_token(document.body, '\tsubcaptionText', i, endInset)
1923 document.warning("Malformed lyx document: Can't find subcaptionText!")
1926 caption = document.body[l][16:].strip('"')
1927 del document.body[l]
1928 del document.body[k]
1930 subst = ['\\begin_inset Float figure', 'wide false', 'sideways false',
1931 'status open', '', '\\begin_layout Plain Layout', '\\begin_inset Caption',
1932 '', '\\begin_layout Plain Layout'] + latex2lyx(caption) + \
1933 [ '\\end_layout', '', '\\end_inset', '',
1934 '\\end_layout', '', '\\begin_layout Plain Layout']
1935 document.body[i : i] = subst
1936 addedLines += len(subst)
1937 endInset += addedLines
1938 subst = ['', '\\end_inset', '', '\\end_layout']
1939 document.body[endInset : endInset] = subst
1940 addedLines += len(subst)
1944 def revert_subfig(document):
1945 " Revert subfloats. "
1948 # whitespace intended (exclude \\begin_inset FloatList)
1949 i = find_tokens(document.body, ['\\begin_inset Float ', '\\begin_inset Wrap'], i)
1955 j = find_end_of_inset(document.body, i)
1957 document.warning("Malformed lyx document: Missing '\\end_inset' (float) at line " + str(i + len(document.header)) + ".\n\t" + document.body[i])
1958 # document.warning(document.body[i-1] + "\n" + document.body[i+1])
1960 continue # this will get us back to the outer loop, since j == -1
1961 # look for embedded float (= subfloat)
1962 # whitespace intended (exclude \\begin_inset FloatList)
1963 k = find_token(document.body, '\\begin_inset Float ', i + 1, j)
1966 l = find_end_of_inset(document.body, k)
1968 document.warning("Malformed lyx document: Missing '\\end_inset' (embedded float).")
1971 continue # escape to the outer loop
1972 m = find_default_layout(document, k + 1, l)
1974 cap = find_token(document.body, '\\begin_inset Caption', k + 1, l)
1979 capend = find_end_of_inset(document.body, cap)
1981 document.warning("Malformed lyx document: Missing '\\end_inset' (caption).")
1985 lbl = find_token(document.body, '\\begin_inset CommandInset label', cap, capend)
1987 lblend = find_end_of_inset(document.body, lbl + 1)
1989 document.warning("Malformed lyx document: Missing '\\end_inset' (label).")
1991 for line in document.body[lbl:lblend + 1]:
1992 if line.startswith('name '):
1993 label = line.split()[1].strip('"')
2000 opt = find_token(document.body, '\\begin_inset OptArg', cap, capend)
2002 optend = find_end_of_inset(document.body, opt)
2004 document.warning("Malformed lyx document: Missing '\\end_inset' (OptArg).")
2006 optc = find_default_layout(document, opt, optend)
2008 document.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
2010 optcend = find_end_of(document.body, optc, "\\begin_layout", "\\end_layout")
2011 for line in document.body[optc:optcend]:
2012 if not line.startswith('\\'):
2013 shortcap += line.strip()
2017 for line in document.body[cap:capend]:
2018 if line in document.body[lbl:lblend]:
2020 elif line in document.body[opt:optend]:
2022 elif not line.startswith('\\'):
2023 caption += line.strip()
2025 caption += "\\backslash\nlabel{" + label + "}"
2026 subst = '\\begin_layout Plain Layout\n\\begin_inset ERT\nstatus collapsed\n\n' \
2027 '\\begin_layout Plain Layout\n\n}\n\\end_layout\n\n\\end_inset\n\n' \
2028 '\\end_layout\n\n\\begin_layout Plain Layout\n'
2029 subst = subst.split('\n')
2030 document.body[l : l+1] = subst
2031 addedLines = len(subst) - 1
2032 # this is before l and so is unchanged by the multiline insertion
2034 del document.body[cap:capend+1]
2035 addedLines -= (capend + 1 - cap)
2036 del document.body[k+1:m-1]
2037 addedLines -= (m - 1 - (k + 1))
2038 insertion = '\\begin_inset ERT\nstatus collapsed\n\n' \
2039 '\\begin_layout Plain Layout\n\n\\backslash\n' \
2041 if len(shortcap) > 0:
2042 insertion = insertion + "[" + shortcap + "]"
2043 if len(caption) > 0:
2044 insertion = insertion + "[" + caption + "]"
2045 insertion = insertion + '{%\n\\end_layout\n\n\\end_inset\n\n\\end_layout\n'
2046 insertion = insertion.split('\n')
2047 document.body[k : k + 1] = insertion
2048 addedLines += len(insertion) - 1
2049 add_to_preamble(document, ['\\usepackage{subfig}\n'])
2053 def revert_wrapplacement(document):
2054 " Revert placement options wrap floats (wrapfig). "
2057 i = find_token(document.body, "\\begin_inset Wrap figure", i)
2060 e = find_end_of_inset(document.body, i)
2061 j = find_token(document.body, "placement", i + 1, e)
2063 document.warning("Malformed LyX document: Couldn't find placement parameter of wrap float.")
2066 r = re.compile("placement (o|i|l|r)")
2067 m = r.match(document.body[j])
2069 document.warning("Malformed LyX document: Placement option isn't O|I|R|L!")
2070 document.body[j] = "placement " + m.group(1).lower()
2074 def remove_extra_embedded_files(document):
2075 " Remove \extra_embedded_files from buffer params "
2076 i = find_token(document.header, '\\extra_embedded_files', 0)
2079 document.header.pop(i)
2082 def convert_spaceinset(document):
2083 " Convert '\\InsetSpace foo' to '\\begin_inset Space foo\n\\end_inset' "
2085 while i < len(document.body):
2086 m = re.match(r'(.*)\\InsetSpace (.*)', document.body[i])
2090 subst = [before, "\\begin_inset Space " + after, "\\end_inset"]
2091 document.body[i: i+1] = subst
2097 def revert_spaceinset(document):
2098 " Revert '\\begin_inset Space foo\n\\end_inset' to '\\InsetSpace foo' "
2101 i = find_token(document.body, "\\begin_inset Space", i)
2104 j = find_end_of_inset(document.body, i)
2106 document.warning("Malformed LyX document: Could not find end of space inset.")
2108 document.body[i] = document.body[i].replace('\\begin_inset Space', '\\InsetSpace')
2109 del document.body[j]
2112 def convert_hfill(document):
2113 " Convert hfill to space inset "
2116 i = find_token(document.body, "\\hfill", i)
2119 subst = document.body[i].replace('\\hfill', \
2120 '\n\\begin_inset Space \\hfill{}\n\\end_inset')
2121 subst = subst.split('\n')
2122 document.body[i : i+1] = subst
2126 def revert_hfills(document):
2127 ' Revert \\hfill commands '
2128 hfill = re.compile(r'\\hfill')
2129 dotfill = re.compile(r'\\dotfill')
2130 hrulefill = re.compile(r'\\hrulefill')
2133 i = find_token(document.body, "\\InsetSpace", i)
2136 if hfill.search(document.body[i]):
2137 document.body[i] = \
2138 document.body[i].replace('\\InsetSpace \\hfill{}', '\\hfill')
2141 if dotfill.search(document.body[i]):
2142 subst = document.body[i].replace('\\InsetSpace \\dotfill{}', \
2143 '\\begin_inset ERT\nstatus collapsed\n\n' \
2144 '\\begin_layout Standard\n\n\n\\backslash\n' \
2145 'dotfill{}\n\\end_layout\n\n\\end_inset\n\n')
2146 subst = subst.split('\n')
2147 document.body[i : i+1] = subst
2150 if hrulefill.search(document.body[i]):
2151 subst = document.body[i].replace('\\InsetSpace \\hrulefill{}', \
2152 '\\begin_inset ERT\nstatus collapsed\n\n' \
2153 '\\begin_layout Standard\n\n\n\\backslash\n' \
2154 'hrulefill{}\n\\end_layout\n\n\\end_inset\n\n')
2155 subst = subst.split('\n')
2156 document.body[i : i+1] = subst
2161 def revert_hspace(document):
2162 ' Revert \\InsetSpace \\hspace{} to ERT '
2164 hspace = re.compile(r'\\hspace{}')
2165 hstar = re.compile(r'\\hspace\*{}')
2167 i = find_token(document.body, "\\InsetSpace \\hspace", i)
2170 length = get_value(document.body, '\\length', i+1)
2172 document.warning("Malformed lyx document: Missing '\\length' in Space inset.")
2174 del document.body[i+1]
2176 if hstar.search(document.body[i]):
2177 subst = document.body[i].replace('\\InsetSpace \\hspace*{}', \
2178 '\\begin_inset ERT\nstatus collapsed\n\n' \
2179 '\\begin_layout Standard\n\n\n\\backslash\n' \
2180 'hspace*{' + length + '}\n\\end_layout\n\n\\end_inset\n\n')
2181 subst = subst.split('\n')
2182 document.body[i : i+1] = subst
2183 addedLines += len(subst) - 1
2186 if hspace.search(document.body[i]):
2187 subst = document.body[i].replace('\\InsetSpace \\hspace{}', \
2188 '\\begin_inset ERT\nstatus collapsed\n\n' \
2189 '\\begin_layout Standard\n\n\n\\backslash\n' \
2190 'hspace{' + length + '}\n\\end_layout\n\n\\end_inset\n\n')
2191 subst = subst.split('\n')
2192 document.body[i : i+1] = subst
2193 addedLines += len(subst) - 1
2199 def revert_protected_hfill(document):
2200 ' Revert \\begin_inset Space \\hspace*{\\fill} to ERT '
2203 i = find_token(document.body, '\\begin_inset Space \\hspace*{\\fill}', i)
2206 j = find_end_of_inset(document.body, i)
2208 document.warning("Malformed LyX document: Could not find end of space inset.")
2210 del document.body[j]
2211 subst = document.body[i].replace('\\begin_inset Space \\hspace*{\\fill}', \
2212 '\\begin_inset ERT\nstatus collapsed\n\n' \
2213 '\\begin_layout Standard\n\n\n\\backslash\n' \
2214 'hspace*{\n\\backslash\nfill}\n\\end_layout\n\n\\end_inset\n\n')
2215 subst = subst.split('\n')
2216 document.body[i : i+1] = subst
2220 def revert_leftarrowfill(document):
2221 ' Revert \\begin_inset Space \\leftarrowfill{} to ERT '
2224 i = find_token(document.body, '\\begin_inset Space \\leftarrowfill{}', i)
2227 j = find_end_of_inset(document.body, i)
2229 document.warning("Malformed LyX document: Could not find end of space inset.")
2231 del document.body[j]
2232 subst = document.body[i].replace('\\begin_inset Space \\leftarrowfill{}', \
2233 '\\begin_inset ERT\nstatus collapsed\n\n' \
2234 '\\begin_layout Standard\n\n\n\\backslash\n' \
2235 'leftarrowfill{}\n\\end_layout\n\n\\end_inset\n\n')
2236 subst = subst.split('\n')
2237 document.body[i : i+1] = subst
2241 def revert_rightarrowfill(document):
2242 ' Revert \\begin_inset Space \\rightarrowfill{} to ERT '
2245 i = find_token(document.body, '\\begin_inset Space \\rightarrowfill{}', i)
2248 j = find_end_of_inset(document.body, i)
2250 document.warning("Malformed LyX document: Could not find end of space inset.")
2252 del document.body[j]
2253 subst = document.body[i].replace('\\begin_inset Space \\rightarrowfill{}', \
2254 '\\begin_inset ERT\nstatus collapsed\n\n' \
2255 '\\begin_layout Standard\n\n\n\\backslash\n' \
2256 'rightarrowfill{}\n\\end_layout\n\n\\end_inset\n\n')
2257 subst = subst.split('\n')
2258 document.body[i : i+1] = subst
2262 def revert_upbracefill(document):
2263 ' Revert \\begin_inset Space \\upbracefill{} to ERT '
2266 i = find_token(document.body, '\\begin_inset Space \\upbracefill{}', i)
2269 j = find_end_of_inset(document.body, i)
2271 document.warning("Malformed LyX document: Could not find end of space inset.")
2273 del document.body[j]
2274 subst = document.body[i].replace('\\begin_inset Space \\upbracefill{}', \
2275 '\\begin_inset ERT\nstatus collapsed\n\n' \
2276 '\\begin_layout Standard\n\n\n\\backslash\n' \
2277 'upbracefill{}\n\\end_layout\n\n\\end_inset\n\n')
2278 subst = subst.split('\n')
2279 document.body[i : i+1] = subst
2283 def revert_downbracefill(document):
2284 ' Revert \\begin_inset Space \\downbracefill{} to ERT '
2287 i = find_token(document.body, '\\begin_inset Space \\downbracefill{}', i)
2290 j = find_end_of_inset(document.body, i)
2292 document.warning("Malformed LyX document: Could not find end of space inset.")
2294 del document.body[j]
2295 subst = document.body[i].replace('\\begin_inset Space \\downbracefill{}', \
2296 '\\begin_inset ERT\nstatus collapsed\n\n' \
2297 '\\begin_layout Standard\n\n\n\\backslash\n' \
2298 'downbracefill{}\n\\end_layout\n\n\\end_inset\n\n')
2299 subst = subst.split('\n')
2300 document.body[i : i+1] = subst
2304 def revert_local_layout(document):
2305 ' Revert local layout headers.'
2308 i = find_token(document.header, "\\begin_local_layout", i)
2311 j = find_end_of(document.header, i, "\\begin_local_layout", "\\end_local_layout")
2313 # this should not happen
2315 document.header[i : j + 1] = []
2318 def convert_pagebreaks(document):
2319 ' Convert inline Newpage insets to new format '
2322 i = find_token(document.body, '\\newpage', i)
2325 document.body[i:i+1] = ['\\begin_inset Newpage newpage',
2329 i = find_token(document.body, '\\pagebreak', i)
2332 document.body[i:i+1] = ['\\begin_inset Newpage pagebreak',
2336 i = find_token(document.body, '\\clearpage', i)
2339 document.body[i:i+1] = ['\\begin_inset Newpage clearpage',
2343 i = find_token(document.body, '\\cleardoublepage', i)
2346 document.body[i:i+1] = ['\\begin_inset Newpage cleardoublepage',
2350 def revert_pagebreaks(document):
2351 ' Revert \\begin_inset Newpage to previous inline format '
2354 i = find_token(document.body, '\\begin_inset Newpage', i)
2357 j = find_end_of_inset(document.body, i)
2359 document.warning("Malformed LyX document: Could not find end of Newpage inset.")
2361 del document.body[j]
2362 document.body[i] = document.body[i].replace('\\begin_inset Newpage newpage', '\\newpage')
2363 document.body[i] = document.body[i].replace('\\begin_inset Newpage pagebreak', '\\pagebreak')
2364 document.body[i] = document.body[i].replace('\\begin_inset Newpage clearpage', '\\clearpage')
2365 document.body[i] = document.body[i].replace('\\begin_inset Newpage cleardoublepage', '\\cleardoublepage')
2368 def convert_linebreaks(document):
2369 ' Convert inline Newline insets to new format '
2372 i = find_token(document.body, '\\newline', i)
2375 document.body[i:i+1] = ['\\begin_inset Newline newline',
2379 i = find_token(document.body, '\\linebreak', i)
2382 document.body[i:i+1] = ['\\begin_inset Newline linebreak',
2386 def revert_linebreaks(document):
2387 ' Revert \\begin_inset Newline to previous inline format '
2390 i = find_token(document.body, '\\begin_inset Newline', i)
2393 j = find_end_of_inset(document.body, i)
2395 document.warning("Malformed LyX document: Could not find end of Newline inset.")
2397 del document.body[j]
2398 document.body[i] = document.body[i].replace('\\begin_inset Newline newline', '\\newline')
2399 document.body[i] = document.body[i].replace('\\begin_inset Newline linebreak', '\\linebreak')
2402 def convert_japanese_plain(document):
2403 ' Set language japanese-plain to japanese '
2405 if document.language == "japanese-plain":
2406 document.language = "japanese"
2407 i = find_token(document.header, "\\language", 0)
2409 document.header[i] = "\\language japanese"
2412 j = find_token(document.body, "\\lang japanese-plain", j)
2415 document.body[j] = document.body[j].replace("\\lang japanese-plain", "\\lang japanese")
2419 def revert_pdfpages(document):
2420 ' Revert pdfpages external inset to ERT '
2423 i = find_token(document.body, "\\begin_inset External", i)
2426 j = find_end_of_inset(document.body, i)
2428 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_pdfpages.")
2431 if get_value(document.body, 'template', i, j) == "PDFPages":
2432 filename = get_value(document.body, 'filename', i, j)
2434 r = re.compile(r'\textra PDFLaTeX \"(.*)\"$')
2435 for k in range(i, j):
2436 m = r.match(document.body[k])
2439 angle = get_value(document.body, 'rotateAngle', i, j)
2440 width = get_value(document.body, 'width', i, j)
2441 height = get_value(document.body, 'height', i, j)
2442 scale = get_value(document.body, 'scale', i, j)
2443 keepAspectRatio = find_token(document.body, "\tkeepAspectRatio", i, j)
2447 options += ",angle=" + angle
2449 options += "angle=" + angle
2452 options += ",width=" + convert_len(width)
2454 options += "width=" + convert_len(width)
2457 options += ",height=" + convert_len(height)
2459 options += "height=" + convert_len(height)
2462 options += ",scale=" + scale
2464 options += "scale=" + scale
2465 if keepAspectRatio != '':
2467 options += ",keepaspectratio"
2469 options += "keepaspectratio"
2471 options = '[' + options + ']'
2472 del document.body[i+1:j+1]
2473 document.body[i:i+1] = ['\\begin_inset ERT',
2476 '\\begin_layout Standard',
2479 'includepdf' + options + '{' + filename + '}',
2483 add_to_preamble(document, ['\\usepackage{pdfpages}\n'])
2489 def revert_mexican(document):
2490 ' Set language Spanish(Mexico) to Spanish '
2492 if document.language == "spanish-mexico":
2493 document.language = "spanish"
2494 i = find_token(document.header, "\\language", 0)
2496 document.header[i] = "\\language spanish"
2499 j = find_token(document.body, "\\lang spanish-mexico", j)
2502 document.body[j] = document.body[j].replace("\\lang spanish-mexico", "\\lang spanish")
2506 def remove_embedding(document):
2507 ' Remove embed tag from all insets '
2508 revert_inset_embedding(document, 'Graphics')
2509 revert_inset_embedding(document, 'External')
2510 revert_inset_embedding(document, 'CommandInset include')
2511 revert_inset_embedding(document, 'CommandInset bibtex')
2514 def revert_master(document):
2515 ' Remove master param '
2516 i = find_token(document.header, "\\master", 0)
2518 del document.header[i]
2521 def revert_graphics_group(document):
2522 ' Revert group information from graphics insets '
2525 i = find_token(document.body, "\\begin_inset Graphics", i)
2528 j = find_end_of_inset(document.body, i)
2530 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_graphics_group.")
2533 k = find_token(document.body, " groupId", i, j)
2537 del document.body[k]
2541 def update_apa_styles(document):
2542 ' Replace obsolete styles '
2544 if document.textclass != "apa":
2547 obsoletedby = { "Acknowledgments": "Acknowledgements",
2548 "Section*": "Section",
2549 "Subsection*": "Subsection",
2550 "Subsubsection*": "Subsubsection",
2551 "Paragraph*": "Paragraph",
2552 "Subparagraph*": "Subparagraph"}
2555 i = find_token(document.body, "\\begin_layout", i)
2559 layout = document.body[i][14:]
2560 if layout in obsoletedby:
2561 document.body[i] = "\\begin_layout " + obsoletedby[layout]
2566 def convert_paper_sizes(document):
2567 ' exchange size options legalpaper and executivepaper to correct order '
2568 # routine is needed to fix http://bugzilla.lyx.org/show_bug.cgi?id=4868
2571 i = find_token(document.header, "\\papersize executivepaper", 0)
2573 document.header[i] = "\\papersize legalpaper"
2575 j = find_token(document.header, "\\papersize legalpaper", 0)
2577 document.header[j] = "\\papersize executivepaper"
2580 def revert_paper_sizes(document):
2581 ' exchange size options legalpaper and executivepaper to correct order '
2584 i = find_token(document.header, "\\papersize executivepaper", 0)
2586 document.header[i] = "\\papersize legalpaper"
2588 j = find_token(document.header, "\\papersize legalpaper", 0)
2590 document.header[j] = "\\papersize executivepaper"
2593 def convert_InsetSpace(document):
2594 " Convert '\\begin_inset Space foo' to '\\begin_inset space foo'"
2597 i = find_token(document.body, "\\begin_inset Space", i)
2600 document.body[i] = document.body[i].replace('\\begin_inset Space', '\\begin_inset space')
2603 def revert_InsetSpace(document):
2604 " Revert '\\begin_inset space foo' to '\\begin_inset Space foo'"
2607 i = find_token(document.body, "\\begin_inset space", i)
2610 document.body[i] = document.body[i].replace('\\begin_inset space', '\\begin_inset Space')
2613 def convert_display_enum(document):
2614 " Convert 'display foo' to 'display false/true'"
2617 i = find_token(document.body, "\tdisplay", i)
2620 val = get_value(document.body, 'display', i)
2622 document.body[i] = document.body[i].replace('none', 'false')
2623 if val == "default":
2624 document.body[i] = document.body[i].replace('default', 'true')
2625 if val == "monochrome":
2626 document.body[i] = document.body[i].replace('monochrome', 'true')
2627 if val == "grayscale":
2628 document.body[i] = document.body[i].replace('grayscale', 'true')
2630 document.body[i] = document.body[i].replace('color', 'true')
2631 if val == "preview":
2632 document.body[i] = document.body[i].replace('preview', 'true')
2636 def revert_display_enum(document):
2637 " Revert 'display false/true' to 'display none/color'"
2640 i = find_token(document.body, "\tdisplay", i)
2643 val = get_value(document.body, 'display', i)
2645 document.body[i] = document.body[i].replace('false', 'none')
2647 document.body[i] = document.body[i].replace('true', 'default')
2651 def remove_fontsCJK(document):
2652 ' Remove font_cjk param '
2653 i = find_token(document.header, "\\font_cjk", 0)
2655 del document.header[i]
2658 def convert_plain_layout(document):
2659 " Convert 'PlainLayout' to 'Plain Layout'"
2662 i = find_token(document.body, '\\begin_layout PlainLayout', i)
2665 document.body[i] = document.body[i].replace('\\begin_layout PlainLayout', \
2666 '\\begin_layout Plain Layout')
2670 def revert_plain_layout(document):
2671 " Convert 'PlainLayout' to 'Plain Layout'"
2674 i = find_token(document.body, '\\begin_layout Plain Layout', i)
2677 document.body[i] = document.body[i].replace('\\begin_layout Plain Layout', \
2678 '\\begin_layout PlainLayout')
2682 def revert_plainlayout(document):
2683 " Convert 'PlainLayout' to 'Plain Layout'"
2686 i = find_token(document.body, '\\begin_layout PlainLayout', i)
2689 # This will be incorrect for some document classes, since Standard is not always
2690 # the default. But (a) it is probably the best we can do and (b) it will actually
2691 # work, in fact, since an unknown layout will be converted to default.
2692 document.body[i] = document.body[i].replace('\\begin_layout PlainLayout', \
2693 '\\begin_layout Standard')
2697 def revert_polytonicgreek(document):
2698 "Set language polytonic Greek to Greek"
2700 if document.language == "polutonikogreek":
2701 document.language = "greek"
2702 i = find_token(document.header, "\\language", 0)
2704 document.header[i] = "\\language greek"
2707 j = find_token(document.body, "\\lang polutonikogreek", j)
2710 document.body[j] = document.body[j].replace("\\lang polutonikogreek", "\\lang greek")
2718 supported_versions = ["1.6.0","1.6"]
2719 convert = [[277, [fix_wrong_tables]],
2720 [278, [close_begin_deeper]],
2721 [279, [long_charstyle_names]],
2722 [280, [axe_show_label]],
2725 [283, [convert_flex]],
2729 [287, [convert_wrapfig_options]],
2730 [288, [convert_inset_command]],
2731 [289, [convert_latexcommand_index]],
2736 [294, [convert_pdf_options]],
2737 [295, [convert_htmlurl, convert_url]],
2738 [296, [convert_include]],
2739 [297, [convert_usorbian]],
2745 [303, [convert_serbocroatian]],
2746 [304, [convert_framed_notes]],
2753 [311, [convert_ams_classes]],
2755 [313, [convert_module_names]],
2758 [316, [convert_subfig]],
2761 [319, [convert_spaceinset, convert_hfill]],
2763 [321, [convert_tablines]],
2764 [322, [convert_plain_layout]],
2765 [323, [convert_pagebreaks]],
2766 [324, [convert_linebreaks]],
2767 [325, [convert_japanese_plain]],
2770 [328, [remove_embedding, remove_extra_embedded_files, remove_inzip_options]],
2773 [331, [convert_ltcaption]],
2775 [333, [update_apa_styles]],
2776 [334, [convert_paper_sizes]],
2777 [335, [convert_InsetSpace]],
2779 [337, [convert_display_enum]],
2783 revert = [[337, [revert_polytonicgreek]],
2784 [336, [revert_display_enum]],
2785 [335, [remove_fontsCJK]],
2786 [334, [revert_InsetSpace]],
2787 [333, [revert_paper_sizes]],
2789 [331, [revert_graphics_group]],
2790 [330, [revert_ltcaption]],
2791 [329, [revert_leftarrowfill, revert_rightarrowfill, revert_upbracefill, revert_downbracefill]],
2792 [328, [revert_master]],
2794 [326, [revert_mexican]],
2795 [325, [revert_pdfpages]],
2797 [323, [revert_linebreaks]],
2798 [322, [revert_pagebreaks]],
2799 [321, [revert_local_layout, revert_plain_layout]],
2800 [320, [revert_tablines]],
2801 [319, [revert_protected_hfill]],
2802 [318, [revert_spaceinset, revert_hfills, revert_hspace]],
2803 [317, [remove_extra_embedded_files]],
2804 [316, [revert_wrapplacement]],
2805 [315, [revert_subfig]],
2806 [314, [revert_colsep, revert_plainlayout]],
2808 [312, [revert_module_names]],
2809 [311, [revert_rotfloat, revert_widesideways]],
2810 [310, [revert_external_embedding]],
2811 [309, [revert_btprintall]],
2812 [308, [revert_nocite]],
2813 [307, [revert_serbianlatin]],
2814 [306, [revert_slash, revert_nobreakdash]],
2815 [305, [revert_interlingua]],
2816 [304, [revert_bahasam]],
2817 [303, [revert_framed_notes]],
2819 [301, [revert_latin, revert_samin]],
2820 [300, [revert_linebreak]],
2821 [299, [revert_pagebreak]],
2822 [298, [revert_hyperlinktype]],
2823 [297, [revert_macro_optional_params]],
2824 [296, [revert_albanian, revert_lowersorbian, revert_uppersorbian]],
2825 [295, [revert_include]],
2826 [294, [revert_href, revert_url]],
2827 [293, [revert_pdf_options_2]],
2828 [292, [revert_inset_info]],
2829 [291, [revert_japanese, revert_japanese_encoding]],
2830 [290, [revert_vietnamese]],
2831 [289, [revert_wraptable]],
2832 [288, [revert_latexcommand_index]],
2833 [287, [revert_inset_command]],
2834 [286, [revert_wrapfig_options]],
2835 [285, [revert_pdf_options]],
2836 [284, [remove_inzip_options]],
2838 [282, [revert_flex]],
2840 [280, [revert_begin_modules]],
2841 [279, [revert_show_label]],
2842 [278, [revert_long_charstyle_names]],
2848 if __name__ == "__main__":