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 if nextpos < len(data) and data[nextpos].isalpha():
254 # not the end of that command
257 data = data[:pos] + rep[1] + data[nextpos:]
260 data = data.replace(rep[0], rep[1])
263 data = wrap_into_ert(data, r'\"', '"')
266 mathre = re.compile('^(.*?)(\$.*?\$)(.*)')
267 lines = data.split('\n')
269 #document.warning("LINE: " + line)
270 #document.warning(str(i) + ":" + document.body[i])
271 #document.warning("LAST: " + document.body[-1])
276 f = m.group(2).replace('\\\\', '\\')
281 subst = s.split('\n')
283 retval.append("\\begin_inset Formula " + f)
284 retval.append("\\end_inset")
286 # Handle whatever is left, which is just text
288 subst = g.split('\n')
293 ####################################################################
295 def convert_ltcaption(document):
298 i = find_token(document.body, "\\begin_inset Tabular", i)
301 j = find_end_of_inset(document.body, i + 1)
303 document.warning("Malformed LyX document: Could not find end of tabular.")
306 nrows = int(document.body[i+1].split('"')[3])
307 ncols = int(document.body[i+1].split('"')[5])
310 for k in range(nrows):
311 m = find_token(document.body, "<row", m)
314 for k in range(ncols):
315 m = find_token(document.body, "<cell", m)
317 mend = find_token(document.body, "</cell>", m + 1)
318 # first look for caption insets
319 mcap = find_token(document.body, "\\begin_inset Caption", m + 1, mend)
320 # then look for ERT captions
322 mcap = find_token(document.body, "caption", m + 1, mend)
324 mcap = find_token(document.body, "\\backslash", mcap - 1, mcap)
327 if caption == 'true':
329 set_option(document, r, 'caption', 'true')
330 set_option(document, m, 'multicolumn', '1')
331 set_option(document, m, 'bottomline', 'false')
332 set_option(document, m, 'topline', 'false')
333 set_option(document, m, 'rightline', 'false')
334 set_option(document, m, 'leftline', 'false')
335 #j = find_end_of_inset(document.body, j + 1)
337 set_option(document, m, 'multicolumn', '2')
344 #FIXME Use of wrap_into_ert can confuse lyx2lyx
345 def revert_ltcaption(document):
348 i = find_token(document.body, "\\begin_inset Tabular", i)
351 j = find_end_of_inset(document.body, i + 1)
353 document.warning("Malformed LyX document: Could not find end of tabular.")
357 nrows = int(document.body[i+1].split('"')[3])
358 ncols = int(document.body[i+1].split('"')[5])
360 for k in range(nrows):
361 m = find_token(document.body, "<row", m)
362 caption = get_option(document, m, 'caption', 'false')
363 if caption == 'true':
364 remove_option(document, m, 'caption')
365 for k in range(ncols):
366 m = find_token(document.body, "<cell", m)
367 remove_option(document, m, 'multicolumn')
369 m = find_token(document.body, "\\begin_inset Caption", m)
372 m = find_end_of_inset(document.body, m + 1)
373 document.body[m] += wrap_into_ert("","","\\backslash\n\\backslash\n%")
379 def convert_tablines(document):
382 i = find_token(document.body, "\\begin_inset Tabular", i)
384 # LyX 1.3 inserted an extra space between \begin_inset
385 # and Tabular so let us try if this is the case and fix it.
386 i = find_token(document.body, "\\begin_inset Tabular", i)
390 document.body[i] = "\\begin_inset Tabular"
391 j = find_end_of_inset(document.body, i + 1)
393 document.warning("Malformed LyX document: Could not find end of tabular.")
397 nrows = int(document.body[i+1].split('"')[3])
398 ncols = int(document.body[i+1].split('"')[5])
401 for k in range(ncols):
402 m = find_token(document.body, "<column", m)
403 left = get_option(document, m, 'leftline', 'false')
404 right = get_option(document, m, 'rightline', 'false')
405 col_info.append([left, right])
406 remove_option(document, m, 'leftline')
407 remove_option(document, m, 'rightline')
411 for k in range(nrows):
412 m = find_token(document.body, "<row", m)
413 top = get_option(document, m, 'topline', 'false')
414 bottom = get_option(document, m, 'bottomline', 'false')
415 row_info.append([top, bottom])
416 remove_option(document, m, 'topline')
417 remove_option(document, m, 'bottomline')
422 for k in range(nrows*ncols):
423 m = find_token(document.body, "<cell", m)
424 mc_info.append(get_option(document, m, 'multicolumn', '0'))
427 for l in range(nrows):
428 for k in range(ncols):
429 m = find_token(document.body, '<cell', m)
430 if mc_info[l*ncols + k] == '0':
431 r = set_option(document, m, 'topline', row_info[l][0])
432 r = set_option(document, m, 'bottomline', row_info[l][1])
433 r = set_option(document, m, 'leftline', col_info[k][0])
434 r = set_option(document, m, 'rightline', col_info[k][1])
435 elif mc_info[l*ncols + k] == '1':
437 while s < ncols and mc_info[l*ncols + s] == '2':
439 if s < ncols and mc_info[l*ncols + s] != '1':
440 r = set_option(document, m, 'rightline', col_info[k][1])
441 if k > 0 and mc_info[l*ncols + k - 1] == '0':
442 r = set_option(document, m, 'leftline', col_info[k][0])
447 def revert_tablines(document):
450 i = find_token(document.body, "\\begin_inset Tabular", i)
453 j = find_end_of_inset(document.body, i + 1)
455 document.warning("Malformed LyX document: Could not find end of tabular.")
459 nrows = int(document.body[i+1].split('"')[3])
460 ncols = int(document.body[i+1].split('"')[5])
463 for k in range(nrows*ncols):
464 m = find_token(document.body, "<cell", m)
465 top = get_option(document, m, 'topline', 'false')
466 bottom = get_option(document, m, 'bottomline', 'false')
467 left = get_option(document, m, 'leftline', 'false')
468 right = get_option(document, m, 'rightline', 'false')
469 lines.append([top, bottom, left, right])
472 # we will want to ignore longtable captions
475 for k in range(nrows):
476 m = find_token(document.body, "<row", m)
477 caption = get_option(document, m, 'caption', 'false')
478 caption_info.append([caption])
483 for k in range(ncols):
484 m = find_token(document.body, "<column", m)
486 for l in range(nrows):
487 left = lines[l*ncols + k][2]
488 if left == 'false' and caption_info[l] == 'false':
490 set_option(document, m, 'leftline', left)
492 for l in range(nrows):
493 right = lines[l*ncols + k][3]
494 if right == 'false' and caption_info[l] == 'false':
496 set_option(document, m, 'rightline', right)
500 for k in range(nrows):
501 m = find_token(document.body, "<row", m)
503 for l in range(ncols):
504 top = lines[k*ncols + l][0]
507 if caption_info[k] == 'false':
509 set_option(document, m, 'topline', top)
511 for l in range(ncols):
512 bottom = lines[k*ncols + l][1]
513 if bottom == 'false':
515 if caption_info[k] == 'false':
517 set_option(document, m, 'bottomline', bottom)
523 def fix_wrong_tables(document):
526 i = find_token(document.body, "\\begin_inset Tabular", i)
529 j = find_end_of_inset(document.body, i + 1)
531 document.warning("Malformed LyX document: Could not find end of tabular.")
535 nrows = int(document.body[i+1].split('"')[3])
536 ncols = int(document.body[i+1].split('"')[5])
538 for l in range(nrows):
540 for k in range(ncols):
541 m = find_token(document.body, '<cell', m)
543 if document.body[m].find('multicolumn') != -1:
544 multicol_cont = int(document.body[m].split('"')[1])
546 if multicol_cont == 2 and (k == 0 or prev_multicolumn == 0):
547 document.body[m] = document.body[m][:5] + document.body[m][21:]
550 prev_multicolumn = multicol_cont
557 def close_begin_deeper(document):
561 i = find_tokens(document.body, ["\\begin_deeper", "\\end_deeper"], i)
566 if document.body[i][:13] == "\\begin_deeper":
573 document.body[-2:-2] = ['\\end_deeper' for i in range(depth)]
576 def long_charstyle_names(document):
579 i = find_token(document.body, "\\begin_inset CharStyle", i)
582 document.body[i] = document.body[i].replace("CharStyle ", "CharStyle CharStyle:")
585 def revert_long_charstyle_names(document):
588 i = find_token(document.body, "\\begin_inset CharStyle", i)
591 document.body[i] = document.body[i].replace("CharStyle CharStyle:", "CharStyle")
595 def axe_show_label(document):
598 i = find_token(document.body, "\\begin_inset CharStyle", i)
601 if document.body[i + 1].find("show_label") != -1:
602 if document.body[i + 1].find("true") != -1:
603 document.body[i + 1] = "status open"
604 del document.body[ i + 2]
606 if document.body[i + 1].find("false") != -1:
607 document.body[i + 1] = "status collapsed"
608 del document.body[ i + 2]
610 document.warning("Malformed LyX document: show_label neither false nor true.")
612 document.warning("Malformed LyX document: show_label missing in CharStyle.")
617 def revert_show_label(document):
620 i = find_token(document.body, "\\begin_inset CharStyle", i)
623 if document.body[i + 1].find("status open") != -1:
624 document.body.insert(i + 1, "show_label true")
626 if document.body[i + 1].find("status collapsed") != -1:
627 document.body.insert(i + 1, "show_label false")
629 document.warning("Malformed LyX document: no legal status line in CharStyle.")
632 def revert_begin_modules(document):
635 i = find_token(document.header, "\\begin_modules", i)
638 j = find_end_of(document.header, i, "\\begin_modules", "\\end_modules")
640 # this should not happen
642 document.header[i : j + 1] = []
644 def convert_flex(document):
645 "Convert CharStyle to Flex"
648 i = find_token(document.body, "\\begin_inset CharStyle", i)
651 document.body[i] = document.body[i].replace('\\begin_inset CharStyle', '\\begin_inset Flex')
653 def revert_flex(document):
654 "Convert Flex to CharStyle"
657 i = find_token(document.body, "\\begin_inset Flex", i)
660 document.body[i] = document.body[i].replace('\\begin_inset Flex', '\\begin_inset CharStyle')
663 # Discard PDF options for hyperref
664 def revert_pdf_options(document):
665 "Revert PDF options for hyperref."
666 # store the PDF options and delete the entries from the Lyx file
674 bookmarksnumbered = ""
676 bookmarksopenlevel = ""
684 i = find_token(document.header, "\\use_hyperref", i)
686 hyperref = get_value(document.header, "\\use_hyperref", i) == 'true'
687 del document.header[i]
688 i = find_token(document.header, "\\pdf_store_options", i)
690 del document.header[i]
691 i = find_token(document.header, "\\pdf_title", 0)
693 title = get_value_string(document.header, '\\pdf_title', 0, 0, True)
694 title = ' pdftitle={' + title + '}'
695 del document.header[i]
696 i = find_token(document.header, "\\pdf_author", 0)
698 author = get_value_string(document.header, '\\pdf_author', 0, 0, True)
700 author = ' pdfauthor={' + author + '}'
702 author = ',\n pdfauthor={' + author + '}'
703 del document.header[i]
704 i = find_token(document.header, "\\pdf_subject", 0)
706 subject = get_value_string(document.header, '\\pdf_subject', 0, 0, True)
707 if title == "" and author == "":
708 subject = ' pdfsubject={' + subject + '}'
710 subject = ',\n pdfsubject={' + subject + '}'
711 del document.header[i]
712 i = find_token(document.header, "\\pdf_keywords", 0)
714 keywords = get_value_string(document.header, '\\pdf_keywords', 0, 0, True)
715 if title == "" and author == "" and subject == "":
716 keywords = ' pdfkeywords={' + keywords + '}'
718 keywords = ',\n pdfkeywords={' + keywords + '}'
719 del document.header[i]
720 i = find_token(document.header, "\\pdf_bookmarks", 0)
722 bookmarks = get_value_string(document.header, '\\pdf_bookmarks', 0)
723 bookmarks = ',\n bookmarks=' + bookmarks
724 del document.header[i]
725 i = find_token(document.header, "\\pdf_bookmarksnumbered", i)
727 bookmarksnumbered = get_value_string(document.header, '\\pdf_bookmarksnumbered', 0)
728 bookmarksnumbered = ',\n bookmarksnumbered=' + bookmarksnumbered
729 del document.header[i]
730 i = find_token(document.header, "\\pdf_bookmarksopen", i)
732 bookmarksopen = get_value_string(document.header, '\\pdf_bookmarksopen', 0)
733 bookmarksopen = ',\n bookmarksopen=' + bookmarksopen
734 del document.header[i]
735 i = find_token(document.header, "\\pdf_bookmarksopenlevel", i)
737 bookmarksopenlevel = get_value_string(document.header, '\\pdf_bookmarksopenlevel', 0, 0, True)
738 bookmarksopenlevel = ',\n bookmarksopenlevel=' + bookmarksopenlevel
739 del document.header[i]
740 i = find_token(document.header, "\\pdf_breaklinks", i)
742 breaklinks = get_value_string(document.header, '\\pdf_breaklinks', 0)
743 breaklinks = ',\n breaklinks=' + breaklinks
744 del document.header[i]
745 i = find_token(document.header, "\\pdf_pdfborder", i)
747 pdfborder = get_value_string(document.header, '\\pdf_pdfborder', 0)
748 if pdfborder == 'true':
749 pdfborder = ',\n pdfborder={0 0 0}'
751 pdfborder = ',\n pdfborder={0 0 1}'
752 del document.header[i]
753 i = find_token(document.header, "\\pdf_colorlinks", i)
755 colorlinks = get_value_string(document.header, '\\pdf_colorlinks', 0)
756 colorlinks = ',\n colorlinks=' + colorlinks
757 del document.header[i]
758 i = find_token(document.header, "\\pdf_backref", i)
760 backref = get_value_string(document.header, '\\pdf_backref', 0)
761 backref = ',\n backref=' + backref
762 del document.header[i]
763 i = find_token(document.header, "\\pdf_pagebackref", i)
765 pagebackref = get_value_string(document.header, '\\pdf_pagebackref', 0)
766 pagebackref = ',\n pagebackref=' + pagebackref
767 del document.header[i]
768 i = find_token(document.header, "\\pdf_pagemode", 0)
770 pagemode = get_value_string(document.header, '\\pdf_pagemode', 0)
771 pagemode = ',\n pdfpagemode=' + pagemode
772 del document.header[i]
773 i = find_token(document.header, "\\pdf_quoted_options", 0)
775 otheroptions = get_value_string(document.header, '\\pdf_quoted_options', 0, 0, True)
776 if title == "" and author == "" and subject == "" and keywords == "":
777 otheroptions = ' ' + otheroptions
779 otheroptions = ',\n ' + otheroptions
780 del document.header[i]
782 # write to the preamble when hyperref was used
784 # preamble write preparations
785 # bookmark numbers are only output when they are turned on
786 if bookmarksopen == ',\n bookmarksopen=true':
787 bookmarksopen = bookmarksopen + bookmarksopenlevel
788 if bookmarks == ',\n bookmarks=true':
789 bookmarks = bookmarks + bookmarksnumbered + bookmarksopen
791 bookmarks = bookmarks
792 # hypersetup is only output when there are things to be set up
793 setupstart = '\\hypersetup{%\n'
795 if otheroptions == "" and title == "" and author == ""\
796 and subject == "" and keywords == "":
800 add_to_preamble(document,
801 ['% Commands inserted by lyx2lyx for PDF properties',
802 '\\usepackage[unicode=true'
821 def remove_inzip_options(document):
822 "Remove inzipName and embed options from the Graphics inset"
825 i = find_token(document.body, "\\begin_inset Graphics", i)
828 j = find_end_of_inset(document.body, i + 1)
831 document.warning("Malformed LyX document: Could not find end of graphics inset.")
832 # If there's a inzip param, just remove that
833 k = find_token(document.body, "\tinzipName", i + 1, j)
836 # embed option must follow the inzipName option
837 del document.body[k+1]
841 def convert_inset_command(document):
844 \begin_inset LatexCommand cmd
846 \begin_inset CommandInset InsetType
851 i = find_token(document.body, "\\begin_inset LatexCommand", i)
854 line = document.body[i]
855 r = re.compile(r'\\begin_inset LatexCommand (.*)$')
859 #this is adapted from factory.cpp
860 if cmdName[0:4].lower() == "cite":
861 insetName = "citation"
862 elif cmdName == "url" or cmdName == "htmlurl":
864 elif cmdName[-3:] == "ref":
866 elif cmdName == "tableofcontents":
868 elif cmdName == "printnomenclature":
869 insetName = "nomencl_print"
870 elif cmdName == "printindex":
871 insetName = "index_print"
874 insertion = ["\\begin_inset CommandInset " + insetName, "LatexCommand " + cmdName]
875 document.body[i : i+1] = insertion
878 def revert_inset_command(document):
881 \begin_inset CommandInset InsetType
884 \begin_inset LatexCommand cmd
885 Some insets may end up being converted to insets earlier versions of LyX
886 will not be able to recognize. Not sure what to do about that.
890 i = find_token(document.body, "\\begin_inset CommandInset", i)
893 nextline = document.body[i+1]
894 r = re.compile(r'LatexCommand\s+(.*)$')
895 m = r.match(nextline)
897 document.warning("Malformed LyX document: Missing LatexCommand in " + document.body[i] + ".")
900 insertion = ["\\begin_inset LatexCommand " + cmdName]
901 document.body[i : i+2] = insertion
904 def convert_wrapfig_options(document):
905 "Convert optional options for wrap floats (wrapfig)."
906 # adds the tokens "lines", "placement", and "overhang"
909 i = find_token(document.body, "\\begin_inset Wrap figure", i)
912 document.body.insert(i + 1, "lines 0")
913 j = find_token(document.body, "placement", i)
914 # placement can be already set or not; if not, set it
916 document.body.insert(i + 3, "overhang 0col%")
918 document.body.insert(i + 2, "placement o")
919 document.body.insert(i + 3, "overhang 0col%")
923 def revert_wrapfig_options(document):
924 "Revert optional options for wrap floats (wrapfig)."
927 i = find_token(document.body, "\\begin_inset Wrap figure", i)
930 j = find_end_of_inset(document.body, i)
932 document.warning("Can't find end of Wrap inset at line " + str(i))
935 k = find_default_layout(document, i, j)
937 document.warning("Can't find default layout for Wrap figure!")
940 # Options should be between i and k now
941 l = find_token(document.body, "lines", i, k)
943 document.warning("Can't find lines option for Wrap figure!")
946 m = find_token(document.body, "overhang", i + 1, k)
948 document.warning("Malformed LyX document: Couldn't find overhang parameter of wrap float!")
951 # Do these in reverse order
957 def convert_latexcommand_index(document):
958 "Convert from LatexCommand form to collapsable form."
960 r1 = re.compile('name "(.*)"')
962 i = find_token(document.body, "\\begin_inset CommandInset index", i)
965 if document.body[i + 1] != "LatexCommand index": # Might also be index_print
967 m = r1.match(document.body[i + 2])
969 document.warning("Unable to match: " + document.body[i+2])
972 fullcontent = m.group(1)
973 #document.warning(fullcontent)
974 document.body[i:i + 3] = ["\\begin_inset Index",
976 "\\begin_layout Standard"]
978 # We are now on the blank line preceding "\end_inset"
979 # We will write the content here, into the inset.
981 linelist = latex2lyx(fullcontent)
982 document.body[i+1:i+1] = linelist
985 document.body.insert(i + 1, "\\end_layout")
989 def revert_latexcommand_index(document):
990 "Revert from collapsable form to LatexCommand form."
993 i = find_token(document.body, "\\begin_inset Index", i)
996 j = find_end_of_inset(document.body, i + 1)
1000 # clean up multiline stuff
1003 reps = read_unicodesymbols()
1005 for curline in range(i + 3, j - 2): # can skip last couple lines
1006 line = document.body[curline]
1007 if line.startswith("\\begin_inset ERT"):
1008 # We don't want to replace things inside ERT, so figure out
1009 # where the end of the inset is.
1010 ert_end = find_end_of_inset(document.body, curline + 1)
1012 elif line.startswith("\\begin_inset Formula"):
1014 elif line.startswith("\\begin_inset Quotes"):
1015 # For now, we do a very basic reversion. Someone who understands
1016 # quotes is welcome to fix it up.
1017 qtype = line[20:].strip()
1031 elif line.isspace() or \
1032 line.startswith("\\begin_layout Standard") or \
1033 line.startswith("\\begin_layout Plain Layout") or \
1034 line.startswith("\\end_layout") or \
1035 line.startswith("\\end_inset") or \
1036 line.startswith("\\lang") or \
1037 line.startswith("status collapsed") or \
1038 line.startswith("status open"):
1039 #skip all that stuff
1042 # a lossless reversion is not possible
1043 # try at least to handle some common insets and settings
1044 # do not replace inside ERTs
1045 if ert_end >= curline:
1046 line = line.replace(r'\backslash', r'\\')
1048 # Do the LyX text --> LaTeX conversion
1050 line = line.replace(rep[1], rep[0])
1051 line = line.replace(r'\backslash', r'\textbackslash{}')
1052 line = line.replace(r'\series bold', r'\bfseries{}').replace(r'\series default', r'\mdseries{}')
1053 line = line.replace(r'\shape italic', r'\itshape{}').replace(r'\shape smallcaps', r'\scshape{}')
1054 line = line.replace(r'\shape slanted', r'\slshape{}').replace(r'\shape default', r'\upshape{}')
1055 line = line.replace(r'\emph on', r'\em{}').replace(r'\emph default', r'\em{}')
1056 line = line.replace(r'\noun on', r'\scshape{}').replace(r'\noun default', r'\upshape{}')
1057 line = line.replace(r'\bar under', r'\underbar{').replace(r'\bar default', r'}')
1058 line = line.replace(r'\family sans', r'\sffamily{}').replace(r'\family default', r'\normalfont{}')
1059 line = line.replace(r'\family typewriter', r'\ttfamily{}').replace(r'\family roman', r'\rmfamily{}')
1060 line = line.replace(r'\InsetSpace ', r'').replace(r'\SpecialChar ', r'')
1063 # end of curline loop
1065 content = content.replace('"', r'\"')
1066 document.body[i:j] = ["\\begin_inset CommandInset index", "LatexCommand index",
1067 "name " + '"' + content + '"', ""]
1071 def revert_wraptable(document):
1072 "Revert wrap table to wrap figure."
1075 i = find_token(document.body, "\\begin_inset Wrap table", i)
1078 document.body[i] = document.body[i].replace('\\begin_inset Wrap table', '\\begin_inset Wrap figure')
1082 def revert_vietnamese(document):
1083 "Set language Vietnamese to English"
1084 # Set document language from Vietnamese to English
1086 if document.language == "vietnamese":
1087 document.language = "english"
1088 i = find_token(document.header, "\\language", 0)
1090 document.header[i] = "\\language english"
1093 j = find_token(document.body, "\\lang vietnamese", j)
1096 document.body[j] = document.body[j].replace("\\lang vietnamese", "\\lang english")
1100 def convert_japanese_cjk(document):
1101 "Set language japanese to japanese-cjk"
1102 # Set document language from japanese-plain to japanese
1104 if document.language == "japanese":
1105 document.language = "japanese-cjk"
1106 i = find_token(document.header, "\\language", 0)
1108 document.header[i] = "\\language japanese-cjk"
1111 j = find_token(document.body, "\\lang japanese", j)
1114 document.body[j] = document.body[j].replace("\\lang japanese", "\\lang japanese-cjk")
1118 def revert_japanese(document):
1119 "Set language japanese-plain to japanese"
1120 # Set document language from japanese-plain to japanese
1122 if document.language == "japanese-plain":
1123 document.language = "japanese"
1124 i = find_token(document.header, "\\language", 0)
1126 document.header[i] = "\\language japanese"
1129 j = find_token(document.body, "\\lang japanese-plain", j)
1132 document.body[j] = document.body[j].replace("\\lang japanese-plain", "\\lang japanese")
1136 def revert_japanese_cjk(document):
1137 "Set language japanese-cjk to japanese"
1138 # Set document language from japanese-plain to japanese
1140 if document.language == "japanese-cjk":
1141 document.language = "japanese"
1142 i = find_token(document.header, "\\language", 0)
1144 document.header[i] = "\\language japanese"
1147 j = find_token(document.body, "\\lang japanese-cjk", j)
1150 document.body[j] = document.body[j].replace("\\lang japanese-cjk", "\\lang japanese")
1154 def revert_japanese_encoding(document):
1155 "Set input encoding form EUC-JP-plain to EUC-JP etc."
1156 # Set input encoding form EUC-JP-plain to EUC-JP etc.
1158 i = find_token(document.header, "\\inputencoding EUC-JP-plain", 0)
1160 document.header[i] = "\\inputencoding EUC-JP"
1162 j = find_token(document.header, "\\inputencoding JIS-plain", 0)
1164 document.header[j] = "\\inputencoding JIS"
1166 k = find_token(document.header, "\\inputencoding SJIS-plain", 0)
1167 if k != -1: # convert to UTF8 since there is currently no SJIS encoding
1168 document.header[k] = "\\inputencoding UTF8"
1171 def revert_inset_info(document):
1172 'Replace info inset with its content'
1175 i = find_token(document.body, '\\begin_inset Info', i)
1178 j = find_end_of_inset(document.body, i + 1)
1181 document.warning("Malformed LyX document: Could not find end of Info inset.")
1184 for k in range(i, j+1):
1185 if document.body[k].startswith("arg"):
1186 arg = document.body[k][3:].strip().strip('"')
1187 if document.body[k].startswith("type"):
1188 type = document.body[k][4:].strip().strip('"')
1189 # I think there is a newline after \\end_inset, which should be removed.
1190 if document.body[j + 1].strip() == "":
1191 document.body[i : (j + 2)] = [type + ':' + arg]
1193 document.body[i : (j + 1)] = [type + ':' + arg]
1196 def convert_pdf_options(document):
1197 # Set the pdfusetitle tag, delete the pdf_store_options,
1198 # set quotes for bookmarksopenlevel"
1199 has_hr = get_value(document.header, "\\use_hyperref", 0, default = "0")
1201 k = find_token(document.header, "\\use_hyperref", 0)
1202 document.header.insert(k + 1, "\\pdf_pdfusetitle true")
1203 k = find_token(document.header, "\\pdf_store_options", 0)
1205 del document.header[k]
1206 i = find_token(document.header, "\\pdf_bookmarksopenlevel", k)
1208 document.header[i] = document.header[i].replace('"', '')
1211 def revert_pdf_options_2(document):
1212 # reset the pdfusetitle tag, set quotes for bookmarksopenlevel"
1213 k = find_token(document.header, "\\use_hyperref", 0)
1214 i = find_token(document.header, "\\pdf_pdfusetitle", k)
1216 del document.header[i]
1217 i = find_token(document.header, "\\pdf_bookmarksopenlevel", k)
1219 values = document.header[i].split()
1220 values[1] = ' "' + values[1] + '"'
1221 document.header[i] = ''.join(values)
1224 def convert_htmlurl(document):
1225 'Convert "htmlurl" to "href" insets for docbook'
1226 if document.backend != "docbook":
1230 i = find_token(document.body, "\\begin_inset CommandInset url", i)
1233 document.body[i] = "\\begin_inset CommandInset href"
1234 document.body[i + 1] = "LatexCommand href"
1238 def convert_url(document):
1239 'Convert url insets to url charstyles'
1240 if document.backend == "docbook":
1244 i = find_token(document.body, "\\begin_inset CommandInset url", i)
1247 n = find_token(document.body, "name", i)
1249 # place the URL name in typewriter before the new URL insert
1250 # grab the name 'bla' from the e.g. the line 'name "bla"',
1251 # therefore start with the 6th character
1252 name = document.body[n][6:-1]
1253 newname = [name + " "]
1254 document.body[i:i] = newname
1256 j = find_token(document.body, "target", i)
1258 document.warning("Malformed LyX document: Can't find target for url inset")
1261 target = document.body[j][8:-1]
1262 k = find_token(document.body, "\\end_inset", j)
1264 document.warning("Malformed LyX document: Can't find end of url inset")
1267 newstuff = ["\\begin_inset Flex URL",
1268 "status collapsed", "",
1269 "\\begin_layout Standard",
1274 document.body[i:k] = newstuff
1277 def convert_ams_classes(document):
1278 tc = document.textclass
1279 if (tc != "amsart" and tc != "amsart-plain" and
1280 tc != "amsart-seq" and tc != "amsbook"):
1282 if tc == "amsart-plain":
1283 document.textclass = "amsart"
1284 document.set_textclass()
1285 document.add_module("Theorems (Starred)")
1287 if tc == "amsart-seq":
1288 document.textclass = "amsart"
1289 document.set_textclass()
1290 document.add_module("Theorems (AMS)")
1292 #Now we want to see if any of the environments in the extended theorems
1293 #module were used in this document. If so, we'll add that module, too.
1294 layouts = ["Criterion", "Algorithm", "Axiom", "Condition", "Note", \
1295 "Notation", "Summary", "Acknowledgement", "Conclusion", "Fact", \
1298 r = re.compile(r'^\\begin_layout (.*?)\*?\s*$')
1301 i = find_token(document.body, "\\begin_layout", i)
1304 m = r.match(document.body[i])
1306 document.warning("Weirdly formed \\begin_layout at line %d of body!" % i)
1310 if layouts.count(m) != 0:
1311 document.add_module("Theorems (AMS-Extended)")
1315 def revert_href(document):
1316 'Reverts hyperlink insets (href) to url insets (url)'
1319 i = find_token(document.body, "\\begin_inset CommandInset href", i)
1322 document.body[i : i + 2] = \
1323 ["\\begin_inset CommandInset url", "LatexCommand url"]
1326 def revert_url(document):
1327 'Reverts Flex URL insets to old-style URL insets'
1330 i = find_token(document.body, "\\begin_inset Flex URL", i)
1333 j = find_end_of_inset(document.body, i)
1335 document.warning("Can't find end of inset in revert_url!")
1337 k = find_default_layout(document, i, j)
1339 document.warning("Can't find default layout in revert_url!")
1342 l = find_end_of(document.body, k, "\\begin_layout", "\\end_layout")
1343 if l == -1 or l >= j:
1344 document.warning("Can't find end of default layout in revert_url!")
1347 # OK, so the inset's data is between lines k and l.
1348 data = " ".join(document.body[k+1:l])
1350 newinset = ["\\begin_inset LatexCommand url", "target \"" + data + "\"",\
1352 document.body[i:j+1] = newinset
1353 i = i + len(newinset)
1356 def convert_include(document):
1357 'Converts include insets to new format.'
1359 r = re.compile(r'\\begin_inset Include\s+\\([^{]+){([^}]*)}(?:\[(.*)\])?')
1361 i = find_token(document.body, "\\begin_inset Include", i)
1364 line = document.body[i]
1365 previewline = document.body[i + 1]
1368 document.warning("Unable to match line " + str(i) + " of body!")
1374 insertion = ["\\begin_inset CommandInset include",
1375 "LatexCommand " + cmd, previewline,
1376 "filename \"" + fn + "\""]
1379 insertion.append("lstparams " + '"' + opt + '"')
1381 document.body[i : i + 2] = insertion
1385 def revert_include(document):
1386 'Reverts include insets to old format.'
1388 r0 = re.compile('preview.*')
1389 r1 = re.compile('LatexCommand (.+)')
1390 r2 = re.compile('filename "(.+)"')
1391 r3 = re.compile('lstparams "(.*)"')
1393 i = find_token(document.body, "\\begin_inset CommandInset include", i)
1397 if r0.match(document.body[nextline]):
1398 previewline = document.body[nextline]
1402 m = r1.match(document.body[nextline])
1404 document.warning("Malformed LyX document: No LatexCommand line for `" +
1405 document.body[i] + "' on line " + str(i) + ".")
1410 m = r2.match(document.body[nextline])
1412 document.warning("Malformed LyX document: No filename line for `" + \
1413 document.body[i] + "' on line " + str(i) + ".")
1419 if (cmd == "lstinputlisting"):
1420 m = r3.match(document.body[nextline])
1422 options = m.group(1)
1425 newline = "\\begin_inset Include \\" + cmd + "{" + fn + "}"
1427 newline += ("[" + options + "]")
1428 insertion = [newline]
1429 if previewline != "":
1430 insertion.append(previewline)
1431 document.body[i : nextline] = insertion
1435 def revert_albanian(document):
1436 "Set language Albanian to English"
1438 if document.language == "albanian":
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 albanian", j)
1448 document.body[j] = document.body[j].replace("\\lang albanian", "\\lang english")
1452 def revert_lowersorbian(document):
1453 "Set language lower Sorbian to English"
1455 if document.language == "lowersorbian":
1456 document.language = "english"
1457 i = find_token(document.header, "\\language", 0)
1459 document.header[i] = "\\language english"
1462 j = find_token(document.body, "\\lang lowersorbian", j)
1465 document.body[j] = document.body[j].replace("\\lang lowersorbian", "\\lang english")
1469 def revert_uppersorbian(document):
1470 "Set language uppersorbian to usorbian as this was used in LyX 1.5"
1472 if document.language == "uppersorbian":
1473 document.language = "usorbian"
1474 i = find_token(document.header, "\\language", 0)
1476 document.header[i] = "\\language usorbian"
1479 j = find_token(document.body, "\\lang uppersorbian", j)
1482 document.body[j] = document.body[j].replace("\\lang uppersorbian", "\\lang usorbian")
1486 def convert_usorbian(document):
1487 "Set language usorbian to uppersorbian"
1489 if document.language == "usorbian":
1490 document.language = "uppersorbian"
1491 i = find_token(document.header, "\\language", 0)
1493 document.header[i] = "\\language uppersorbian"
1496 j = find_token(document.body, "\\lang usorbian", j)
1499 document.body[j] = document.body[j].replace("\\lang usorbian", "\\lang uppersorbian")
1503 def revert_macro_optional_params(document):
1504 "Convert macro definitions with optional parameters into ERTs"
1505 # Stub to convert macro definitions with one or more optional parameters
1506 # into uninterpreted ERT insets
1509 def revert_hyperlinktype(document):
1510 'Reverts hyperlink type'
1514 i = find_token(document.body, "target", i)
1517 j = find_token(document.body, "type", i)
1521 del document.body[j]
1525 def revert_pagebreak(document):
1526 'Reverts pagebreak to ERT'
1529 i = find_token(document.body, "\\pagebreak", i)
1532 document.body[i] = '\\begin_inset ERT\nstatus collapsed\n\n' \
1533 '\\begin_layout Standard\n\n\n\\backslash\n' \
1534 'pagebreak{}\n\\end_layout\n\n\\end_inset\n\n'
1538 def revert_linebreak(document):
1539 'Reverts linebreak to ERT'
1542 i = find_token(document.body, "\\linebreak", i)
1545 document.body[i] = '\\begin_inset ERT\nstatus collapsed\n\n' \
1546 '\\begin_layout Standard\n\n\n\\backslash\n' \
1547 'linebreak{}\n\\end_layout\n\n\\end_inset\n\n'
1551 def revert_latin(document):
1552 "Set language Latin to English"
1554 if document.language == "latin":
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 latin", j)
1564 document.body[j] = document.body[j].replace("\\lang latin", "\\lang english")
1568 def revert_samin(document):
1569 "Set language North Sami to English"
1571 if document.language == "samin":
1572 document.language = "english"
1573 i = find_token(document.header, "\\language", 0)
1575 document.header[i] = "\\language english"
1578 j = find_token(document.body, "\\lang samin", j)
1581 document.body[j] = document.body[j].replace("\\lang samin", "\\lang english")
1585 def convert_serbocroatian(document):
1586 "Set language Serbocroatian to Croatian as this was really Croatian in LyX 1.5"
1588 if document.language == "serbocroatian":
1589 document.language = "croatian"
1590 i = find_token(document.header, "\\language", 0)
1592 document.header[i] = "\\language croatian"
1595 j = find_token(document.body, "\\lang serbocroatian", j)
1598 document.body[j] = document.body[j].replace("\\lang serbocroatian", "\\lang croatian")
1602 def convert_framed_notes(document):
1603 "Convert framed notes to boxes. "
1606 i = find_tokens(document.body, ["\\begin_inset Note Framed", "\\begin_inset Note Shaded"], i)
1609 subst = [document.body[i].replace("\\begin_inset Note", "\\begin_inset Box"),
1618 'height_special "totalheight"']
1619 document.body[i:i+1] = subst
1623 def convert_module_names(document):
1624 modulemap = { 'Braille' : 'braille', 'Endnote' : 'endnotes', 'Foot to End' : 'foottoend',\
1625 'Hanging' : 'hanging', 'Linguistics' : 'linguistics', 'Logical Markup' : 'logicalmkup', \
1626 'Theorems (AMS-Extended)' : 'theorems-ams-extended', 'Theorems (AMS)' : 'theorems-ams', \
1627 'Theorems (Order By Chapter)' : 'theorems-chap', 'Theorems (Order By Section)' : 'theorems-sec', \
1628 'Theorems (Starred)' : 'theorems-starred', 'Theorems' : 'theorems-std' }
1629 modlist = document.get_module_list()
1630 if len(modlist) == 0:
1634 if modulemap.has_key(mod):
1635 newmodlist.append(modulemap[mod])
1637 document.warning("Can't find module %s in the module map!" % mod)
1638 newmodlist.append(mod)
1639 document.set_module_list(newmodlist)
1642 def revert_module_names(document):
1643 modulemap = { 'braille' : 'Braille', 'endnotes' : 'Endnote', 'foottoend' : 'Foot to End',\
1644 'hanging' : 'Hanging', 'linguistics' : 'Linguistics', 'logicalmkup' : 'Logical Markup', \
1645 'theorems-ams-extended' : 'Theorems (AMS-Extended)', 'theorems-ams' : 'Theorems (AMS)', \
1646 'theorems-chap' : 'Theorems (Order By Chapter)', 'theorems-sec' : 'Theorems (Order By Section)', \
1647 'theorems-starred' : 'Theorems (Starred)', 'theorems-std' : 'Theorems'}
1648 modlist = document.get_module_list()
1649 if len(modlist) == 0:
1653 if modulemap.has_key(mod):
1654 newmodlist.append(modulemap[mod])
1656 document.warning("Can't find module %s in the module map!" % mod)
1657 newmodlist.append(mod)
1658 document.set_module_list(newmodlist)
1661 def revert_colsep(document):
1662 i = find_token(document.header, "\\columnsep", 0)
1665 colsepline = document.header[i]
1666 r = re.compile(r'\\columnsep (.*)')
1667 m = r.match(colsepline)
1669 document.warning("Malformed column separation line!")
1672 del document.header[i]
1673 #it seems to be safe to add the package even if it is already used
1674 pretext = ["\\usepackage{geometry}", "\\geometry{columnsep=" + colsep + "}"]
1676 add_to_preamble(document, pretext)
1679 def revert_framed_notes(document):
1680 "Revert framed boxes to notes. "
1683 i = find_tokens(document.body, ["\\begin_inset Box Framed", "\\begin_inset Box Shaded"], i)
1687 j = find_end_of_inset(document.body, i + 1)
1690 document.warning("Malformed LyX document: Could not find end of Box inset.")
1691 k = find_token(document.body, "status", i + 1, j)
1693 document.warning("Malformed LyX document: Missing `status' tag in Box inset.")
1695 status = document.body[k]
1696 l = find_default_layout(document, i + 1, j)
1698 document.warning("Malformed LyX document: Missing `\\begin_layout' in Box inset.")
1700 m = find_token(document.body, "\\end_layout", i + 1, j)
1702 document.warning("Malformed LyX document: Missing `\\end_layout' in Box inset.")
1704 ibox = find_token(document.body, "has_inner_box 1", i + 1, k)
1705 pbox = find_token(document.body, "use_parbox 1", i + 1, k)
1706 if ibox == -1 and pbox == -1:
1707 document.body[i] = document.body[i].replace("\\begin_inset Box", "\\begin_inset Note")
1708 del document.body[i+1:k]
1710 document.body[i] = document.body[i].replace("\\begin_inset Box Shaded", "\\begin_inset Box Frameless")
1711 subst1 = [document.body[l],
1712 "\\begin_inset Note Shaded",
1714 '\\begin_layout Standard']
1715 document.body[l:l + 1] = subst1
1716 subst2 = [document.body[m], "\\end_layout", "\\end_inset"]
1717 document.body[m:m + 1] = subst2
1721 def revert_slash(document):
1722 'Revert \\SpecialChar \\slash{} to ERT'
1723 r = re.compile(r'\\SpecialChar \\slash{}')
1725 while i < len(document.body):
1726 m = r.match(document.body[i])
1728 subst = ['\\begin_inset ERT',
1729 'status collapsed', '',
1730 '\\begin_layout Standard',
1731 '', '', '\\backslash',
1735 document.body[i: i+1] = subst
1741 def revert_nobreakdash(document):
1742 'Revert \\SpecialChar \\nobreakdash- to ERT'
1744 while i < len(document.body):
1745 line = document.body[i]
1746 r = re.compile(r'\\SpecialChar \\nobreakdash-')
1749 subst = ['\\begin_inset ERT',
1750 'status collapsed', '',
1751 '\\begin_layout Standard', '', '',
1756 document.body[i:i+1] = subst
1758 j = find_token(document.header, "\\use_amsmath", 0)
1760 document.warning("Malformed LyX document: Missing '\\use_amsmath'.")
1762 document.header[j] = "\\use_amsmath 2"
1767 #Returns number of lines added/removed
1768 def revert_nocite_key(body, start, end):
1769 'key "..." -> \nocite{...}'
1770 r = re.compile(r'^key "(.*)"')
1774 m = r.match(body[i])
1776 body[i:i+1] = ["\\backslash", "nocite{" + m.group(1) + "}"]
1777 j += 1 # because we added a line
1778 i += 2 # skip that line
1781 j -= 1 # because we deleted a line
1782 # no need to change i, since it now points to the next line
1786 def revert_nocite(document):
1787 "Revert LatexCommand nocite to ERT"
1790 i = find_token(document.body, "\\begin_inset CommandInset citation", i)
1793 if (document.body[i+1] != "LatexCommand nocite"):
1794 # note that we already incremented i
1797 insetEnd = find_end_of_inset(document.body, i)
1799 #this should not happen
1800 document.warning("End of CommandInset citation not found in revert_nocite!")
1803 paramLocation = i + 2 #start of the inset's parameters
1805 document.body[i:i+2] = \
1806 ["\\begin_inset ERT", "status collapsed", "", "\\begin_layout Standard"]
1807 # that added two lines
1810 #print insetEnd, document.body[i: insetEnd + 1]
1811 insetEnd += revert_nocite_key(document.body, paramLocation, insetEnd)
1812 #print insetEnd, document.body[i: insetEnd + 1]
1813 document.body.insert(insetEnd, "\\end_layout")
1814 document.body.insert(insetEnd + 1, "")
1818 def revert_btprintall(document):
1819 "Revert (non-bibtopic) btPrintAll option to ERT \nocite{*}"
1820 i = find_token(document.header, '\\use_bibtopic', 0)
1822 document.warning("Malformed lyx document: Missing '\\use_bibtopic'.")
1824 if get_value(document.header, '\\use_bibtopic', 0) == "false":
1826 while i < len(document.body):
1827 i = find_token(document.body, "\\begin_inset CommandInset bibtex", i)
1830 j = find_end_of_inset(document.body, i + 1)
1832 #this should not happen
1833 document.warning("End of CommandInset bibtex not found in revert_btprintall!")
1834 j = len(document.body)
1835 # this range isn't really right, but it should be OK, since we shouldn't
1836 # see more than one matching line in each inset
1838 for k in range(i, j):
1839 if (document.body[k] == 'btprint "btPrintAll"'):
1840 del document.body[k]
1841 subst = ["\\begin_inset ERT",
1842 "status collapsed", "",
1843 "\\begin_layout Standard", "",
1848 document.body[i:i] = subst
1849 addlines = addedlines + len(subst) - 1
1853 def revert_bahasam(document):
1854 "Set language Bahasa Malaysia to Bahasa Indonesia"
1856 if document.language == "bahasam":
1857 document.language = "bahasa"
1858 i = find_token(document.header, "\\language", 0)
1860 document.header[i] = "\\language bahasa"
1863 j = find_token(document.body, "\\lang bahasam", j)
1866 document.body[j] = document.body[j].replace("\\lang bahasam", "\\lang bahasa")
1870 def revert_interlingua(document):
1871 "Set language Interlingua to English"
1873 if document.language == "interlingua":
1874 document.language = "english"
1875 i = find_token(document.header, "\\language", 0)
1877 document.header[i] = "\\language english"
1880 j = find_token(document.body, "\\lang interlingua", j)
1883 document.body[j] = document.body[j].replace("\\lang interlingua", "\\lang english")
1887 def revert_serbianlatin(document):
1888 "Set language Serbian-Latin to Croatian"
1890 if document.language == "serbian-latin":
1891 document.language = "croatian"
1892 i = find_token(document.header, "\\language", 0)
1894 document.header[i] = "\\language croatian"
1897 j = find_token(document.body, "\\lang serbian-latin", j)
1900 document.body[j] = document.body[j].replace("\\lang serbian-latin", "\\lang croatian")
1904 def revert_rotfloat(document):
1905 " Revert sideways custom floats. "
1908 # whitespace intended (exclude \\begin_inset FloatList)
1909 i = find_token(document.body, "\\begin_inset Float ", i)
1912 line = document.body[i]
1913 r = re.compile(r'\\begin_inset Float (.*)$')
1916 document.warning("Unable to match line " + str(i) + " of body!")
1919 floattype = m.group(1)
1920 if floattype == "figure" or floattype == "table":
1923 j = find_end_of_inset(document.body, i)
1925 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_rotfloat.")
1929 if get_value(document.body, 'sideways', i, j) == "false":
1932 l = find_default_layout(document, i + 1, j)
1934 document.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
1936 subst = ['\\begin_layout Standard',
1937 '\\begin_inset ERT',
1938 'status collapsed', '',
1939 '\\begin_layout Standard', '', '',
1941 'end{sideways' + floattype + '}',
1942 '\\end_layout', '', '\\end_inset']
1943 document.body[j : j+1] = subst
1944 addedLines = len(subst) - 1
1945 del document.body[i+1 : l]
1946 addedLines -= (l-1) - (i+1)
1947 subst = ['\\begin_inset ERT', 'status collapsed', '',
1948 '\\begin_layout Standard', '', '', '\\backslash',
1949 'begin{sideways' + floattype + '}',
1950 '\\end_layout', '', '\\end_inset', '',
1952 document.body[i : i+1] = subst
1953 addedLines += len(subst) - 1
1954 if floattype == "algorithm":
1955 add_to_preamble(document,
1956 ['% Commands inserted by lyx2lyx for sideways algorithm float',
1957 '\\usepackage{rotfloat}',
1958 '\\floatstyle{ruled}',
1959 '\\newfloat{algorithm}{tbp}{loa}',
1960 '\\floatname{algorithm}{Algorithm}'])
1962 document.warning("Cannot create preamble definition for custom float" + floattype + ".")
1966 def revert_widesideways(document):
1967 " Revert wide sideways floats. "
1970 # whitespace intended (exclude \\begin_inset FloatList)
1971 i = find_token(document.body, '\\begin_inset Float ', i)
1974 line = document.body[i]
1975 r = re.compile(r'\\begin_inset Float (.*)$')
1978 document.warning("Unable to match line " + str(i) + " of body!")
1981 floattype = m.group(1)
1982 if floattype != "figure" and floattype != "table":
1985 j = find_end_of_inset(document.body, i)
1987 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_widesideways.")
1990 if get_value(document.body, 'sideways', i, j) == "false" or \
1991 get_value(document.body, 'wide', i, j) == "false":
1994 l = find_default_layout(document, i + 1, j)
1996 document.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
1998 subst = ['\\begin_layout Standard', '\\begin_inset ERT',
1999 'status collapsed', '',
2000 '\\begin_layout Standard', '', '', '\\backslash',
2001 'end{sideways' + floattype + '*}',
2002 '\\end_layout', '', '\\end_inset']
2003 document.body[j : j+1] = subst
2004 addedLines = len(subst) - 1
2005 del document.body[i+1:l-1]
2006 addedLines -= (l-1) - (i+1)
2007 subst = ['\\begin_inset ERT', 'status collapsed', '',
2008 '\\begin_layout Standard', '', '', '\\backslash',
2009 'begin{sideways' + floattype + '*}', '\\end_layout', '',
2010 '\\end_inset', '', '\\end_layout', '']
2011 document.body[i : i+1] = subst
2012 addedLines += len(subst) - 1
2013 add_to_preamble(document, ['\\usepackage{rotfloat}\n'])
2017 def revert_inset_embedding(document, type):
2018 ' Remove embed tag from certain type of insets'
2021 i = find_token(document.body, "\\begin_inset %s" % type, i)
2024 j = find_end_of_inset(document.body, i)
2026 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_inset_embedding.")
2029 k = find_token(document.body, "\tembed", i, j)
2031 k = find_token(document.body, "embed", i, j)
2033 del document.body[k]
2037 def revert_external_embedding(document):
2038 ' Remove embed tag from external inset '
2039 revert_inset_embedding(document, 'External')
2042 def convert_subfig(document):
2043 " Convert subfigures to subfloats. "
2046 i = find_token(document.body, '\\begin_inset Graphics', i)
2049 endInset = find_end_of_inset(document.body, i)
2051 document.warning("Malformed lyx document: Missing '\\end_inset' in convert_subfig.")
2054 k = find_token(document.body, '\tsubcaption', i, endInset)
2058 l = find_token(document.body, '\tsubcaptionText', i, endInset)
2060 document.warning("Malformed lyx document: Can't find subcaptionText!")
2063 caption = document.body[l][16:].strip('"')
2064 del document.body[l]
2065 del document.body[k]
2067 subst = ['\\begin_inset Float figure', 'wide false', 'sideways false',
2068 'status open', '', '\\begin_layout Plain Layout', '\\begin_inset Caption',
2069 '', '\\begin_layout Plain Layout'] + latex2lyx(caption) + \
2070 [ '\\end_layout', '', '\\end_inset', '',
2071 '\\end_layout', '', '\\begin_layout Plain Layout']
2072 document.body[i : i] = subst
2073 addedLines += len(subst)
2074 endInset += addedLines
2075 subst = ['', '\\end_inset', '', '\\end_layout']
2076 document.body[endInset : endInset] = subst
2077 addedLines += len(subst)
2081 def revert_subfig(document):
2082 " Revert subfloats. "
2085 # whitespace intended (exclude \\begin_inset FloatList)
2086 i = find_tokens(document.body, ['\\begin_inset Float ', '\\begin_inset Wrap'], i)
2092 j = find_end_of_inset(document.body, i)
2094 document.warning("Malformed lyx document: Missing '\\end_inset' (float) at line " + str(i + len(document.header)) + ".\n\t" + document.body[i])
2095 # document.warning(document.body[i-1] + "\n" + document.body[i+1])
2097 continue # this will get us back to the outer loop, since j == -1
2098 # look for embedded float (= subfloat)
2099 # whitespace intended (exclude \\begin_inset FloatList)
2100 k = find_token(document.body, '\\begin_inset Float ', i + 1, j)
2103 l = find_end_of_inset(document.body, k)
2105 document.warning("Malformed lyx document: Missing '\\end_inset' (embedded float).")
2108 continue # escape to the outer loop
2109 m = find_default_layout(document, k + 1, l)
2111 cap = find_token(document.body, '\\begin_inset Caption', k + 1, l)
2116 capend = find_end_of_inset(document.body, cap)
2118 document.warning("Malformed lyx document: Missing '\\end_inset' (caption).")
2122 lbl = find_token(document.body, '\\begin_inset CommandInset label', cap, capend)
2124 lblend = find_end_of_inset(document.body, lbl + 1)
2126 document.warning("Malformed lyx document: Missing '\\end_inset' (label).")
2128 for line in document.body[lbl:lblend + 1]:
2129 if line.startswith('name '):
2130 label = line.split()[1].strip('"')
2137 opt = find_token(document.body, '\\begin_inset OptArg', cap, capend)
2139 optend = find_end_of_inset(document.body, opt)
2141 document.warning("Malformed lyx document: Missing '\\end_inset' (OptArg).")
2143 optc = find_default_layout(document, opt, optend)
2145 document.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
2147 optcend = find_end_of(document.body, optc, "\\begin_layout", "\\end_layout")
2148 for line in document.body[optc:optcend]:
2149 if not line.startswith('\\'):
2150 shortcap += line.strip()
2154 for line in document.body[cap:capend]:
2155 if line in document.body[lbl:lblend]:
2157 elif line in document.body[opt:optend]:
2159 elif not line.startswith('\\'):
2160 caption += line.strip()
2162 caption += "\\backslash\nlabel{" + label + "}"
2163 subst = '\\begin_layout Plain Layout\n\\begin_inset ERT\nstatus collapsed\n\n' \
2164 '\\begin_layout Plain Layout\n\n}\n\\end_layout\n\n\\end_inset\n\n' \
2165 '\\end_layout\n\n\\begin_layout Plain Layout\n'
2166 subst = subst.split('\n')
2167 document.body[l : l+1] = subst
2168 addedLines = len(subst) - 1
2169 # this is before l and so is unchanged by the multiline insertion
2171 del document.body[cap:capend+1]
2172 addedLines -= (capend + 1 - cap)
2173 del document.body[k+1:m-1]
2174 addedLines -= (m - 1 - (k + 1))
2175 insertion = '\\begin_inset ERT\nstatus collapsed\n\n' \
2176 '\\begin_layout Plain Layout\n\n\\backslash\n' \
2178 if len(shortcap) > 0:
2179 insertion = insertion + "[" + shortcap + "]"
2180 if len(caption) > 0:
2181 insertion = insertion + "[" + caption + "]"
2182 insertion = insertion + '{%\n\\end_layout\n\n\\end_inset\n\n\\end_layout\n'
2183 insertion = insertion.split('\n')
2184 document.body[k : k + 1] = insertion
2185 addedLines += len(insertion) - 1
2186 add_to_preamble(document, ['\\usepackage{subfig}\n'])
2190 def revert_wrapplacement(document):
2191 " Revert placement options wrap floats (wrapfig). "
2194 i = find_token(document.body, "\\begin_inset Wrap figure", i)
2197 e = find_end_of_inset(document.body, i)
2198 j = find_token(document.body, "placement", i + 1, e)
2200 document.warning("Malformed LyX document: Couldn't find placement parameter of wrap float.")
2203 r = re.compile("placement (o|i|l|r)")
2204 m = r.match(document.body[j])
2206 document.warning("Malformed LyX document: Placement option isn't O|I|R|L!")
2207 document.body[j] = "placement " + m.group(1).lower()
2211 def remove_extra_embedded_files(document):
2212 " Remove \extra_embedded_files from buffer params "
2213 i = find_token(document.header, '\\extra_embedded_files', 0)
2216 document.header.pop(i)
2219 def convert_spaceinset(document):
2220 " Convert '\\InsetSpace foo' to '\\begin_inset Space foo\n\\end_inset' "
2222 while i < len(document.body):
2223 m = re.match(r'(.*)\\InsetSpace (.*)', document.body[i])
2227 subst = [before, "\\begin_inset Space " + after, "\\end_inset"]
2228 document.body[i: i+1] = subst
2234 def revert_spaceinset(document):
2235 " Revert '\\begin_inset Space foo\n\\end_inset' to '\\InsetSpace foo' "
2238 i = find_token(document.body, "\\begin_inset Space", i)
2241 j = find_end_of_inset(document.body, i)
2243 document.warning("Malformed LyX document: Could not find end of space inset.")
2245 document.body[i] = document.body[i].replace('\\begin_inset Space', '\\InsetSpace')
2246 del document.body[j]
2249 def convert_hfill(document):
2250 " Convert hfill to space inset "
2253 i = find_token(document.body, "\\hfill", i)
2256 subst = document.body[i].replace('\\hfill', \
2257 '\n\\begin_inset Space \\hfill{}\n\\end_inset')
2258 subst = subst.split('\n')
2259 document.body[i : i+1] = subst
2263 def revert_hfills(document):
2264 ' Revert \\hfill commands '
2265 hfill = re.compile(r'\\hfill')
2266 dotfill = re.compile(r'\\dotfill')
2267 hrulefill = re.compile(r'\\hrulefill')
2270 i = find_token(document.body, "\\InsetSpace", i)
2273 if hfill.search(document.body[i]):
2274 document.body[i] = \
2275 document.body[i].replace('\\InsetSpace \\hfill{}', '\\hfill')
2278 if dotfill.search(document.body[i]):
2279 subst = document.body[i].replace('\\InsetSpace \\dotfill{}', \
2280 '\\begin_inset ERT\nstatus collapsed\n\n' \
2281 '\\begin_layout Standard\n\n\n\\backslash\n' \
2282 'dotfill{}\n\\end_layout\n\n\\end_inset\n\n')
2283 subst = subst.split('\n')
2284 document.body[i : i+1] = subst
2287 if hrulefill.search(document.body[i]):
2288 subst = document.body[i].replace('\\InsetSpace \\hrulefill{}', \
2289 '\\begin_inset ERT\nstatus collapsed\n\n' \
2290 '\\begin_layout Standard\n\n\n\\backslash\n' \
2291 'hrulefill{}\n\\end_layout\n\n\\end_inset\n\n')
2292 subst = subst.split('\n')
2293 document.body[i : i+1] = subst
2298 def revert_hspace(document):
2299 ' Revert \\InsetSpace \\hspace{} to ERT '
2301 hspace = re.compile(r'\\hspace{}')
2302 hstar = re.compile(r'\\hspace\*{}')
2304 i = find_token(document.body, "\\InsetSpace \\hspace", i)
2307 length = get_value(document.body, '\\length', i+1)
2309 document.warning("Malformed lyx document: Missing '\\length' in Space inset.")
2311 del document.body[i+1]
2313 if hstar.search(document.body[i]):
2314 subst = document.body[i].replace('\\InsetSpace \\hspace*{}', \
2315 '\\begin_inset ERT\nstatus collapsed\n\n' \
2316 '\\begin_layout Standard\n\n\n\\backslash\n' \
2317 'hspace*{' + length + '}\n\\end_layout\n\n\\end_inset\n\n')
2318 subst = subst.split('\n')
2319 document.body[i : i+1] = subst
2320 addedLines += len(subst) - 1
2323 if hspace.search(document.body[i]):
2324 subst = document.body[i].replace('\\InsetSpace \\hspace{}', \
2325 '\\begin_inset ERT\nstatus collapsed\n\n' \
2326 '\\begin_layout Standard\n\n\n\\backslash\n' \
2327 'hspace{' + length + '}\n\\end_layout\n\n\\end_inset\n\n')
2328 subst = subst.split('\n')
2329 document.body[i : i+1] = subst
2330 addedLines += len(subst) - 1
2336 def revert_protected_hfill(document):
2337 ' Revert \\begin_inset Space \\hspace*{\\fill} to ERT '
2340 i = find_token(document.body, '\\begin_inset Space \\hspace*{\\fill}', i)
2343 j = find_end_of_inset(document.body, i)
2345 document.warning("Malformed LyX document: Could not find end of space inset.")
2347 del document.body[j]
2348 subst = document.body[i].replace('\\begin_inset Space \\hspace*{\\fill}', \
2349 '\\begin_inset ERT\nstatus collapsed\n\n' \
2350 '\\begin_layout Standard\n\n\n\\backslash\n' \
2351 'hspace*{\n\\backslash\nfill}\n\\end_layout\n\n\\end_inset\n\n')
2352 subst = subst.split('\n')
2353 document.body[i : i+1] = subst
2357 def revert_leftarrowfill(document):
2358 ' Revert \\begin_inset Space \\leftarrowfill{} to ERT '
2361 i = find_token(document.body, '\\begin_inset Space \\leftarrowfill{}', i)
2364 j = find_end_of_inset(document.body, i)
2366 document.warning("Malformed LyX document: Could not find end of space inset.")
2368 del document.body[j]
2369 subst = document.body[i].replace('\\begin_inset Space \\leftarrowfill{}', \
2370 '\\begin_inset ERT\nstatus collapsed\n\n' \
2371 '\\begin_layout Standard\n\n\n\\backslash\n' \
2372 'leftarrowfill{}\n\\end_layout\n\n\\end_inset\n\n')
2373 subst = subst.split('\n')
2374 document.body[i : i+1] = subst
2378 def revert_rightarrowfill(document):
2379 ' Revert \\begin_inset Space \\rightarrowfill{} to ERT '
2382 i = find_token(document.body, '\\begin_inset Space \\rightarrowfill{}', i)
2385 j = find_end_of_inset(document.body, i)
2387 document.warning("Malformed LyX document: Could not find end of space inset.")
2389 del document.body[j]
2390 subst = document.body[i].replace('\\begin_inset Space \\rightarrowfill{}', \
2391 '\\begin_inset ERT\nstatus collapsed\n\n' \
2392 '\\begin_layout Standard\n\n\n\\backslash\n' \
2393 'rightarrowfill{}\n\\end_layout\n\n\\end_inset\n\n')
2394 subst = subst.split('\n')
2395 document.body[i : i+1] = subst
2399 def revert_upbracefill(document):
2400 ' Revert \\begin_inset Space \\upbracefill{} to ERT '
2403 i = find_token(document.body, '\\begin_inset Space \\upbracefill{}', i)
2406 j = find_end_of_inset(document.body, i)
2408 document.warning("Malformed LyX document: Could not find end of space inset.")
2410 del document.body[j]
2411 subst = document.body[i].replace('\\begin_inset Space \\upbracefill{}', \
2412 '\\begin_inset ERT\nstatus collapsed\n\n' \
2413 '\\begin_layout Standard\n\n\n\\backslash\n' \
2414 'upbracefill{}\n\\end_layout\n\n\\end_inset\n\n')
2415 subst = subst.split('\n')
2416 document.body[i : i+1] = subst
2420 def revert_downbracefill(document):
2421 ' Revert \\begin_inset Space \\downbracefill{} to ERT '
2424 i = find_token(document.body, '\\begin_inset Space \\downbracefill{}', i)
2427 j = find_end_of_inset(document.body, i)
2429 document.warning("Malformed LyX document: Could not find end of space inset.")
2431 del document.body[j]
2432 subst = document.body[i].replace('\\begin_inset Space \\downbracefill{}', \
2433 '\\begin_inset ERT\nstatus collapsed\n\n' \
2434 '\\begin_layout Standard\n\n\n\\backslash\n' \
2435 'downbracefill{}\n\\end_layout\n\n\\end_inset\n\n')
2436 subst = subst.split('\n')
2437 document.body[i : i+1] = subst
2441 def revert_local_layout(document):
2442 ' Revert local layout headers.'
2445 i = find_token(document.header, "\\begin_local_layout", i)
2448 j = find_end_of(document.header, i, "\\begin_local_layout", "\\end_local_layout")
2450 # this should not happen
2452 document.header[i : j + 1] = []
2455 def convert_pagebreaks(document):
2456 ' Convert inline Newpage insets to new format '
2459 i = find_token(document.body, '\\newpage', i)
2462 document.body[i:i+1] = ['\\begin_inset Newpage newpage',
2466 i = find_token(document.body, '\\pagebreak', i)
2469 document.body[i:i+1] = ['\\begin_inset Newpage pagebreak',
2473 i = find_token(document.body, '\\clearpage', i)
2476 document.body[i:i+1] = ['\\begin_inset Newpage clearpage',
2480 i = find_token(document.body, '\\cleardoublepage', i)
2483 document.body[i:i+1] = ['\\begin_inset Newpage cleardoublepage',
2487 def revert_pagebreaks(document):
2488 ' Revert \\begin_inset Newpage to previous inline format '
2491 i = find_token(document.body, '\\begin_inset Newpage', i)
2494 j = find_end_of_inset(document.body, i)
2496 document.warning("Malformed LyX document: Could not find end of Newpage inset.")
2498 del document.body[j]
2499 document.body[i] = document.body[i].replace('\\begin_inset Newpage newpage', '\\newpage')
2500 document.body[i] = document.body[i].replace('\\begin_inset Newpage pagebreak', '\\pagebreak')
2501 document.body[i] = document.body[i].replace('\\begin_inset Newpage clearpage', '\\clearpage')
2502 document.body[i] = document.body[i].replace('\\begin_inset Newpage cleardoublepage', '\\cleardoublepage')
2505 def convert_linebreaks(document):
2506 ' Convert inline Newline insets to new format '
2509 i = find_token(document.body, '\\newline', i)
2512 document.body[i:i+1] = ['\\begin_inset Newline newline',
2516 i = find_token(document.body, '\\linebreak', i)
2519 document.body[i:i+1] = ['\\begin_inset Newline linebreak',
2523 def revert_linebreaks(document):
2524 ' Revert \\begin_inset Newline to previous inline format '
2527 i = find_token(document.body, '\\begin_inset Newline', i)
2530 j = find_end_of_inset(document.body, i)
2532 document.warning("Malformed LyX document: Could not find end of Newline inset.")
2534 del document.body[j]
2535 document.body[i] = document.body[i].replace('\\begin_inset Newline newline', '\\newline')
2536 document.body[i] = document.body[i].replace('\\begin_inset Newline linebreak', '\\linebreak')
2539 def convert_japanese_plain(document):
2540 ' Set language japanese-plain to japanese '
2542 if document.language == "japanese-plain":
2543 document.language = "japanese"
2544 i = find_token(document.header, "\\language", 0)
2546 document.header[i] = "\\language japanese"
2549 j = find_token(document.body, "\\lang japanese-plain", j)
2552 document.body[j] = document.body[j].replace("\\lang japanese-plain", "\\lang japanese")
2556 def revert_pdfpages(document):
2557 ' Revert pdfpages external inset to ERT '
2560 i = find_token(document.body, "\\begin_inset External", i)
2563 j = find_end_of_inset(document.body, i)
2565 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_pdfpages.")
2568 if get_value(document.body, 'template', i, j) == "PDFPages":
2569 filename = get_value(document.body, 'filename', i, j)
2571 r = re.compile(r'\textra PDFLaTeX \"(.*)\"$')
2572 for k in range(i, j):
2573 m = r.match(document.body[k])
2576 angle = get_value(document.body, 'rotateAngle', i, j)
2577 width = get_value(document.body, 'width', i, j)
2578 height = get_value(document.body, 'height', i, j)
2579 scale = get_value(document.body, 'scale', i, j)
2580 keepAspectRatio = find_token(document.body, "\tkeepAspectRatio", i, j)
2584 options += ",angle=" + angle
2586 options += "angle=" + angle
2589 options += ",width=" + convert_len(width)
2591 options += "width=" + convert_len(width)
2594 options += ",height=" + convert_len(height)
2596 options += "height=" + convert_len(height)
2599 options += ",scale=" + scale
2601 options += "scale=" + scale
2602 if keepAspectRatio != '':
2604 options += ",keepaspectratio"
2606 options += "keepaspectratio"
2608 options = '[' + options + ']'
2609 del document.body[i+1:j+1]
2610 document.body[i:i+1] = ['\\begin_inset ERT',
2613 '\\begin_layout Standard',
2616 'includepdf' + options + '{' + filename + '}',
2620 add_to_preamble(document, ['\\usepackage{pdfpages}\n'])
2626 def revert_mexican(document):
2627 ' Set language Spanish(Mexico) to Spanish '
2629 if document.language == "spanish-mexico":
2630 document.language = "spanish"
2631 i = find_token(document.header, "\\language", 0)
2633 document.header[i] = "\\language spanish"
2636 j = find_token(document.body, "\\lang spanish-mexico", j)
2639 document.body[j] = document.body[j].replace("\\lang spanish-mexico", "\\lang spanish")
2643 def remove_embedding(document):
2644 ' Remove embed tag from all insets '
2645 revert_inset_embedding(document, 'Graphics')
2646 revert_inset_embedding(document, 'External')
2647 revert_inset_embedding(document, 'CommandInset include')
2648 revert_inset_embedding(document, 'CommandInset bibtex')
2651 def revert_master(document):
2652 ' Remove master param '
2653 i = find_token(document.header, "\\master", 0)
2655 del document.header[i]
2658 def revert_graphics_group(document):
2659 ' Revert group information from graphics insets '
2662 i = find_token(document.body, "\\begin_inset Graphics", i)
2665 j = find_end_of_inset(document.body, i)
2667 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_graphics_group.")
2670 k = find_token(document.body, " groupId", i, j)
2674 del document.body[k]
2678 def update_apa_styles(document):
2679 ' Replace obsolete styles '
2681 if document.textclass != "apa":
2684 obsoletedby = { "Acknowledgments": "Acknowledgements",
2685 "Section*": "Section",
2686 "Subsection*": "Subsection",
2687 "Subsubsection*": "Subsubsection",
2688 "Paragraph*": "Paragraph",
2689 "Subparagraph*": "Subparagraph"}
2692 i = find_token(document.body, "\\begin_layout", i)
2696 layout = document.body[i][14:]
2697 if layout in obsoletedby:
2698 document.body[i] = "\\begin_layout " + obsoletedby[layout]
2703 def convert_paper_sizes(document):
2704 ' exchange size options legalpaper and executivepaper to correct order '
2705 # routine is needed to fix http://bugzilla.lyx.org/show_bug.cgi?id=4868
2708 i = find_token(document.header, "\\papersize executivepaper", 0)
2710 document.header[i] = "\\papersize legalpaper"
2712 j = find_token(document.header, "\\papersize legalpaper", 0)
2714 document.header[j] = "\\papersize executivepaper"
2717 def revert_paper_sizes(document):
2718 ' exchange size options legalpaper and executivepaper to correct order '
2721 i = find_token(document.header, "\\papersize executivepaper", 0)
2723 document.header[i] = "\\papersize legalpaper"
2725 j = find_token(document.header, "\\papersize legalpaper", 0)
2727 document.header[j] = "\\papersize executivepaper"
2730 def convert_InsetSpace(document):
2731 " Convert '\\begin_inset Space foo' to '\\begin_inset space foo'"
2734 i = find_token(document.body, "\\begin_inset Space", i)
2737 document.body[i] = document.body[i].replace('\\begin_inset Space', '\\begin_inset space')
2740 def revert_InsetSpace(document):
2741 " Revert '\\begin_inset space foo' to '\\begin_inset Space foo'"
2744 i = find_token(document.body, "\\begin_inset space", i)
2747 document.body[i] = document.body[i].replace('\\begin_inset space', '\\begin_inset Space')
2750 def convert_display_enum(document):
2751 " Convert 'display foo' to 'display false/true'"
2754 i = find_token(document.body, "\tdisplay", i)
2757 val = get_value(document.body, 'display', i)
2759 document.body[i] = document.body[i].replace('none', 'false')
2760 if val == "default":
2761 document.body[i] = document.body[i].replace('default', 'true')
2762 if val == "monochrome":
2763 document.body[i] = document.body[i].replace('monochrome', 'true')
2764 if val == "grayscale":
2765 document.body[i] = document.body[i].replace('grayscale', 'true')
2767 document.body[i] = document.body[i].replace('color', 'true')
2768 if val == "preview":
2769 document.body[i] = document.body[i].replace('preview', 'true')
2773 def revert_display_enum(document):
2774 " Revert 'display false/true' to 'display none/color'"
2777 i = find_token(document.body, "\tdisplay", i)
2780 val = get_value(document.body, 'display', i)
2782 document.body[i] = document.body[i].replace('false', 'none')
2784 document.body[i] = document.body[i].replace('true', 'default')
2788 def remove_fontsCJK(document):
2789 ' Remove font_cjk param '
2790 i = find_token(document.header, "\\font_cjk", 0)
2792 del document.header[i]
2795 def convert_plain_layout(document):
2796 " Convert 'PlainLayout' to 'Plain Layout'"
2799 i = find_token(document.body, '\\begin_layout PlainLayout', i)
2802 document.body[i] = document.body[i].replace('\\begin_layout PlainLayout', \
2803 '\\begin_layout Plain Layout')
2807 def revert_plain_layout(document):
2808 " Convert 'PlainLayout' to 'Plain Layout'"
2811 i = find_token(document.body, '\\begin_layout Plain Layout', i)
2814 document.body[i] = document.body[i].replace('\\begin_layout Plain Layout', \
2815 '\\begin_layout PlainLayout')
2819 def revert_plainlayout(document):
2820 " Convert 'PlainLayout' to 'Plain Layout'"
2823 i = find_token(document.body, '\\begin_layout PlainLayout', i)
2826 # This will be incorrect for some document classes, since Standard is not always
2827 # the default. But (a) it is probably the best we can do and (b) it will actually
2828 # work, in fact, since an unknown layout will be converted to default.
2829 document.body[i] = document.body[i].replace('\\begin_layout PlainLayout', \
2830 '\\begin_layout Standard')
2834 def revert_polytonicgreek(document):
2835 "Set language polytonic Greek to Greek"
2837 if document.language == "polutonikogreek":
2838 document.language = "greek"
2839 i = find_token(document.header, "\\language", 0)
2841 document.header[i] = "\\language greek"
2844 j = find_token(document.body, "\\lang polutonikogreek", j)
2847 document.body[j] = document.body[j].replace("\\lang polutonikogreek", "\\lang greek")
2855 supported_versions = ["1.6.0","1.6"]
2856 convert = [[277, [fix_wrong_tables]],
2857 [278, [close_begin_deeper]],
2858 [279, [long_charstyle_names]],
2859 [280, [axe_show_label]],
2862 [283, [convert_flex]],
2866 [287, [convert_wrapfig_options]],
2867 [288, [convert_inset_command]],
2868 [289, [convert_latexcommand_index]],
2871 [292, [convert_japanese_cjk]],
2873 [294, [convert_pdf_options]],
2874 [295, [convert_htmlurl, convert_url]],
2875 [296, [convert_include]],
2876 [297, [convert_usorbian]],
2882 [303, [convert_serbocroatian]],
2883 [304, [convert_framed_notes]],
2890 [311, [convert_ams_classes]],
2892 [313, [convert_module_names]],
2895 [316, [convert_subfig]],
2898 [319, [convert_spaceinset, convert_hfill]],
2900 [321, [convert_tablines]],
2901 [322, [convert_plain_layout]],
2902 [323, [convert_pagebreaks]],
2903 [324, [convert_linebreaks]],
2904 [325, [convert_japanese_plain]],
2907 [328, [remove_embedding, remove_extra_embedded_files, remove_inzip_options]],
2910 [331, [convert_ltcaption]],
2912 [333, [update_apa_styles]],
2913 [334, [convert_paper_sizes]],
2914 [335, [convert_InsetSpace]],
2916 [337, [convert_display_enum]],
2920 revert = [[337, [revert_polytonicgreek]],
2921 [336, [revert_display_enum]],
2922 [335, [remove_fontsCJK]],
2923 [334, [revert_InsetSpace]],
2924 [333, [revert_paper_sizes]],
2926 [331, [revert_graphics_group]],
2927 [330, [revert_ltcaption]],
2928 [329, [revert_leftarrowfill, revert_rightarrowfill, revert_upbracefill, revert_downbracefill]],
2929 [328, [revert_master]],
2931 [326, [revert_mexican]],
2932 [325, [revert_pdfpages]],
2934 [323, [revert_linebreaks]],
2935 [322, [revert_pagebreaks]],
2936 [321, [revert_local_layout, revert_plain_layout]],
2937 [320, [revert_tablines]],
2938 [319, [revert_protected_hfill]],
2939 [318, [revert_spaceinset, revert_hfills, revert_hspace]],
2940 [317, [remove_extra_embedded_files]],
2941 [316, [revert_wrapplacement]],
2942 [315, [revert_subfig]],
2943 [314, [revert_colsep, revert_plainlayout]],
2945 [312, [revert_module_names]],
2946 [311, [revert_rotfloat, revert_widesideways]],
2947 [310, [revert_external_embedding]],
2948 [309, [revert_btprintall]],
2949 [308, [revert_nocite]],
2950 [307, [revert_serbianlatin]],
2951 [306, [revert_slash, revert_nobreakdash]],
2952 [305, [revert_interlingua]],
2953 [304, [revert_bahasam]],
2954 [303, [revert_framed_notes]],
2956 [301, [revert_latin, revert_samin]],
2957 [300, [revert_linebreak]],
2958 [299, [revert_pagebreak]],
2959 [298, [revert_hyperlinktype]],
2960 [297, [revert_macro_optional_params]],
2961 [296, [revert_albanian, revert_lowersorbian, revert_uppersorbian]],
2962 [295, [revert_include]],
2963 [294, [revert_href, revert_url]],
2964 [293, [revert_pdf_options_2]],
2965 [292, [revert_inset_info]],
2966 [291, [revert_japanese, revert_japanese_encoding, revert_japanese_cjk]],
2967 [290, [revert_vietnamese]],
2968 [289, [revert_wraptable]],
2969 [288, [revert_latexcommand_index]],
2970 [287, [revert_inset_command]],
2971 [286, [revert_wrapfig_options]],
2972 [285, [revert_pdf_options]],
2973 [284, [remove_inzip_options]],
2975 [282, [revert_flex]],
2977 [280, [revert_begin_modules]],
2978 [279, [revert_show_label]],
2979 [278, [revert_long_charstyle_names]],
2985 if __name__ == "__main__":