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 '''Within string, replace occurrences of src with dst, wrapped into ERT
47 E.g.: wrap_into_ert('sch\"on', "\\", "\\backslash") is:
48 sch<ERT>\\backslash</ERT>"on'''
49 return string.replace(src, '\n\\begin_inset ERT\nstatus collapsed\n\\begin_layout Standard\n'
50 + dst + '\n\\end_layout\n\\end_inset\n')
52 def put_cmd_in_ert(string):
53 string = string.replace('\\', "\\backslash\n")
54 string = "\\begin_inset ERT\nstatus collapsed\n\\begin_layout Standard\n" \
55 + string + "\n\\end_layout\n\\end_inset"
58 def add_to_preamble(document, text):
59 """ Add text to the preamble if it is not already there.
60 Only the first line is checked!"""
62 if find_token(document.preamble, text[0], 0) != -1:
65 document.preamble.extend(text)
67 # Convert a LyX length into a LaTeX length
69 units = {"text%":"\\backslash\ntextwidth", "col%":"\\backslash\ncolumnwidth",
70 "page%":"\\backslash\npagewidth", "line%":"\\backslash\nlinewidth",
71 "theight%":"\\backslash\ntextheight", "pheight%":"\\backslash\npageheight"}
73 # Convert LyX units to LaTeX units
74 for unit in units.keys():
75 if len.find(unit) != -1:
76 len = '%f' % (len2value(len) / 100)
77 len = len.strip('0') + units[unit]
82 # Return the value of len without the unit in numerical form.
84 result = re.search('([+-]?[0-9.]+)', len)
86 return float(result.group(1))
90 # Unfortunately, this doesn't really work, since Standard isn't always default.
91 # But it's as good as we can do right now.
92 def find_default_layout(document, start, end):
93 l = find_token(document.body, "\\begin_layout Standard", start, end)
95 l = find_token(document.body, "\\begin_layout PlainLayout", start, end)
97 l = find_token(document.body, "\\begin_layout Plain Layout", start, end)
100 def get_option(document, m, option, default):
101 l = document.body[m].find(option)
104 val = document.body[m][l:].split('"')[1]
107 def remove_option(document, m, option):
108 l = document.body[m].find(option)
110 val = document.body[m][l:].split('"')[1]
111 document.body[m] = document.body[m][:l-1] + document.body[m][l+len(option + '="' + val + '"'):]
114 def set_option(document, m, option, value):
115 l = document.body[m].find(option)
117 oldval = document.body[m][l:].split('"')[1]
118 l = l + len(option + '="')
119 document.body[m] = document.body[m][:l] + value + document.body[m][l+len(oldval):]
121 document.body[m] = document.body[m][:-1] + ' ' + option + '="' + value + '">'
125 def read_unicodesymbols():
126 " Read the unicodesymbols list of unicode characters and corresponding commands."
127 pathname = os.path.abspath(os.path.dirname(sys.argv[0]))
128 fp = open(os.path.join(pathname.strip('lyx2lyx'), 'unicodesymbols'))
130 # Two backslashes, followed by some non-word character, and then a character
131 # in brackets. The idea is to check for constructs like: \"{u}, which is how
132 # they are written in the unicodesymbols file; but they can also be written
134 r = re.compile(r'\\\\(\W)\{(\w)\}')
135 for line in fp.readlines():
136 if line[0] != '#' and line.strip() != "":
137 line=line.replace(' "',' ') # remove all quotation marks with spaces before
138 line=line.replace('" ',' ') # remove all quotation marks with spaces after
139 line=line.replace(r'\"','"') # replace \" by " (for characters with diaeresis)
141 [ucs4,command,dead] = line.split(None,2)
142 if command[0:1] != "\\":
144 spec_chars.append([command, unichr(eval(ucs4))])
150 # If the character is a double-quote, then we need to escape it, too,
151 # since it is done that way in the LyX file.
152 if m.group(1) == "\"":
154 command += m.group(1) + m.group(2)
155 spec_chars.append([command, unichr(eval(ucs4))])
160 def extract_argument(line):
161 'Extracts a LaTeX argument from the start of line. Returns (arg, rest).'
166 bracere = re.compile("(\s*)(.*)")
167 n = bracere.match(line)
168 whitespace = n.group(1)
171 if brace != "[" and brace != "{":
195 # We never found the matching brace
196 # So, to be on the safe side, let's just return everything
197 # which will then get wrapped as ERT
199 return (line[:pos + 1], line[pos + 1:])
203 '''Converts LaTeX commands into ERT. line may well be a multi-line
204 string when it is returned.'''
209 ## FIXME Escaped \ ??
210 labelre = re.compile(r'(.*?)\\(\\(?:[a-zA-Z]+|.))(.*)')
212 m = labelre.match(line)
219 (arg, rest) = extract_argument(end)
224 cmd = put_cmd_in_ert(cmd)
225 retval += "\n" + cmd + "\n"
227 m = labelre.match(line)
233 '''Takes a string, possibly multi-line, and returns the result of
234 converting LaTeX constructs into LyX constructs. Returns a list of
235 lines, suitable for insertion into document.body.'''
239 # Convert LaTeX to Unicode
240 reps = read_unicodesymbols()
241 # Commands of this sort need to be checked to make sure they are
242 # followed by a non-alpha character, lest we replace too much.
243 hardone = re.compile(r'^\\\\[a-zA-Z]+$')
246 if hardone.match(rep[0]):
249 pos = data.find(rep[0], pos)
252 nextpos = pos + len(rep[0])
253 nextchar = data[nextpos - 1 : nextpos]
254 if nextchar.isalpha():
255 # not the end of that command
258 data = data[:pos] + rep[1] + data[nextpos:]
261 data = data.replace(rep[0], rep[1])
264 data = wrap_into_ert(data, r'\"', '"')
267 mathre = re.compile('^(.*?)(\$.*?\$)(.*)')
268 lines = data.split('\n')
270 #document.warning("LINE: " + line)
271 #document.warning(str(i) + ":" + document.body[i])
272 #document.warning("LAST: " + document.body[-1])
277 f = m.group(2).replace('\\\\', '\\')
282 subst = s.split('\n')
284 retval.append("\\begin_inset Formula " + f)
285 retval.append("\\end_inset")
287 # Handle whatever is left, which is just text
289 subst = g.split('\n')
294 ####################################################################
296 def convert_ltcaption(document):
299 i = find_token(document.body, "\\begin_inset Tabular", i)
302 j = find_end_of_inset(document.body, i + 1)
304 document.warning("Malformed LyX document: Could not find end of tabular.")
307 nrows = int(document.body[i+1].split('"')[3])
308 ncols = int(document.body[i+1].split('"')[5])
311 for k in range(nrows):
312 m = find_token(document.body, "<row", m)
315 for k in range(ncols):
316 m = find_token(document.body, "<cell", m)
318 mend = find_token(document.body, "</cell>", m + 1)
319 # first look for caption insets
320 mcap = find_token(document.body, "\\begin_inset Caption", m + 1, mend)
321 # then look for ERT captions
323 mcap = find_token(document.body, "caption", m + 1, mend)
325 mcap = find_token(document.body, "\\backslash", mcap - 1, mcap)
328 if caption == 'true':
330 set_option(document, r, 'caption', 'true')
331 set_option(document, m, 'multicolumn', '1')
332 set_option(document, m, 'bottomline', 'false')
333 set_option(document, m, 'topline', 'false')
334 set_option(document, m, 'rightline', 'false')
335 set_option(document, m, 'leftline', 'false')
336 #j = find_end_of_inset(document.body, j + 1)
338 set_option(document, m, 'multicolumn', '2')
345 #FIXME Use of wrap_into_ert can confuse lyx2lyx
346 def revert_ltcaption(document):
349 i = find_token(document.body, "\\begin_inset Tabular", i)
352 j = find_end_of_inset(document.body, i + 1)
354 document.warning("Malformed LyX document: Could not find end of tabular.")
358 nrows = int(document.body[i+1].split('"')[3])
359 ncols = int(document.body[i+1].split('"')[5])
361 for k in range(nrows):
362 m = find_token(document.body, "<row", m)
363 caption = get_option(document, m, 'caption', 'false')
364 if caption == 'true':
365 remove_option(document, m, 'caption')
366 for k in range(ncols):
367 m = find_token(document.body, "<cell", m)
368 remove_option(document, m, 'multicolumn')
370 m = find_token(document.body, "\\begin_inset Caption", m)
373 m = find_end_of_inset(document.body, m + 1)
374 document.body[m] += wrap_into_ert("","","\\backslash\n\\backslash\n%")
380 def convert_tablines(document):
383 i = find_token(document.body, "\\begin_inset Tabular", i)
385 # LyX 1.3 inserted an extra space between \begin_inset
386 # and Tabular so let us try if this is the case and fix it.
387 i = find_token(document.body, "\\begin_inset Tabular", i)
391 document.body[i] = "\\begin_inset Tabular"
392 j = find_end_of_inset(document.body, i + 1)
394 document.warning("Malformed LyX document: Could not find end of tabular.")
398 nrows = int(document.body[i+1].split('"')[3])
399 ncols = int(document.body[i+1].split('"')[5])
402 for k in range(ncols):
403 m = find_token(document.body, "<column", m)
404 left = get_option(document, m, 'leftline', 'false')
405 right = get_option(document, m, 'rightline', 'false')
406 col_info.append([left, right])
407 remove_option(document, m, 'leftline')
408 remove_option(document, m, 'rightline')
412 for k in range(nrows):
413 m = find_token(document.body, "<row", m)
414 top = get_option(document, m, 'topline', 'false')
415 bottom = get_option(document, m, 'bottomline', 'false')
416 row_info.append([top, bottom])
417 remove_option(document, m, 'topline')
418 remove_option(document, m, 'bottomline')
423 for k in range(nrows*ncols):
424 m = find_token(document.body, "<cell", m)
425 mc_info.append(get_option(document, m, 'multicolumn', '0'))
428 for l in range(nrows):
429 for k in range(ncols):
430 m = find_token(document.body, '<cell', m)
431 if mc_info[l*ncols + k] == '0':
432 r = set_option(document, m, 'topline', row_info[l][0])
433 r = set_option(document, m, 'bottomline', row_info[l][1])
434 r = set_option(document, m, 'leftline', col_info[k][0])
435 r = set_option(document, m, 'rightline', col_info[k][1])
436 elif mc_info[l*ncols + k] == '1':
438 while s < ncols and mc_info[l*ncols + s] == '2':
440 if s < ncols and mc_info[l*ncols + s] != '1':
441 r = set_option(document, m, 'rightline', col_info[k][1])
442 if k > 0 and mc_info[l*ncols + k - 1] == '0':
443 r = set_option(document, m, 'leftline', col_info[k][0])
448 def revert_tablines(document):
451 i = find_token(document.body, "\\begin_inset Tabular", i)
454 j = find_end_of_inset(document.body, i + 1)
456 document.warning("Malformed LyX document: Could not find end of tabular.")
460 nrows = int(document.body[i+1].split('"')[3])
461 ncols = int(document.body[i+1].split('"')[5])
464 for k in range(nrows*ncols):
465 m = find_token(document.body, "<cell", m)
466 top = get_option(document, m, 'topline', 'false')
467 bottom = get_option(document, m, 'bottomline', 'false')
468 left = get_option(document, m, 'leftline', 'false')
469 right = get_option(document, m, 'rightline', 'false')
470 lines.append([top, bottom, left, right])
473 # we will want to ignore longtable captions
476 for k in range(nrows):
477 m = find_token(document.body, "<row", m)
478 caption = get_option(document, m, 'caption', 'false')
479 caption_info.append([caption])
484 for k in range(ncols):
485 m = find_token(document.body, "<column", m)
487 for l in range(nrows):
488 left = lines[l*ncols + k][2]
489 if left == 'false' and caption_info[l] == 'false':
491 set_option(document, m, 'leftline', left)
493 for l in range(nrows):
494 right = lines[l*ncols + k][3]
495 if right == 'false' and caption_info[l] == 'false':
497 set_option(document, m, 'rightline', right)
501 for k in range(nrows):
502 m = find_token(document.body, "<row", m)
504 for l in range(ncols):
505 top = lines[k*ncols + l][0]
508 if caption_info[k] == 'false':
510 set_option(document, m, 'topline', top)
512 for l in range(ncols):
513 bottom = lines[k*ncols + l][1]
514 if bottom == 'false':
516 if caption_info[k] == 'false':
518 set_option(document, m, 'bottomline', bottom)
524 def fix_wrong_tables(document):
527 i = find_token(document.body, "\\begin_inset Tabular", i)
530 j = find_end_of_inset(document.body, i + 1)
532 document.warning("Malformed LyX document: Could not find end of tabular.")
536 nrows = int(document.body[i+1].split('"')[3])
537 ncols = int(document.body[i+1].split('"')[5])
539 for l in range(nrows):
541 for k in range(ncols):
542 m = find_token(document.body, '<cell', m)
544 if document.body[m].find('multicolumn') != -1:
545 multicol_cont = int(document.body[m].split('"')[1])
547 if multicol_cont == 2 and (k == 0 or prev_multicolumn == 0):
548 document.body[m] = document.body[m][:5] + document.body[m][21:]
551 prev_multicolumn = multicol_cont
558 def close_begin_deeper(document):
562 i = find_tokens(document.body, ["\\begin_deeper", "\\end_deeper"], i)
567 if document.body[i][:13] == "\\begin_deeper":
574 document.body[-2:-2] = ['\\end_deeper' for i in range(depth)]
577 def long_charstyle_names(document):
580 i = find_token(document.body, "\\begin_inset CharStyle", i)
583 document.body[i] = document.body[i].replace("CharStyle ", "CharStyle CharStyle:")
586 def revert_long_charstyle_names(document):
589 i = find_token(document.body, "\\begin_inset CharStyle", i)
592 document.body[i] = document.body[i].replace("CharStyle CharStyle:", "CharStyle")
596 def axe_show_label(document):
599 i = find_token(document.body, "\\begin_inset CharStyle", i)
602 if document.body[i + 1].find("show_label") != -1:
603 if document.body[i + 1].find("true") != -1:
604 document.body[i + 1] = "status open"
605 del document.body[ i + 2]
607 if document.body[i + 1].find("false") != -1:
608 document.body[i + 1] = "status collapsed"
609 del document.body[ i + 2]
611 document.warning("Malformed LyX document: show_label neither false nor true.")
613 document.warning("Malformed LyX document: show_label missing in CharStyle.")
618 def revert_show_label(document):
621 i = find_token(document.body, "\\begin_inset CharStyle", i)
624 if document.body[i + 1].find("status open") != -1:
625 document.body.insert(i + 1, "show_label true")
627 if document.body[i + 1].find("status collapsed") != -1:
628 document.body.insert(i + 1, "show_label false")
630 document.warning("Malformed LyX document: no legal status line in CharStyle.")
633 def revert_begin_modules(document):
636 i = find_token(document.header, "\\begin_modules", i)
639 j = find_end_of(document.header, i, "\\begin_modules", "\\end_modules")
641 # this should not happen
643 document.header[i : j + 1] = []
645 def convert_flex(document):
646 "Convert CharStyle to Flex"
649 i = find_token(document.body, "\\begin_inset CharStyle", i)
652 document.body[i] = document.body[i].replace('\\begin_inset CharStyle', '\\begin_inset Flex')
654 def revert_flex(document):
655 "Convert Flex to CharStyle"
658 i = find_token(document.body, "\\begin_inset Flex", i)
661 document.body[i] = document.body[i].replace('\\begin_inset Flex', '\\begin_inset CharStyle')
664 # Discard PDF options for hyperref
665 def revert_pdf_options(document):
666 "Revert PDF options for hyperref."
667 # store the PDF options and delete the entries from the Lyx file
675 bookmarksnumbered = ""
677 bookmarksopenlevel = ""
685 i = find_token(document.header, "\\use_hyperref", i)
687 hyperref = get_value(document.header, "\\use_hyperref", i) == 'true'
688 del document.header[i]
689 i = find_token(document.header, "\\pdf_store_options", i)
691 del document.header[i]
692 i = find_token(document.header, "\\pdf_title", 0)
694 title = get_value_string(document.header, '\\pdf_title', 0, 0, True)
695 title = ' pdftitle={' + title + '}'
696 del document.header[i]
697 i = find_token(document.header, "\\pdf_author", 0)
699 author = get_value_string(document.header, '\\pdf_author', 0, 0, True)
701 author = ' pdfauthor={' + author + '}'
703 author = ',\n pdfauthor={' + author + '}'
704 del document.header[i]
705 i = find_token(document.header, "\\pdf_subject", 0)
707 subject = get_value_string(document.header, '\\pdf_subject', 0, 0, True)
708 if title == "" and author == "":
709 subject = ' pdfsubject={' + subject + '}'
711 subject = ',\n pdfsubject={' + subject + '}'
712 del document.header[i]
713 i = find_token(document.header, "\\pdf_keywords", 0)
715 keywords = get_value_string(document.header, '\\pdf_keywords', 0, 0, True)
716 if title == "" and author == "" and subject == "":
717 keywords = ' pdfkeywords={' + keywords + '}'
719 keywords = ',\n pdfkeywords={' + keywords + '}'
720 del document.header[i]
721 i = find_token(document.header, "\\pdf_bookmarks", 0)
723 bookmarks = get_value_string(document.header, '\\pdf_bookmarks', 0)
724 bookmarks = ',\n bookmarks=' + bookmarks
725 del document.header[i]
726 i = find_token(document.header, "\\pdf_bookmarksnumbered", i)
728 bookmarksnumbered = get_value_string(document.header, '\\pdf_bookmarksnumbered', 0)
729 bookmarksnumbered = ',\n bookmarksnumbered=' + bookmarksnumbered
730 del document.header[i]
731 i = find_token(document.header, "\\pdf_bookmarksopen", i)
733 bookmarksopen = get_value_string(document.header, '\\pdf_bookmarksopen', 0)
734 bookmarksopen = ',\n bookmarksopen=' + bookmarksopen
735 del document.header[i]
736 i = find_token(document.header, "\\pdf_bookmarksopenlevel", i)
738 bookmarksopenlevel = get_value_string(document.header, '\\pdf_bookmarksopenlevel', 0, 0, True)
739 bookmarksopenlevel = ',\n bookmarksopenlevel=' + bookmarksopenlevel
740 del document.header[i]
741 i = find_token(document.header, "\\pdf_breaklinks", i)
743 breaklinks = get_value_string(document.header, '\\pdf_breaklinks', 0)
744 breaklinks = ',\n breaklinks=' + breaklinks
745 del document.header[i]
746 i = find_token(document.header, "\\pdf_pdfborder", i)
748 pdfborder = get_value_string(document.header, '\\pdf_pdfborder', 0)
749 if pdfborder == 'true':
750 pdfborder = ',\n pdfborder={0 0 0}'
752 pdfborder = ',\n pdfborder={0 0 1}'
753 del document.header[i]
754 i = find_token(document.header, "\\pdf_colorlinks", i)
756 colorlinks = get_value_string(document.header, '\\pdf_colorlinks', 0)
757 colorlinks = ',\n colorlinks=' + colorlinks
758 del document.header[i]
759 i = find_token(document.header, "\\pdf_backref", i)
761 backref = get_value_string(document.header, '\\pdf_backref', 0)
762 backref = ',\n backref=' + backref
763 del document.header[i]
764 i = find_token(document.header, "\\pdf_pagebackref", i)
766 pagebackref = get_value_string(document.header, '\\pdf_pagebackref', 0)
767 pagebackref = ',\n pagebackref=' + pagebackref
768 del document.header[i]
769 i = find_token(document.header, "\\pdf_pagemode", 0)
771 pagemode = get_value_string(document.header, '\\pdf_pagemode', 0)
772 pagemode = ',\n pdfpagemode=' + pagemode
773 del document.header[i]
774 i = find_token(document.header, "\\pdf_quoted_options", 0)
776 otheroptions = get_value_string(document.header, '\\pdf_quoted_options', 0, 0, True)
777 if title == "" and author == "" and subject == "" and keywords == "":
778 otheroptions = ' ' + otheroptions
780 otheroptions = ',\n ' + otheroptions
781 del document.header[i]
783 # write to the preamble when hyperref was used
785 # preamble write preparations
786 # bookmark numbers are only output when they are turned on
787 if bookmarksopen == ',\n bookmarksopen=true':
788 bookmarksopen = bookmarksopen + bookmarksopenlevel
789 if bookmarks == ',\n bookmarks=true':
790 bookmarks = bookmarks + bookmarksnumbered + bookmarksopen
792 bookmarks = bookmarks
793 # hypersetup is only output when there are things to be set up
794 setupstart = '\\hypersetup{%\n'
796 if otheroptions == "" and title == "" and author == ""\
797 and subject == "" and keywords == "":
801 add_to_preamble(document,
802 ['% Commands inserted by lyx2lyx for PDF properties',
803 '\\usepackage[unicode=true'
822 def remove_inzip_options(document):
823 "Remove inzipName and embed options from the Graphics inset"
826 i = find_token(document.body, "\\begin_inset Graphics", i)
829 j = find_end_of_inset(document.body, i + 1)
832 document.warning("Malformed LyX document: Could not find end of graphics inset.")
833 # If there's a inzip param, just remove that
834 k = find_token(document.body, "\tinzipName", i + 1, j)
837 # embed option must follow the inzipName option
838 del document.body[k+1]
842 def convert_inset_command(document):
845 \begin_inset LatexCommand cmd
847 \begin_inset CommandInset InsetType
852 i = find_token(document.body, "\\begin_inset LatexCommand", i)
855 line = document.body[i]
856 r = re.compile(r'\\begin_inset LatexCommand (.*)$')
860 #this is adapted from factory.cpp
861 if cmdName[0:4].lower() == "cite":
862 insetName = "citation"
863 elif cmdName == "url" or cmdName == "htmlurl":
865 elif cmdName[-3:] == "ref":
867 elif cmdName == "tableofcontents":
869 elif cmdName == "printnomenclature":
870 insetName = "nomencl_print"
871 elif cmdName == "printindex":
872 insetName = "index_print"
875 insertion = ["\\begin_inset CommandInset " + insetName, "LatexCommand " + cmdName]
876 document.body[i : i+1] = insertion
879 def revert_inset_command(document):
882 \begin_inset CommandInset InsetType
885 \begin_inset LatexCommand cmd
886 Some insets may end up being converted to insets earlier versions of LyX
887 will not be able to recognize. Not sure what to do about that.
891 i = find_token(document.body, "\\begin_inset CommandInset", i)
894 nextline = document.body[i+1]
895 r = re.compile(r'LatexCommand\s+(.*)$')
896 m = r.match(nextline)
898 document.warning("Malformed LyX document: Missing LatexCommand in " + document.body[i] + ".")
901 insertion = ["\\begin_inset LatexCommand " + cmdName]
902 document.body[i : i+2] = insertion
905 def convert_wrapfig_options(document):
906 "Convert optional options for wrap floats (wrapfig)."
907 # adds the tokens "lines", "placement", and "overhang"
910 i = find_token(document.body, "\\begin_inset Wrap figure", i)
913 document.body.insert(i + 1, "lines 0")
914 j = find_token(document.body, "placement", i)
915 # placement can be already set or not; if not, set it
917 document.body.insert(i + 3, "overhang 0col%")
919 document.body.insert(i + 2, "placement o")
920 document.body.insert(i + 3, "overhang 0col%")
924 def revert_wrapfig_options(document):
925 "Revert optional options for wrap floats (wrapfig)."
928 i = find_token(document.body, "\\begin_inset Wrap figure", i)
931 j = find_end_of_inset(document.body, i)
933 document.warning("Can't find end of Wrap inset at line " + str(i))
936 k = find_default_layout(document, i, j)
938 document.warning("Can't find default layout for Wrap figure!")
941 # Options should be between i and k now
942 l = find_token(document.body, "lines", i, k)
944 document.warning("Can't find lines option for Wrap figure!")
947 m = find_token(document.body, "overhang", i + 1, k)
949 document.warning("Malformed LyX document: Couldn't find overhang parameter of wrap float!")
952 # Do these in reverse order
958 def convert_latexcommand_index(document):
959 "Convert from LatexCommand form to collapsable form."
961 r1 = re.compile('name "(.*)"')
963 i = find_token(document.body, "\\begin_inset CommandInset index", i)
966 if document.body[i + 1] != "LatexCommand index": # Might also be index_print
968 m = r1.match(document.body[i + 2])
970 document.warning("Unable to match: " + document.body[i+2])
973 fullcontent = m.group(1)
974 #document.warning(fullcontent)
975 document.body[i:i + 3] = ["\\begin_inset Index",
977 "\\begin_layout Standard"]
979 # We are now on the blank line preceding "\end_inset"
980 # We will write the content here, into the inset.
982 linelist = latex2lyx(fullcontent)
983 document.body[i+1:i+1] = linelist
986 document.body.insert(i + 1, "\\end_layout")
990 def revert_latexcommand_index(document):
991 "Revert from collapsable form to LatexCommand form."
994 i = find_token(document.body, "\\begin_inset Index", i)
997 j = find_end_of_inset(document.body, i + 1)
1000 del document.body[j - 1]
1001 del document.body[j - 2] # \end_layout
1002 document.body[i] = "\\begin_inset CommandInset index"
1003 document.body[i + 1] = "LatexCommand index"
1004 # clean up multiline stuff
1007 for k in range(i + 3, j - 2):
1008 line = document.body[k]
1009 if line.startswith("\\begin_inset ERT"):
1010 ert_end = find_end_of_inset(document.body, k + 1)
1012 if line.startswith("\\begin_inset Formula"):
1014 if line.startswith("\\begin_layout Standard"):
1016 if line.startswith("\\begin_layout Plain Layout"):
1018 if line.startswith("\\end_layout"):
1020 if line.startswith("\\end_inset"):
1022 if line.startswith("status collapsed"):
1024 if line.startswith("status open"):
1026 # a lossless reversion is not possible
1027 # try at least to handle some common insets and settings
1028 # do not replace inside ERTs
1030 # Do the LyX text --> LaTeX conversion
1031 for rep in replacements:
1032 line = line.replace(rep[1], rep[0])
1033 line = line.replace(r'\backslash', r'\textbackslash{}')
1034 line = line.replace(r'\series bold', r'\bfseries{}').replace(r'\series default', r'\mdseries{}')
1035 line = line.replace(r'\shape italic', r'\itshape{}').replace(r'\shape smallcaps', r'\scshape{}')
1036 line = line.replace(r'\shape slanted', r'\slshape{}').replace(r'\shape default', r'\upshape{}')
1037 line = line.replace(r'\emph on', r'\em{}').replace(r'\emph default', r'\em{}')
1038 line = line.replace(r'\noun on', r'\scshape{}').replace(r'\noun default', r'\upshape{}')
1039 line = line.replace(r'\bar under', r'\underbar{').replace(r'\bar default', r'}')
1040 line = line.replace(r'\family sans', r'\sffamily{}').replace(r'\family default', r'\normalfont{}')
1041 line = line.replace(r'\family typewriter', r'\ttfamily{}').replace(r'\family roman', r'\rmfamily{}')
1042 line = line.replace(r'\InsetSpace ', r'').replace(r'\SpecialChar ', r'')
1044 line = line.replace(r'\backslash', r'\\')
1045 content = content + line;
1046 document.body[i + 3] = "name " + '"' + content + '"'
1047 for k in range(i + 4, j - 2):
1048 del document.body[i + 4]
1049 document.body.insert(i + 4, "")
1050 del document.body[i + 2] # \begin_layout standard
1054 def revert_wraptable(document):
1055 "Revert wrap table to wrap figure."
1058 i = find_token(document.body, "\\begin_inset Wrap table", i)
1061 document.body[i] = document.body[i].replace('\\begin_inset Wrap table', '\\begin_inset Wrap figure')
1065 def revert_vietnamese(document):
1066 "Set language Vietnamese to English"
1067 # Set document language from Vietnamese to English
1069 if document.language == "vietnamese":
1070 document.language = "english"
1071 i = find_token(document.header, "\\language", 0)
1073 document.header[i] = "\\language english"
1076 j = find_token(document.body, "\\lang vietnamese", j)
1079 document.body[j] = document.body[j].replace("\\lang vietnamese", "\\lang english")
1083 def convert_japanese_cjk(document):
1084 "Set language japanese to japanese-cjk"
1085 # Set document language from japanese-plain to japanese
1087 if document.language == "japanese":
1088 document.language = "japanese-cjk"
1089 i = find_token(document.header, "\\language", 0)
1091 document.header[i] = "\\language japanese-cjk"
1094 j = find_token(document.body, "\\lang japanese", j)
1097 document.body[j] = document.body[j].replace("\\lang japanese", "\\lang japanese-cjk")
1101 def revert_japanese(document):
1102 "Set language japanese-plain to japanese"
1103 # Set document language from japanese-plain to japanese
1105 if document.language == "japanese-plain":
1106 document.language = "japanese"
1107 i = find_token(document.header, "\\language", 0)
1109 document.header[i] = "\\language japanese"
1112 j = find_token(document.body, "\\lang japanese-plain", j)
1115 document.body[j] = document.body[j].replace("\\lang japanese-plain", "\\lang japanese")
1119 def revert_japanese_cjk(document):
1120 "Set language japanese-cjk to japanese"
1121 # Set document language from japanese-plain to japanese
1123 if document.language == "japanese-cjk":
1124 document.language = "japanese"
1125 i = find_token(document.header, "\\language", 0)
1127 document.header[i] = "\\language japanese"
1130 j = find_token(document.body, "\\lang japanese-cjk", j)
1133 document.body[j] = document.body[j].replace("\\lang japanese-cjk", "\\lang japanese")
1137 def revert_japanese_encoding(document):
1138 "Set input encoding form EUC-JP-plain to EUC-JP etc."
1139 # Set input encoding form EUC-JP-plain to EUC-JP etc.
1141 i = find_token(document.header, "\\inputencoding EUC-JP-plain", 0)
1143 document.header[i] = "\\inputencoding EUC-JP"
1145 j = find_token(document.header, "\\inputencoding JIS-plain", 0)
1147 document.header[j] = "\\inputencoding JIS"
1149 k = find_token(document.header, "\\inputencoding SJIS-plain", 0)
1150 if k != -1: # convert to UTF8 since there is currently no SJIS encoding
1151 document.header[k] = "\\inputencoding UTF8"
1154 def revert_inset_info(document):
1155 'Replace info inset with its content'
1158 i = find_token(document.body, '\\begin_inset Info', i)
1161 j = find_end_of_inset(document.body, i + 1)
1164 document.warning("Malformed LyX document: Could not find end of Info inset.")
1167 for k in range(i, j+1):
1168 if document.body[k].startswith("arg"):
1169 arg = document.body[k][3:].strip().strip('"')
1170 if document.body[k].startswith("type"):
1171 type = document.body[k][4:].strip().strip('"')
1172 # I think there is a newline after \\end_inset, which should be removed.
1173 if document.body[j + 1].strip() == "":
1174 document.body[i : (j + 2)] = [type + ':' + arg]
1176 document.body[i : (j + 1)] = [type + ':' + arg]
1179 def convert_pdf_options(document):
1180 # Set the pdfusetitle tag, delete the pdf_store_options,
1181 # set quotes for bookmarksopenlevel"
1182 has_hr = get_value(document.header, "\\use_hyperref", 0, default = "0")
1184 k = find_token(document.header, "\\use_hyperref", 0)
1185 document.header.insert(k + 1, "\\pdf_pdfusetitle true")
1186 k = find_token(document.header, "\\pdf_store_options", 0)
1188 del document.header[k]
1189 i = find_token(document.header, "\\pdf_bookmarksopenlevel", k)
1191 document.header[i] = document.header[i].replace('"', '')
1194 def revert_pdf_options_2(document):
1195 # reset the pdfusetitle tag, set quotes for bookmarksopenlevel"
1196 k = find_token(document.header, "\\use_hyperref", 0)
1197 i = find_token(document.header, "\\pdf_pdfusetitle", k)
1199 del document.header[i]
1200 i = find_token(document.header, "\\pdf_bookmarksopenlevel", k)
1202 values = document.header[i].split()
1203 values[1] = ' "' + values[1] + '"'
1204 document.header[i] = ''.join(values)
1207 def convert_htmlurl(document):
1208 'Convert "htmlurl" to "href" insets for docbook'
1209 if document.backend != "docbook":
1213 i = find_token(document.body, "\\begin_inset CommandInset url", i)
1216 document.body[i] = "\\begin_inset CommandInset href"
1217 document.body[i + 1] = "LatexCommand href"
1221 def convert_url(document):
1222 'Convert url insets to url charstyles'
1223 if document.backend == "docbook":
1227 i = find_token(document.body, "\\begin_inset CommandInset url", i)
1230 n = find_token(document.body, "name", i)
1232 # place the URL name in typewriter before the new URL insert
1233 # grab the name 'bla' from the e.g. the line 'name "bla"',
1234 # therefore start with the 6th character
1235 name = document.body[n][6:-1]
1236 newname = [name + " "]
1237 document.body[i:i] = newname
1239 j = find_token(document.body, "target", i)
1241 document.warning("Malformed LyX document: Can't find target for url inset")
1244 target = document.body[j][8:-1]
1245 k = find_token(document.body, "\\end_inset", j)
1247 document.warning("Malformed LyX document: Can't find end of url inset")
1250 newstuff = ["\\begin_inset Flex URL",
1251 "status collapsed", "",
1252 "\\begin_layout Standard",
1257 document.body[i:k] = newstuff
1260 def convert_ams_classes(document):
1261 tc = document.textclass
1262 if (tc != "amsart" and tc != "amsart-plain" and
1263 tc != "amsart-seq" and tc != "amsbook"):
1265 if tc == "amsart-plain":
1266 document.textclass = "amsart"
1267 document.set_textclass()
1268 document.add_module("Theorems (Starred)")
1270 if tc == "amsart-seq":
1271 document.textclass = "amsart"
1272 document.set_textclass()
1273 document.add_module("Theorems (AMS)")
1275 #Now we want to see if any of the environments in the extended theorems
1276 #module were used in this document. If so, we'll add that module, too.
1277 layouts = ["Criterion", "Algorithm", "Axiom", "Condition", "Note", \
1278 "Notation", "Summary", "Acknowledgement", "Conclusion", "Fact", \
1281 r = re.compile(r'^\\begin_layout (.*?)\*?\s*$')
1284 i = find_token(document.body, "\\begin_layout", i)
1287 m = r.match(document.body[i])
1289 document.warning("Weirdly formed \\begin_layout at line %d of body!" % i)
1293 if layouts.count(m) != 0:
1294 document.add_module("Theorems (AMS-Extended)")
1298 def revert_href(document):
1299 'Reverts hyperlink insets (href) to url insets (url)'
1302 i = find_token(document.body, "\\begin_inset CommandInset href", i)
1305 document.body[i : i + 2] = \
1306 ["\\begin_inset CommandInset url", "LatexCommand url"]
1309 def revert_url(document):
1310 'Reverts Flex URL insets to old-style URL insets'
1313 i = find_token(document.body, "\\begin_inset Flex URL", i)
1316 j = find_end_of_inset(document.body, i)
1318 document.warning("Can't find end of inset in revert_url!")
1320 k = find_default_layout(document, i, j)
1322 document.warning("Can't find default layout in revert_url!")
1325 l = find_end_of(document.body, k, "\\begin_layout", "\\end_layout")
1326 if l == -1 or l >= j:
1327 document.warning("Can't find end of default layout in revert_url!")
1330 # OK, so the inset's data is between lines k and l.
1331 data = " ".join(document.body[k+1:l])
1333 newinset = ["\\begin_inset LatexCommand url", "target \"" + data + "\"",\
1335 document.body[i:j+1] = newinset
1336 i = i + len(newinset)
1339 def convert_include(document):
1340 'Converts include insets to new format.'
1342 r = re.compile(r'\\begin_inset Include\s+\\([^{]+){([^}]*)}(?:\[(.*)\])?')
1344 i = find_token(document.body, "\\begin_inset Include", i)
1347 line = document.body[i]
1348 previewline = document.body[i + 1]
1351 document.warning("Unable to match line " + str(i) + " of body!")
1357 insertion = ["\\begin_inset CommandInset include",
1358 "LatexCommand " + cmd, previewline,
1359 "filename \"" + fn + "\""]
1362 insertion.append("lstparams " + '"' + opt + '"')
1364 document.body[i : i + 2] = insertion
1368 def revert_include(document):
1369 'Reverts include insets to old format.'
1371 r0 = re.compile('preview.*')
1372 r1 = re.compile('LatexCommand (.+)')
1373 r2 = re.compile('filename "(.+)"')
1374 r3 = re.compile('lstparams "(.*)"')
1376 i = find_token(document.body, "\\begin_inset CommandInset include", i)
1380 if r0.match(document.body[nextline]):
1381 previewline = document.body[nextline]
1385 m = r1.match(document.body[nextline])
1387 document.warning("Malformed LyX document: No LatexCommand line for `" +
1388 document.body[i] + "' on line " + str(i) + ".")
1393 m = r2.match(document.body[nextline])
1395 document.warning("Malformed LyX document: No filename line for `" + \
1396 document.body[i] + "' on line " + str(i) + ".")
1402 if (cmd == "lstinputlisting"):
1403 m = r3.match(document.body[nextline])
1405 options = m.group(1)
1408 newline = "\\begin_inset Include \\" + cmd + "{" + fn + "}"
1410 newline += ("[" + options + "]")
1411 insertion = [newline]
1412 if previewline != "":
1413 insertion.append(previewline)
1414 document.body[i : nextline] = insertion
1418 def revert_albanian(document):
1419 "Set language Albanian to English"
1421 if document.language == "albanian":
1422 document.language = "english"
1423 i = find_token(document.header, "\\language", 0)
1425 document.header[i] = "\\language english"
1428 j = find_token(document.body, "\\lang albanian", j)
1431 document.body[j] = document.body[j].replace("\\lang albanian", "\\lang english")
1435 def revert_lowersorbian(document):
1436 "Set language lower Sorbian to English"
1438 if document.language == "lowersorbian":
1439 document.language = "english"
1440 i = find_token(document.header, "\\language", 0)
1442 document.header[i] = "\\language english"
1445 j = find_token(document.body, "\\lang lowersorbian", j)
1448 document.body[j] = document.body[j].replace("\\lang lowersorbian", "\\lang english")
1452 def revert_uppersorbian(document):
1453 "Set language uppersorbian to usorbian as this was used in LyX 1.5"
1455 if document.language == "uppersorbian":
1456 document.language = "usorbian"
1457 i = find_token(document.header, "\\language", 0)
1459 document.header[i] = "\\language usorbian"
1462 j = find_token(document.body, "\\lang uppersorbian", j)
1465 document.body[j] = document.body[j].replace("\\lang uppersorbian", "\\lang usorbian")
1469 def convert_usorbian(document):
1470 "Set language usorbian to uppersorbian"
1472 if document.language == "usorbian":
1473 document.language = "uppersorbian"
1474 i = find_token(document.header, "\\language", 0)
1476 document.header[i] = "\\language uppersorbian"
1479 j = find_token(document.body, "\\lang usorbian", j)
1482 document.body[j] = document.body[j].replace("\\lang usorbian", "\\lang uppersorbian")
1486 def revert_macro_optional_params(document):
1487 "Convert macro definitions with optional parameters into ERTs"
1488 # Stub to convert macro definitions with one or more optional parameters
1489 # into uninterpreted ERT insets
1492 def revert_hyperlinktype(document):
1493 'Reverts hyperlink type'
1497 i = find_token(document.body, "target", i)
1500 j = find_token(document.body, "type", i)
1504 del document.body[j]
1508 def revert_pagebreak(document):
1509 'Reverts pagebreak to ERT'
1512 i = find_token(document.body, "\\pagebreak", i)
1515 document.body[i] = '\\begin_inset ERT\nstatus collapsed\n\n' \
1516 '\\begin_layout Standard\n\n\n\\backslash\n' \
1517 'pagebreak{}\n\\end_layout\n\n\\end_inset\n\n'
1521 def revert_linebreak(document):
1522 'Reverts linebreak to ERT'
1525 i = find_token(document.body, "\\linebreak", i)
1528 document.body[i] = '\\begin_inset ERT\nstatus collapsed\n\n' \
1529 '\\begin_layout Standard\n\n\n\\backslash\n' \
1530 'linebreak{}\n\\end_layout\n\n\\end_inset\n\n'
1534 def revert_latin(document):
1535 "Set language Latin to English"
1537 if document.language == "latin":
1538 document.language = "english"
1539 i = find_token(document.header, "\\language", 0)
1541 document.header[i] = "\\language english"
1544 j = find_token(document.body, "\\lang latin", j)
1547 document.body[j] = document.body[j].replace("\\lang latin", "\\lang english")
1551 def revert_samin(document):
1552 "Set language North Sami to English"
1554 if document.language == "samin":
1555 document.language = "english"
1556 i = find_token(document.header, "\\language", 0)
1558 document.header[i] = "\\language english"
1561 j = find_token(document.body, "\\lang samin", j)
1564 document.body[j] = document.body[j].replace("\\lang samin", "\\lang english")
1568 def convert_serbocroatian(document):
1569 "Set language Serbocroatian to Croatian as this was really Croatian in LyX 1.5"
1571 if document.language == "serbocroatian":
1572 document.language = "croatian"
1573 i = find_token(document.header, "\\language", 0)
1575 document.header[i] = "\\language croatian"
1578 j = find_token(document.body, "\\lang serbocroatian", j)
1581 document.body[j] = document.body[j].replace("\\lang serbocroatian", "\\lang croatian")
1585 def convert_framed_notes(document):
1586 "Convert framed notes to boxes. "
1589 i = find_tokens(document.body, ["\\begin_inset Note Framed", "\\begin_inset Note Shaded"], i)
1592 subst = [document.body[i].replace("\\begin_inset Note", "\\begin_inset Box"),
1601 'height_special "totalheight"']
1602 document.body[i:i+1] = subst
1606 def convert_module_names(document):
1607 modulemap = { 'Braille' : 'braille', 'Endnote' : 'endnotes', 'Foot to End' : 'foottoend',\
1608 'Hanging' : 'hanging', 'Linguistics' : 'linguistics', 'Logical Markup' : 'logicalmkup', \
1609 'Theorems (AMS-Extended)' : 'theorems-ams-extended', 'Theorems (AMS)' : 'theorems-ams', \
1610 'Theorems (Order By Chapter)' : 'theorems-chap', 'Theorems (Order By Section)' : 'theorems-sec', \
1611 'Theorems (Starred)' : 'theorems-starred', 'Theorems' : 'theorems-std' }
1612 modlist = document.get_module_list()
1613 if len(modlist) == 0:
1617 if modulemap.has_key(mod):
1618 newmodlist.append(modulemap[mod])
1620 document.warning("Can't find module %s in the module map!" % mod)
1621 newmodlist.append(mod)
1622 document.set_module_list(newmodlist)
1625 def revert_module_names(document):
1626 modulemap = { 'braille' : 'Braille', 'endnotes' : 'Endnote', 'foottoend' : 'Foot to End',\
1627 'hanging' : 'Hanging', 'linguistics' : 'Linguistics', 'logicalmkup' : 'Logical Markup', \
1628 'theorems-ams-extended' : 'Theorems (AMS-Extended)', 'theorems-ams' : 'Theorems (AMS)', \
1629 'theorems-chap' : 'Theorems (Order By Chapter)', 'theorems-sec' : 'Theorems (Order By Section)', \
1630 'theorems-starred' : 'Theorems (Starred)', 'theorems-std' : 'Theorems'}
1631 modlist = document.get_module_list()
1632 if len(modlist) == 0:
1636 if modulemap.has_key(mod):
1637 newmodlist.append(modulemap[mod])
1639 document.warning("Can't find module %s in the module map!" % mod)
1640 newmodlist.append(mod)
1641 document.set_module_list(newmodlist)
1644 def revert_colsep(document):
1645 i = find_token(document.header, "\\columnsep", 0)
1648 colsepline = document.header[i]
1649 r = re.compile(r'\\columnsep (.*)')
1650 m = r.match(colsepline)
1652 document.warning("Malformed column separation line!")
1655 del document.header[i]
1656 #it seems to be safe to add the package even if it is already used
1657 pretext = ["\\usepackage{geometry}", "\\geometry{columnsep=" + colsep + "}"]
1659 add_to_preamble(document, pretext)
1662 def revert_framed_notes(document):
1663 "Revert framed boxes to notes. "
1666 i = find_tokens(document.body, ["\\begin_inset Box Framed", "\\begin_inset Box Shaded"], i)
1670 j = find_end_of_inset(document.body, i + 1)
1673 document.warning("Malformed LyX document: Could not find end of Box inset.")
1674 k = find_token(document.body, "status", i + 1, j)
1676 document.warning("Malformed LyX document: Missing `status' tag in Box inset.")
1678 status = document.body[k]
1679 l = find_default_layout(document, i + 1, j)
1681 document.warning("Malformed LyX document: Missing `\\begin_layout' in Box inset.")
1683 m = find_token(document.body, "\\end_layout", i + 1, j)
1685 document.warning("Malformed LyX document: Missing `\\end_layout' in Box inset.")
1687 ibox = find_token(document.body, "has_inner_box 1", i + 1, k)
1688 pbox = find_token(document.body, "use_parbox 1", i + 1, k)
1689 if ibox == -1 and pbox == -1:
1690 document.body[i] = document.body[i].replace("\\begin_inset Box", "\\begin_inset Note")
1691 del document.body[i+1:k]
1693 document.body[i] = document.body[i].replace("\\begin_inset Box Shaded", "\\begin_inset Box Frameless")
1694 subst1 = [document.body[l],
1695 "\\begin_inset Note Shaded",
1697 '\\begin_layout Standard']
1698 document.body[l:l + 1] = subst1
1699 subst2 = [document.body[m], "\\end_layout", "\\end_inset"]
1700 document.body[m:m + 1] = subst2
1704 def revert_slash(document):
1705 'Revert \\SpecialChar \\slash{} to ERT'
1706 r = re.compile(r'\\SpecialChar \\slash{}')
1708 while i < len(document.body):
1709 m = r.match(document.body[i])
1711 subst = ['\\begin_inset ERT',
1712 'status collapsed', '',
1713 '\\begin_layout Standard',
1714 '', '', '\\backslash',
1718 document.body[i: i+1] = subst
1724 def revert_nobreakdash(document):
1725 'Revert \\SpecialChar \\nobreakdash- to ERT'
1727 while i < len(document.body):
1728 line = document.body[i]
1729 r = re.compile(r'\\SpecialChar \\nobreakdash-')
1732 subst = ['\\begin_inset ERT',
1733 'status collapsed', '',
1734 '\\begin_layout Standard', '', '',
1739 document.body[i:i+1] = subst
1741 j = find_token(document.header, "\\use_amsmath", 0)
1743 document.warning("Malformed LyX document: Missing '\\use_amsmath'.")
1745 document.header[j] = "\\use_amsmath 2"
1750 #Returns number of lines added/removed
1751 def revert_nocite_key(body, start, end):
1752 'key "..." -> \nocite{...}'
1753 r = re.compile(r'^key "(.*)"')
1757 m = r.match(body[i])
1759 body[i:i+1] = ["\\backslash", "nocite{" + m.group(1) + "}"]
1760 j += 1 # because we added a line
1761 i += 2 # skip that line
1764 j -= 1 # because we deleted a line
1765 # no need to change i, since it now points to the next line
1769 def revert_nocite(document):
1770 "Revert LatexCommand nocite to ERT"
1773 i = find_token(document.body, "\\begin_inset CommandInset citation", i)
1776 if (document.body[i+1] != "LatexCommand nocite"):
1777 # note that we already incremented i
1780 insetEnd = find_end_of_inset(document.body, i)
1782 #this should not happen
1783 document.warning("End of CommandInset citation not found in revert_nocite!")
1786 paramLocation = i + 2 #start of the inset's parameters
1788 document.body[i:i+2] = \
1789 ["\\begin_inset ERT", "status collapsed", "", "\\begin_layout Standard"]
1790 # that added two lines
1793 #print insetEnd, document.body[i: insetEnd + 1]
1794 insetEnd += revert_nocite_key(document.body, paramLocation, insetEnd)
1795 #print insetEnd, document.body[i: insetEnd + 1]
1796 document.body.insert(insetEnd, "\\end_layout")
1797 document.body.insert(insetEnd + 1, "")
1801 def revert_btprintall(document):
1802 "Revert (non-bibtopic) btPrintAll option to ERT \nocite{*}"
1803 i = find_token(document.header, '\\use_bibtopic', 0)
1805 document.warning("Malformed lyx document: Missing '\\use_bibtopic'.")
1807 if get_value(document.header, '\\use_bibtopic', 0) == "false":
1809 while i < len(document.body):
1810 i = find_token(document.body, "\\begin_inset CommandInset bibtex", i)
1813 j = find_end_of_inset(document.body, i + 1)
1815 #this should not happen
1816 document.warning("End of CommandInset bibtex not found in revert_btprintall!")
1817 j = len(document.body)
1818 # this range isn't really right, but it should be OK, since we shouldn't
1819 # see more than one matching line in each inset
1821 for k in range(i, j):
1822 if (document.body[k] == 'btprint "btPrintAll"'):
1823 del document.body[k]
1824 subst = ["\\begin_inset ERT",
1825 "status collapsed", "",
1826 "\\begin_layout Standard", "",
1831 document.body[i:i] = subst
1832 addlines = addedlines + len(subst) - 1
1836 def revert_bahasam(document):
1837 "Set language Bahasa Malaysia to Bahasa Indonesia"
1839 if document.language == "bahasam":
1840 document.language = "bahasa"
1841 i = find_token(document.header, "\\language", 0)
1843 document.header[i] = "\\language bahasa"
1846 j = find_token(document.body, "\\lang bahasam", j)
1849 document.body[j] = document.body[j].replace("\\lang bahasam", "\\lang bahasa")
1853 def revert_interlingua(document):
1854 "Set language Interlingua to English"
1856 if document.language == "interlingua":
1857 document.language = "english"
1858 i = find_token(document.header, "\\language", 0)
1860 document.header[i] = "\\language english"
1863 j = find_token(document.body, "\\lang interlingua", j)
1866 document.body[j] = document.body[j].replace("\\lang interlingua", "\\lang english")
1870 def revert_serbianlatin(document):
1871 "Set language Serbian-Latin to Croatian"
1873 if document.language == "serbian-latin":
1874 document.language = "croatian"
1875 i = find_token(document.header, "\\language", 0)
1877 document.header[i] = "\\language croatian"
1880 j = find_token(document.body, "\\lang serbian-latin", j)
1883 document.body[j] = document.body[j].replace("\\lang serbian-latin", "\\lang croatian")
1887 def revert_rotfloat(document):
1888 " Revert sideways custom floats. "
1891 # whitespace intended (exclude \\begin_inset FloatList)
1892 i = find_token(document.body, "\\begin_inset Float ", i)
1895 line = document.body[i]
1896 r = re.compile(r'\\begin_inset Float (.*)$')
1899 document.warning("Unable to match line " + str(i) + " of body!")
1902 floattype = m.group(1)
1903 if floattype == "figure" or floattype == "table":
1906 j = find_end_of_inset(document.body, i)
1908 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_rotfloat.")
1912 if get_value(document.body, 'sideways', i, j) == "false":
1915 l = find_default_layout(document, i + 1, j)
1917 document.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
1919 subst = ['\\begin_layout Standard',
1920 '\\begin_inset ERT',
1921 'status collapsed', '',
1922 '\\begin_layout Standard', '', '',
1924 'end{sideways' + floattype + '}',
1925 '\\end_layout', '', '\\end_inset']
1926 document.body[j : j+1] = subst
1927 addedLines = len(subst) - 1
1928 del document.body[i+1 : l]
1929 addedLines -= (l-1) - (i+1)
1930 subst = ['\\begin_inset ERT', 'status collapsed', '',
1931 '\\begin_layout Standard', '', '', '\\backslash',
1932 'begin{sideways' + floattype + '}',
1933 '\\end_layout', '', '\\end_inset', '',
1935 document.body[i : i+1] = subst
1936 addedLines += len(subst) - 1
1937 if floattype == "algorithm":
1938 add_to_preamble(document,
1939 ['% Commands inserted by lyx2lyx for sideways algorithm float',
1940 '\\usepackage{rotfloat}',
1941 '\\floatstyle{ruled}',
1942 '\\newfloat{algorithm}{tbp}{loa}',
1943 '\\floatname{algorithm}{Algorithm}'])
1945 document.warning("Cannot create preamble definition for custom float" + floattype + ".")
1949 def revert_widesideways(document):
1950 " Revert wide sideways floats. "
1953 # whitespace intended (exclude \\begin_inset FloatList)
1954 i = find_token(document.body, '\\begin_inset Float ', i)
1957 line = document.body[i]
1958 r = re.compile(r'\\begin_inset Float (.*)$')
1961 document.warning("Unable to match line " + str(i) + " of body!")
1964 floattype = m.group(1)
1965 if floattype != "figure" and floattype != "table":
1968 j = find_end_of_inset(document.body, i)
1970 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_widesideways.")
1973 if get_value(document.body, 'sideways', i, j) == "false" or \
1974 get_value(document.body, 'wide', i, j) == "false":
1977 l = find_default_layout(document, i + 1, j)
1979 document.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
1981 subst = ['\\begin_layout Standard', '\\begin_inset ERT',
1982 'status collapsed', '',
1983 '\\begin_layout Standard', '', '', '\\backslash',
1984 'end{sideways' + floattype + '*}',
1985 '\\end_layout', '', '\\end_inset']
1986 document.body[j : j+1] = subst
1987 addedLines = len(subst) - 1
1988 del document.body[i+1:l-1]
1989 addedLines -= (l-1) - (i+1)
1990 subst = ['\\begin_inset ERT', 'status collapsed', '',
1991 '\\begin_layout Standard', '', '', '\\backslash',
1992 'begin{sideways' + floattype + '*}', '\\end_layout', '',
1993 '\\end_inset', '', '\\end_layout', '']
1994 document.body[i : i+1] = subst
1995 addedLines += len(subst) - 1
1996 add_to_preamble(document, ['\\usepackage{rotfloat}\n'])
2000 def revert_inset_embedding(document, type):
2001 ' Remove embed tag from certain type of insets'
2004 i = find_token(document.body, "\\begin_inset %s" % type, i)
2007 j = find_end_of_inset(document.body, i)
2009 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_inset_embedding.")
2012 k = find_token(document.body, "\tembed", i, j)
2014 k = find_token(document.body, "embed", i, j)
2016 del document.body[k]
2020 def revert_external_embedding(document):
2021 ' Remove embed tag from external inset '
2022 revert_inset_embedding(document, 'External')
2025 def convert_subfig(document):
2026 " Convert subfigures to subfloats. "
2029 i = find_token(document.body, '\\begin_inset Graphics', i)
2032 endInset = find_end_of_inset(document.body, i)
2034 document.warning("Malformed lyx document: Missing '\\end_inset' in convert_subfig.")
2037 k = find_token(document.body, '\tsubcaption', i, endInset)
2041 l = find_token(document.body, '\tsubcaptionText', i, endInset)
2043 document.warning("Malformed lyx document: Can't find subcaptionText!")
2046 caption = document.body[l][16:].strip('"')
2047 del document.body[l]
2048 del document.body[k]
2050 subst = ['\\begin_inset Float figure', 'wide false', 'sideways false',
2051 'status open', '', '\\begin_layout Plain Layout', '\\begin_inset Caption',
2052 '', '\\begin_layout Plain Layout'] + latex2lyx(caption) + \
2053 [ '\\end_layout', '', '\\end_inset', '',
2054 '\\end_layout', '', '\\begin_layout Plain Layout']
2055 document.body[i : i] = subst
2056 addedLines += len(subst)
2057 endInset += addedLines
2058 subst = ['', '\\end_inset', '', '\\end_layout']
2059 document.body[endInset : endInset] = subst
2060 addedLines += len(subst)
2064 def revert_subfig(document):
2065 " Revert subfloats. "
2068 # whitespace intended (exclude \\begin_inset FloatList)
2069 i = find_tokens(document.body, ['\\begin_inset Float ', '\\begin_inset Wrap'], i)
2075 j = find_end_of_inset(document.body, i)
2077 document.warning("Malformed lyx document: Missing '\\end_inset' (float) at line " + str(i + len(document.header)) + ".\n\t" + document.body[i])
2078 # document.warning(document.body[i-1] + "\n" + document.body[i+1])
2080 continue # this will get us back to the outer loop, since j == -1
2081 # look for embedded float (= subfloat)
2082 # whitespace intended (exclude \\begin_inset FloatList)
2083 k = find_token(document.body, '\\begin_inset Float ', i + 1, j)
2086 l = find_end_of_inset(document.body, k)
2088 document.warning("Malformed lyx document: Missing '\\end_inset' (embedded float).")
2091 continue # escape to the outer loop
2092 m = find_default_layout(document, k + 1, l)
2094 cap = find_token(document.body, '\\begin_inset Caption', k + 1, l)
2099 capend = find_end_of_inset(document.body, cap)
2101 document.warning("Malformed lyx document: Missing '\\end_inset' (caption).")
2105 lbl = find_token(document.body, '\\begin_inset CommandInset label', cap, capend)
2107 lblend = find_end_of_inset(document.body, lbl + 1)
2109 document.warning("Malformed lyx document: Missing '\\end_inset' (label).")
2111 for line in document.body[lbl:lblend + 1]:
2112 if line.startswith('name '):
2113 label = line.split()[1].strip('"')
2120 opt = find_token(document.body, '\\begin_inset OptArg', cap, capend)
2122 optend = find_end_of_inset(document.body, opt)
2124 document.warning("Malformed lyx document: Missing '\\end_inset' (OptArg).")
2126 optc = find_default_layout(document, opt, optend)
2128 document.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
2130 optcend = find_end_of(document.body, optc, "\\begin_layout", "\\end_layout")
2131 for line in document.body[optc:optcend]:
2132 if not line.startswith('\\'):
2133 shortcap += line.strip()
2137 for line in document.body[cap:capend]:
2138 if line in document.body[lbl:lblend]:
2140 elif line in document.body[opt:optend]:
2142 elif not line.startswith('\\'):
2143 caption += line.strip()
2145 caption += "\\backslash\nlabel{" + label + "}"
2146 subst = '\\begin_layout Plain Layout\n\\begin_inset ERT\nstatus collapsed\n\n' \
2147 '\\begin_layout Plain Layout\n\n}\n\\end_layout\n\n\\end_inset\n\n' \
2148 '\\end_layout\n\n\\begin_layout Plain Layout\n'
2149 subst = subst.split('\n')
2150 document.body[l : l+1] = subst
2151 addedLines = len(subst) - 1
2152 # this is before l and so is unchanged by the multiline insertion
2154 del document.body[cap:capend+1]
2155 addedLines -= (capend + 1 - cap)
2156 del document.body[k+1:m-1]
2157 addedLines -= (m - 1 - (k + 1))
2158 insertion = '\\begin_inset ERT\nstatus collapsed\n\n' \
2159 '\\begin_layout Plain Layout\n\n\\backslash\n' \
2161 if len(shortcap) > 0:
2162 insertion = insertion + "[" + shortcap + "]"
2163 if len(caption) > 0:
2164 insertion = insertion + "[" + caption + "]"
2165 insertion = insertion + '{%\n\\end_layout\n\n\\end_inset\n\n\\end_layout\n'
2166 insertion = insertion.split('\n')
2167 document.body[k : k + 1] = insertion
2168 addedLines += len(insertion) - 1
2169 add_to_preamble(document, ['\\usepackage{subfig}\n'])
2173 def revert_wrapplacement(document):
2174 " Revert placement options wrap floats (wrapfig). "
2177 i = find_token(document.body, "\\begin_inset Wrap figure", i)
2180 e = find_end_of_inset(document.body, i)
2181 j = find_token(document.body, "placement", i + 1, e)
2183 document.warning("Malformed LyX document: Couldn't find placement parameter of wrap float.")
2186 r = re.compile("placement (o|i|l|r)")
2187 m = r.match(document.body[j])
2189 document.warning("Malformed LyX document: Placement option isn't O|I|R|L!")
2190 document.body[j] = "placement " + m.group(1).lower()
2194 def remove_extra_embedded_files(document):
2195 " Remove \extra_embedded_files from buffer params "
2196 i = find_token(document.header, '\\extra_embedded_files', 0)
2199 document.header.pop(i)
2202 def convert_spaceinset(document):
2203 " Convert '\\InsetSpace foo' to '\\begin_inset Space foo\n\\end_inset' "
2205 while i < len(document.body):
2206 m = re.match(r'(.*)\\InsetSpace (.*)', document.body[i])
2210 subst = [before, "\\begin_inset Space " + after, "\\end_inset"]
2211 document.body[i: i+1] = subst
2217 def revert_spaceinset(document):
2218 " Revert '\\begin_inset Space foo\n\\end_inset' to '\\InsetSpace foo' "
2221 i = find_token(document.body, "\\begin_inset Space", i)
2224 j = find_end_of_inset(document.body, i)
2226 document.warning("Malformed LyX document: Could not find end of space inset.")
2228 document.body[i] = document.body[i].replace('\\begin_inset Space', '\\InsetSpace')
2229 del document.body[j]
2232 def convert_hfill(document):
2233 " Convert hfill to space inset "
2236 i = find_token(document.body, "\\hfill", i)
2239 subst = document.body[i].replace('\\hfill', \
2240 '\n\\begin_inset Space \\hfill{}\n\\end_inset')
2241 subst = subst.split('\n')
2242 document.body[i : i+1] = subst
2246 def revert_hfills(document):
2247 ' Revert \\hfill commands '
2248 hfill = re.compile(r'\\hfill')
2249 dotfill = re.compile(r'\\dotfill')
2250 hrulefill = re.compile(r'\\hrulefill')
2253 i = find_token(document.body, "\\InsetSpace", i)
2256 if hfill.search(document.body[i]):
2257 document.body[i] = \
2258 document.body[i].replace('\\InsetSpace \\hfill{}', '\\hfill')
2261 if dotfill.search(document.body[i]):
2262 subst = document.body[i].replace('\\InsetSpace \\dotfill{}', \
2263 '\\begin_inset ERT\nstatus collapsed\n\n' \
2264 '\\begin_layout Standard\n\n\n\\backslash\n' \
2265 'dotfill{}\n\\end_layout\n\n\\end_inset\n\n')
2266 subst = subst.split('\n')
2267 document.body[i : i+1] = subst
2270 if hrulefill.search(document.body[i]):
2271 subst = document.body[i].replace('\\InsetSpace \\hrulefill{}', \
2272 '\\begin_inset ERT\nstatus collapsed\n\n' \
2273 '\\begin_layout Standard\n\n\n\\backslash\n' \
2274 'hrulefill{}\n\\end_layout\n\n\\end_inset\n\n')
2275 subst = subst.split('\n')
2276 document.body[i : i+1] = subst
2281 def revert_hspace(document):
2282 ' Revert \\InsetSpace \\hspace{} to ERT '
2284 hspace = re.compile(r'\\hspace{}')
2285 hstar = re.compile(r'\\hspace\*{}')
2287 i = find_token(document.body, "\\InsetSpace \\hspace", i)
2290 length = get_value(document.body, '\\length', i+1)
2292 document.warning("Malformed lyx document: Missing '\\length' in Space inset.")
2294 del document.body[i+1]
2296 if hstar.search(document.body[i]):
2297 subst = document.body[i].replace('\\InsetSpace \\hspace*{}', \
2298 '\\begin_inset ERT\nstatus collapsed\n\n' \
2299 '\\begin_layout Standard\n\n\n\\backslash\n' \
2300 'hspace*{' + length + '}\n\\end_layout\n\n\\end_inset\n\n')
2301 subst = subst.split('\n')
2302 document.body[i : i+1] = subst
2303 addedLines += len(subst) - 1
2306 if hspace.search(document.body[i]):
2307 subst = document.body[i].replace('\\InsetSpace \\hspace{}', \
2308 '\\begin_inset ERT\nstatus collapsed\n\n' \
2309 '\\begin_layout Standard\n\n\n\\backslash\n' \
2310 'hspace{' + length + '}\n\\end_layout\n\n\\end_inset\n\n')
2311 subst = subst.split('\n')
2312 document.body[i : i+1] = subst
2313 addedLines += len(subst) - 1
2319 def revert_protected_hfill(document):
2320 ' Revert \\begin_inset Space \\hspace*{\\fill} to ERT '
2323 i = find_token(document.body, '\\begin_inset Space \\hspace*{\\fill}', i)
2326 j = find_end_of_inset(document.body, i)
2328 document.warning("Malformed LyX document: Could not find end of space inset.")
2330 del document.body[j]
2331 subst = document.body[i].replace('\\begin_inset Space \\hspace*{\\fill}', \
2332 '\\begin_inset ERT\nstatus collapsed\n\n' \
2333 '\\begin_layout Standard\n\n\n\\backslash\n' \
2334 'hspace*{\n\\backslash\nfill}\n\\end_layout\n\n\\end_inset\n\n')
2335 subst = subst.split('\n')
2336 document.body[i : i+1] = subst
2340 def revert_leftarrowfill(document):
2341 ' Revert \\begin_inset Space \\leftarrowfill{} to ERT '
2344 i = find_token(document.body, '\\begin_inset Space \\leftarrowfill{}', i)
2347 j = find_end_of_inset(document.body, i)
2349 document.warning("Malformed LyX document: Could not find end of space inset.")
2351 del document.body[j]
2352 subst = document.body[i].replace('\\begin_inset Space \\leftarrowfill{}', \
2353 '\\begin_inset ERT\nstatus collapsed\n\n' \
2354 '\\begin_layout Standard\n\n\n\\backslash\n' \
2355 'leftarrowfill{}\n\\end_layout\n\n\\end_inset\n\n')
2356 subst = subst.split('\n')
2357 document.body[i : i+1] = subst
2361 def revert_rightarrowfill(document):
2362 ' Revert \\begin_inset Space \\rightarrowfill{} to ERT '
2365 i = find_token(document.body, '\\begin_inset Space \\rightarrowfill{}', i)
2368 j = find_end_of_inset(document.body, i)
2370 document.warning("Malformed LyX document: Could not find end of space inset.")
2372 del document.body[j]
2373 subst = document.body[i].replace('\\begin_inset Space \\rightarrowfill{}', \
2374 '\\begin_inset ERT\nstatus collapsed\n\n' \
2375 '\\begin_layout Standard\n\n\n\\backslash\n' \
2376 'rightarrowfill{}\n\\end_layout\n\n\\end_inset\n\n')
2377 subst = subst.split('\n')
2378 document.body[i : i+1] = subst
2382 def revert_upbracefill(document):
2383 ' Revert \\begin_inset Space \\upbracefill{} to ERT '
2386 i = find_token(document.body, '\\begin_inset Space \\upbracefill{}', i)
2389 j = find_end_of_inset(document.body, i)
2391 document.warning("Malformed LyX document: Could not find end of space inset.")
2393 del document.body[j]
2394 subst = document.body[i].replace('\\begin_inset Space \\upbracefill{}', \
2395 '\\begin_inset ERT\nstatus collapsed\n\n' \
2396 '\\begin_layout Standard\n\n\n\\backslash\n' \
2397 'upbracefill{}\n\\end_layout\n\n\\end_inset\n\n')
2398 subst = subst.split('\n')
2399 document.body[i : i+1] = subst
2403 def revert_downbracefill(document):
2404 ' Revert \\begin_inset Space \\downbracefill{} to ERT '
2407 i = find_token(document.body, '\\begin_inset Space \\downbracefill{}', i)
2410 j = find_end_of_inset(document.body, i)
2412 document.warning("Malformed LyX document: Could not find end of space inset.")
2414 del document.body[j]
2415 subst = document.body[i].replace('\\begin_inset Space \\downbracefill{}', \
2416 '\\begin_inset ERT\nstatus collapsed\n\n' \
2417 '\\begin_layout Standard\n\n\n\\backslash\n' \
2418 'downbracefill{}\n\\end_layout\n\n\\end_inset\n\n')
2419 subst = subst.split('\n')
2420 document.body[i : i+1] = subst
2424 def revert_local_layout(document):
2425 ' Revert local layout headers.'
2428 i = find_token(document.header, "\\begin_local_layout", i)
2431 j = find_end_of(document.header, i, "\\begin_local_layout", "\\end_local_layout")
2433 # this should not happen
2435 document.header[i : j + 1] = []
2438 def convert_pagebreaks(document):
2439 ' Convert inline Newpage insets to new format '
2442 i = find_token(document.body, '\\newpage', i)
2445 document.body[i:i+1] = ['\\begin_inset Newpage newpage',
2449 i = find_token(document.body, '\\pagebreak', i)
2452 document.body[i:i+1] = ['\\begin_inset Newpage pagebreak',
2456 i = find_token(document.body, '\\clearpage', i)
2459 document.body[i:i+1] = ['\\begin_inset Newpage clearpage',
2463 i = find_token(document.body, '\\cleardoublepage', i)
2466 document.body[i:i+1] = ['\\begin_inset Newpage cleardoublepage',
2470 def revert_pagebreaks(document):
2471 ' Revert \\begin_inset Newpage to previous inline format '
2474 i = find_token(document.body, '\\begin_inset Newpage', i)
2477 j = find_end_of_inset(document.body, i)
2479 document.warning("Malformed LyX document: Could not find end of Newpage inset.")
2481 del document.body[j]
2482 document.body[i] = document.body[i].replace('\\begin_inset Newpage newpage', '\\newpage')
2483 document.body[i] = document.body[i].replace('\\begin_inset Newpage pagebreak', '\\pagebreak')
2484 document.body[i] = document.body[i].replace('\\begin_inset Newpage clearpage', '\\clearpage')
2485 document.body[i] = document.body[i].replace('\\begin_inset Newpage cleardoublepage', '\\cleardoublepage')
2488 def convert_linebreaks(document):
2489 ' Convert inline Newline insets to new format '
2492 i = find_token(document.body, '\\newline', i)
2495 document.body[i:i+1] = ['\\begin_inset Newline newline',
2499 i = find_token(document.body, '\\linebreak', i)
2502 document.body[i:i+1] = ['\\begin_inset Newline linebreak',
2506 def revert_linebreaks(document):
2507 ' Revert \\begin_inset Newline to previous inline format '
2510 i = find_token(document.body, '\\begin_inset Newline', i)
2513 j = find_end_of_inset(document.body, i)
2515 document.warning("Malformed LyX document: Could not find end of Newline inset.")
2517 del document.body[j]
2518 document.body[i] = document.body[i].replace('\\begin_inset Newline newline', '\\newline')
2519 document.body[i] = document.body[i].replace('\\begin_inset Newline linebreak', '\\linebreak')
2522 def convert_japanese_plain(document):
2523 ' Set language japanese-plain to japanese '
2525 if document.language == "japanese-plain":
2526 document.language = "japanese"
2527 i = find_token(document.header, "\\language", 0)
2529 document.header[i] = "\\language japanese"
2532 j = find_token(document.body, "\\lang japanese-plain", j)
2535 document.body[j] = document.body[j].replace("\\lang japanese-plain", "\\lang japanese")
2539 def revert_pdfpages(document):
2540 ' Revert pdfpages external inset to ERT '
2543 i = find_token(document.body, "\\begin_inset External", i)
2546 j = find_end_of_inset(document.body, i)
2548 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_pdfpages.")
2551 if get_value(document.body, 'template', i, j) == "PDFPages":
2552 filename = get_value(document.body, 'filename', i, j)
2554 r = re.compile(r'\textra PDFLaTeX \"(.*)\"$')
2555 for k in range(i, j):
2556 m = r.match(document.body[k])
2559 angle = get_value(document.body, 'rotateAngle', i, j)
2560 width = get_value(document.body, 'width', i, j)
2561 height = get_value(document.body, 'height', i, j)
2562 scale = get_value(document.body, 'scale', i, j)
2563 keepAspectRatio = find_token(document.body, "\tkeepAspectRatio", i, j)
2567 options += ",angle=" + angle
2569 options += "angle=" + angle
2572 options += ",width=" + convert_len(width)
2574 options += "width=" + convert_len(width)
2577 options += ",height=" + convert_len(height)
2579 options += "height=" + convert_len(height)
2582 options += ",scale=" + scale
2584 options += "scale=" + scale
2585 if keepAspectRatio != '':
2587 options += ",keepaspectratio"
2589 options += "keepaspectratio"
2591 options = '[' + options + ']'
2592 del document.body[i+1:j+1]
2593 document.body[i:i+1] = ['\\begin_inset ERT',
2596 '\\begin_layout Standard',
2599 'includepdf' + options + '{' + filename + '}',
2603 add_to_preamble(document, ['\\usepackage{pdfpages}\n'])
2609 def revert_mexican(document):
2610 ' Set language Spanish(Mexico) to Spanish '
2612 if document.language == "spanish-mexico":
2613 document.language = "spanish"
2614 i = find_token(document.header, "\\language", 0)
2616 document.header[i] = "\\language spanish"
2619 j = find_token(document.body, "\\lang spanish-mexico", j)
2622 document.body[j] = document.body[j].replace("\\lang spanish-mexico", "\\lang spanish")
2626 def remove_embedding(document):
2627 ' Remove embed tag from all insets '
2628 revert_inset_embedding(document, 'Graphics')
2629 revert_inset_embedding(document, 'External')
2630 revert_inset_embedding(document, 'CommandInset include')
2631 revert_inset_embedding(document, 'CommandInset bibtex')
2634 def revert_master(document):
2635 ' Remove master param '
2636 i = find_token(document.header, "\\master", 0)
2638 del document.header[i]
2641 def revert_graphics_group(document):
2642 ' Revert group information from graphics insets '
2645 i = find_token(document.body, "\\begin_inset Graphics", i)
2648 j = find_end_of_inset(document.body, i)
2650 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_graphics_group.")
2653 k = find_token(document.body, " groupId", i, j)
2657 del document.body[k]
2661 def update_apa_styles(document):
2662 ' Replace obsolete styles '
2664 if document.textclass != "apa":
2667 obsoletedby = { "Acknowledgments": "Acknowledgements",
2668 "Section*": "Section",
2669 "Subsection*": "Subsection",
2670 "Subsubsection*": "Subsubsection",
2671 "Paragraph*": "Paragraph",
2672 "Subparagraph*": "Subparagraph"}
2675 i = find_token(document.body, "\\begin_layout", i)
2679 layout = document.body[i][14:]
2680 if layout in obsoletedby:
2681 document.body[i] = "\\begin_layout " + obsoletedby[layout]
2686 def convert_paper_sizes(document):
2687 ' exchange size options legalpaper and executivepaper to correct order '
2688 # routine is needed to fix http://bugzilla.lyx.org/show_bug.cgi?id=4868
2691 i = find_token(document.header, "\\papersize executivepaper", 0)
2693 document.header[i] = "\\papersize legalpaper"
2695 j = find_token(document.header, "\\papersize legalpaper", 0)
2697 document.header[j] = "\\papersize executivepaper"
2700 def revert_paper_sizes(document):
2701 ' exchange size options legalpaper and executivepaper to correct order '
2704 i = find_token(document.header, "\\papersize executivepaper", 0)
2706 document.header[i] = "\\papersize legalpaper"
2708 j = find_token(document.header, "\\papersize legalpaper", 0)
2710 document.header[j] = "\\papersize executivepaper"
2713 def convert_InsetSpace(document):
2714 " Convert '\\begin_inset Space foo' to '\\begin_inset space foo'"
2717 i = find_token(document.body, "\\begin_inset Space", i)
2720 document.body[i] = document.body[i].replace('\\begin_inset Space', '\\begin_inset space')
2723 def revert_InsetSpace(document):
2724 " Revert '\\begin_inset space foo' to '\\begin_inset Space foo'"
2727 i = find_token(document.body, "\\begin_inset space", i)
2730 document.body[i] = document.body[i].replace('\\begin_inset space', '\\begin_inset Space')
2733 def convert_display_enum(document):
2734 " Convert 'display foo' to 'display false/true'"
2737 i = find_token(document.body, "\tdisplay", i)
2740 val = get_value(document.body, 'display', i)
2742 document.body[i] = document.body[i].replace('none', 'false')
2743 if val == "default":
2744 document.body[i] = document.body[i].replace('default', 'true')
2745 if val == "monochrome":
2746 document.body[i] = document.body[i].replace('monochrome', 'true')
2747 if val == "grayscale":
2748 document.body[i] = document.body[i].replace('grayscale', 'true')
2750 document.body[i] = document.body[i].replace('color', 'true')
2751 if val == "preview":
2752 document.body[i] = document.body[i].replace('preview', 'true')
2756 def revert_display_enum(document):
2757 " Revert 'display false/true' to 'display none/color'"
2760 i = find_token(document.body, "\tdisplay", i)
2763 val = get_value(document.body, 'display', i)
2765 document.body[i] = document.body[i].replace('false', 'none')
2767 document.body[i] = document.body[i].replace('true', 'default')
2771 def remove_fontsCJK(document):
2772 ' Remove font_cjk param '
2773 i = find_token(document.header, "\\font_cjk", 0)
2775 del document.header[i]
2778 def convert_plain_layout(document):
2779 " Convert 'PlainLayout' to 'Plain Layout'"
2782 i = find_token(document.body, '\\begin_layout PlainLayout', i)
2785 document.body[i] = document.body[i].replace('\\begin_layout PlainLayout', \
2786 '\\begin_layout Plain Layout')
2790 def revert_plain_layout(document):
2791 " Convert 'PlainLayout' to 'Plain Layout'"
2794 i = find_token(document.body, '\\begin_layout Plain Layout', i)
2797 document.body[i] = document.body[i].replace('\\begin_layout Plain Layout', \
2798 '\\begin_layout PlainLayout')
2802 def revert_plainlayout(document):
2803 " Convert 'PlainLayout' to 'Plain Layout'"
2806 i = find_token(document.body, '\\begin_layout PlainLayout', i)
2809 # This will be incorrect for some document classes, since Standard is not always
2810 # the default. But (a) it is probably the best we can do and (b) it will actually
2811 # work, in fact, since an unknown layout will be converted to default.
2812 document.body[i] = document.body[i].replace('\\begin_layout PlainLayout', \
2813 '\\begin_layout Standard')
2817 def revert_polytonicgreek(document):
2818 "Set language polytonic Greek to Greek"
2820 if document.language == "polutonikogreek":
2821 document.language = "greek"
2822 i = find_token(document.header, "\\language", 0)
2824 document.header[i] = "\\language greek"
2827 j = find_token(document.body, "\\lang polutonikogreek", j)
2830 document.body[j] = document.body[j].replace("\\lang polutonikogreek", "\\lang greek")
2838 supported_versions = ["1.6.0","1.6"]
2839 convert = [[277, [fix_wrong_tables]],
2840 [278, [close_begin_deeper]],
2841 [279, [long_charstyle_names]],
2842 [280, [axe_show_label]],
2845 [283, [convert_flex]],
2849 [287, [convert_wrapfig_options]],
2850 [288, [convert_inset_command]],
2851 [289, [convert_latexcommand_index]],
2854 [292, [convert_japanese_cjk]],
2856 [294, [convert_pdf_options]],
2857 [295, [convert_htmlurl, convert_url]],
2858 [296, [convert_include]],
2859 [297, [convert_usorbian]],
2865 [303, [convert_serbocroatian]],
2866 [304, [convert_framed_notes]],
2873 [311, [convert_ams_classes]],
2875 [313, [convert_module_names]],
2878 [316, [convert_subfig]],
2881 [319, [convert_spaceinset, convert_hfill]],
2883 [321, [convert_tablines]],
2884 [322, [convert_plain_layout]],
2885 [323, [convert_pagebreaks]],
2886 [324, [convert_linebreaks]],
2887 [325, [convert_japanese_plain]],
2890 [328, [remove_embedding, remove_extra_embedded_files, remove_inzip_options]],
2893 [331, [convert_ltcaption]],
2895 [333, [update_apa_styles]],
2896 [334, [convert_paper_sizes]],
2897 [335, [convert_InsetSpace]],
2899 [337, [convert_display_enum]],
2903 revert = [[337, [revert_polytonicgreek]],
2904 [336, [revert_display_enum]],
2905 [335, [remove_fontsCJK]],
2906 [334, [revert_InsetSpace]],
2907 [333, [revert_paper_sizes]],
2909 [331, [revert_graphics_group]],
2910 [330, [revert_ltcaption]],
2911 [329, [revert_leftarrowfill, revert_rightarrowfill, revert_upbracefill, revert_downbracefill]],
2912 [328, [revert_master]],
2914 [326, [revert_mexican]],
2915 [325, [revert_pdfpages]],
2917 [323, [revert_linebreaks]],
2918 [322, [revert_pagebreaks]],
2919 [321, [revert_local_layout, revert_plain_layout]],
2920 [320, [revert_tablines]],
2921 [319, [revert_protected_hfill]],
2922 [318, [revert_spaceinset, revert_hfills, revert_hspace]],
2923 [317, [remove_extra_embedded_files]],
2924 [316, [revert_wrapplacement]],
2925 [315, [revert_subfig]],
2926 [314, [revert_colsep, revert_plainlayout]],
2928 [312, [revert_module_names]],
2929 [311, [revert_rotfloat, revert_widesideways]],
2930 [310, [revert_external_embedding]],
2931 [309, [revert_btprintall]],
2932 [308, [revert_nocite]],
2933 [307, [revert_serbianlatin]],
2934 [306, [revert_slash, revert_nobreakdash]],
2935 [305, [revert_interlingua]],
2936 [304, [revert_bahasam]],
2937 [303, [revert_framed_notes]],
2939 [301, [revert_latin, revert_samin]],
2940 [300, [revert_linebreak]],
2941 [299, [revert_pagebreak]],
2942 [298, [revert_hyperlinktype]],
2943 [297, [revert_macro_optional_params]],
2944 [296, [revert_albanian, revert_lowersorbian, revert_uppersorbian]],
2945 [295, [revert_include]],
2946 [294, [revert_href, revert_url]],
2947 [293, [revert_pdf_options_2]],
2948 [292, [revert_inset_info]],
2949 [291, [revert_japanese, revert_japanese_encoding, revert_japanese_cjk]],
2950 [290, [revert_vietnamese]],
2951 [289, [revert_wraptable]],
2952 [288, [revert_latexcommand_index]],
2953 [287, [revert_inset_command]],
2954 [286, [revert_wrapfig_options]],
2955 [285, [revert_pdf_options]],
2956 [284, [remove_inzip_options]],
2958 [282, [revert_flex]],
2960 [280, [revert_begin_modules]],
2961 [279, [revert_show_label]],
2962 [278, [revert_long_charstyle_names]],
2968 if __name__ == "__main__":