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 revert_japanese(document):
1084 "Set language japanese-plain to japanese"
1085 # Set document language from japanese-plain to japanese
1087 if document.language == "japanese-plain":
1088 document.language = "japanese"
1089 i = find_token(document.header, "\\language", 0)
1091 document.header[i] = "\\language japanese"
1094 j = find_token(document.body, "\\lang japanese-plain", j)
1097 document.body[j] = document.body[j].replace("\\lang japanese-plain", "\\lang japanese")
1101 def revert_japanese_encoding(document):
1102 "Set input encoding form EUC-JP-plain to EUC-JP etc."
1103 # Set input encoding form EUC-JP-plain to EUC-JP etc.
1105 i = find_token(document.header, "\\inputencoding EUC-JP-plain", 0)
1107 document.header[i] = "\\inputencoding EUC-JP"
1109 j = find_token(document.header, "\\inputencoding JIS-plain", 0)
1111 document.header[j] = "\\inputencoding JIS"
1113 k = find_token(document.header, "\\inputencoding SJIS-plain", 0)
1114 if k != -1: # convert to UTF8 since there is currently no SJIS encoding
1115 document.header[k] = "\\inputencoding UTF8"
1118 def revert_inset_info(document):
1119 'Replace info inset with its content'
1122 i = find_token(document.body, '\\begin_inset Info', i)
1125 j = find_end_of_inset(document.body, i + 1)
1128 document.warning("Malformed LyX document: Could not find end of Info inset.")
1131 for k in range(i, j+1):
1132 if document.body[k].startswith("arg"):
1133 arg = document.body[k][3:].strip().strip('"')
1134 if document.body[k].startswith("type"):
1135 type = document.body[k][4:].strip().strip('"')
1136 # I think there is a newline after \\end_inset, which should be removed.
1137 if document.body[j + 1].strip() == "":
1138 document.body[i : (j + 2)] = [type + ':' + arg]
1140 document.body[i : (j + 1)] = [type + ':' + arg]
1143 def convert_pdf_options(document):
1144 # Set the pdfusetitle tag, delete the pdf_store_options,
1145 # set quotes for bookmarksopenlevel"
1146 has_hr = get_value(document.header, "\\use_hyperref", 0, default = "0")
1148 k = find_token(document.header, "\\use_hyperref", 0)
1149 document.header.insert(k + 1, "\\pdf_pdfusetitle true")
1150 k = find_token(document.header, "\\pdf_store_options", 0)
1152 del document.header[k]
1153 i = find_token(document.header, "\\pdf_bookmarksopenlevel", k)
1155 document.header[i] = document.header[i].replace('"', '')
1158 def revert_pdf_options_2(document):
1159 # reset the pdfusetitle tag, set quotes for bookmarksopenlevel"
1160 k = find_token(document.header, "\\use_hyperref", 0)
1161 i = find_token(document.header, "\\pdf_pdfusetitle", k)
1163 del document.header[i]
1164 i = find_token(document.header, "\\pdf_bookmarksopenlevel", k)
1166 values = document.header[i].split()
1167 values[1] = ' "' + values[1] + '"'
1168 document.header[i] = ''.join(values)
1171 def convert_htmlurl(document):
1172 'Convert "htmlurl" to "href" insets for docbook'
1173 if document.backend != "docbook":
1177 i = find_token(document.body, "\\begin_inset CommandInset url", i)
1180 document.body[i] = "\\begin_inset CommandInset href"
1181 document.body[i + 1] = "LatexCommand href"
1185 def convert_url(document):
1186 'Convert url insets to url charstyles'
1187 if document.backend == "docbook":
1191 i = find_token(document.body, "\\begin_inset CommandInset url", i)
1194 n = find_token(document.body, "name", i)
1196 # place the URL name in typewriter before the new URL insert
1197 # grab the name 'bla' from the e.g. the line 'name "bla"',
1198 # therefore start with the 6th character
1199 name = document.body[n][6:-1]
1200 newname = [name + " "]
1201 document.body[i:i] = newname
1203 j = find_token(document.body, "target", i)
1205 document.warning("Malformed LyX document: Can't find target for url inset")
1208 target = document.body[j][8:-1]
1209 k = find_token(document.body, "\\end_inset", j)
1211 document.warning("Malformed LyX document: Can't find end of url inset")
1214 newstuff = ["\\begin_inset Flex URL",
1215 "status collapsed", "",
1216 "\\begin_layout Standard",
1221 document.body[i:k] = newstuff
1224 def convert_ams_classes(document):
1225 tc = document.textclass
1226 if (tc != "amsart" and tc != "amsart-plain" and
1227 tc != "amsart-seq" and tc != "amsbook"):
1229 if tc == "amsart-plain":
1230 document.textclass = "amsart"
1231 document.set_textclass()
1232 document.add_module("Theorems (Starred)")
1234 if tc == "amsart-seq":
1235 document.textclass = "amsart"
1236 document.set_textclass()
1237 document.add_module("Theorems (AMS)")
1239 #Now we want to see if any of the environments in the extended theorems
1240 #module were used in this document. If so, we'll add that module, too.
1241 layouts = ["Criterion", "Algorithm", "Axiom", "Condition", "Note", \
1242 "Notation", "Summary", "Acknowledgement", "Conclusion", "Fact", \
1245 r = re.compile(r'^\\begin_layout (.*?)\*?\s*$')
1248 i = find_token(document.body, "\\begin_layout", i)
1251 m = r.match(document.body[i])
1253 document.warning("Weirdly formed \\begin_layout at line %d of body!" % i)
1257 if layouts.count(m) != 0:
1258 document.add_module("Theorems (AMS-Extended)")
1262 def revert_href(document):
1263 'Reverts hyperlink insets (href) to url insets (url)'
1266 i = find_token(document.body, "\\begin_inset CommandInset href", i)
1269 document.body[i : i + 2] = \
1270 ["\\begin_inset CommandInset url", "LatexCommand url"]
1273 def revert_url(document):
1274 'Reverts Flex URL insets to old-style URL insets'
1277 i = find_token(document.body, "\\begin_inset Flex URL", i)
1280 j = find_end_of_inset(document.body, i)
1282 document.warning("Can't find end of inset in revert_url!")
1284 k = find_default_layout(document, i, j)
1286 document.warning("Can't find default layout in revert_url!")
1289 l = find_end_of(document.body, k, "\\begin_layout", "\\end_layout")
1290 if l == -1 or l >= j:
1291 document.warning("Can't find end of default layout in revert_url!")
1294 # OK, so the inset's data is between lines k and l.
1295 data = " ".join(document.body[k+1:l])
1297 newinset = ["\\begin_inset LatexCommand url", "target \"" + data + "\"",\
1299 document.body[i:j+1] = newinset
1300 i = i + len(newinset)
1303 def convert_include(document):
1304 'Converts include insets to new format.'
1306 r = re.compile(r'\\begin_inset Include\s+\\([^{]+){([^}]*)}(?:\[(.*)\])?')
1308 i = find_token(document.body, "\\begin_inset Include", i)
1311 line = document.body[i]
1312 previewline = document.body[i + 1]
1315 document.warning("Unable to match line " + str(i) + " of body!")
1321 insertion = ["\\begin_inset CommandInset include",
1322 "LatexCommand " + cmd, previewline,
1323 "filename \"" + fn + "\""]
1326 insertion.append("lstparams " + '"' + opt + '"')
1328 document.body[i : i + 2] = insertion
1332 def revert_include(document):
1333 'Reverts include insets to old format.'
1335 r0 = re.compile('preview.*')
1336 r1 = re.compile('LatexCommand (.+)')
1337 r2 = re.compile('filename "(.+)"')
1338 r3 = re.compile('lstparams "(.*)"')
1340 i = find_token(document.body, "\\begin_inset CommandInset include", i)
1344 if r0.match(document.body[nextline]):
1345 previewline = document.body[nextline]
1349 m = r1.match(document.body[nextline])
1351 document.warning("Malformed LyX document: No LatexCommand line for `" +
1352 document.body[i] + "' on line " + str(i) + ".")
1357 m = r2.match(document.body[nextline])
1359 document.warning("Malformed LyX document: No filename line for `" + \
1360 document.body[i] + "' on line " + str(i) + ".")
1366 if (cmd == "lstinputlisting"):
1367 m = r3.match(document.body[nextline])
1369 options = m.group(1)
1372 newline = "\\begin_inset Include \\" + cmd + "{" + fn + "}"
1374 newline += ("[" + options + "]")
1375 insertion = [newline]
1376 if previewline != "":
1377 insertion.append(previewline)
1378 document.body[i : nextline] = insertion
1382 def revert_albanian(document):
1383 "Set language Albanian to English"
1385 if document.language == "albanian":
1386 document.language = "english"
1387 i = find_token(document.header, "\\language", 0)
1389 document.header[i] = "\\language english"
1392 j = find_token(document.body, "\\lang albanian", j)
1395 document.body[j] = document.body[j].replace("\\lang albanian", "\\lang english")
1399 def revert_lowersorbian(document):
1400 "Set language lower Sorbian to English"
1402 if document.language == "lowersorbian":
1403 document.language = "english"
1404 i = find_token(document.header, "\\language", 0)
1406 document.header[i] = "\\language english"
1409 j = find_token(document.body, "\\lang lowersorbian", j)
1412 document.body[j] = document.body[j].replace("\\lang lowersorbian", "\\lang english")
1416 def revert_uppersorbian(document):
1417 "Set language uppersorbian to usorbian as this was used in LyX 1.5"
1419 if document.language == "uppersorbian":
1420 document.language = "usorbian"
1421 i = find_token(document.header, "\\language", 0)
1423 document.header[i] = "\\language usorbian"
1426 j = find_token(document.body, "\\lang uppersorbian", j)
1429 document.body[j] = document.body[j].replace("\\lang uppersorbian", "\\lang usorbian")
1433 def convert_usorbian(document):
1434 "Set language usorbian to uppersorbian"
1436 if document.language == "usorbian":
1437 document.language = "uppersorbian"
1438 i = find_token(document.header, "\\language", 0)
1440 document.header[i] = "\\language uppersorbian"
1443 j = find_token(document.body, "\\lang usorbian", j)
1446 document.body[j] = document.body[j].replace("\\lang usorbian", "\\lang uppersorbian")
1450 def revert_macro_optional_params(document):
1451 "Convert macro definitions with optional parameters into ERTs"
1452 # Stub to convert macro definitions with one or more optional parameters
1453 # into uninterpreted ERT insets
1456 def revert_hyperlinktype(document):
1457 'Reverts hyperlink type'
1461 i = find_token(document.body, "target", i)
1464 j = find_token(document.body, "type", i)
1468 del document.body[j]
1472 def revert_pagebreak(document):
1473 'Reverts pagebreak to ERT'
1476 i = find_token(document.body, "\\pagebreak", i)
1479 document.body[i] = '\\begin_inset ERT\nstatus collapsed\n\n' \
1480 '\\begin_layout Standard\n\n\n\\backslash\n' \
1481 'pagebreak{}\n\\end_layout\n\n\\end_inset\n\n'
1485 def revert_linebreak(document):
1486 'Reverts linebreak to ERT'
1489 i = find_token(document.body, "\\linebreak", i)
1492 document.body[i] = '\\begin_inset ERT\nstatus collapsed\n\n' \
1493 '\\begin_layout Standard\n\n\n\\backslash\n' \
1494 'linebreak{}\n\\end_layout\n\n\\end_inset\n\n'
1498 def revert_latin(document):
1499 "Set language Latin to English"
1501 if document.language == "latin":
1502 document.language = "english"
1503 i = find_token(document.header, "\\language", 0)
1505 document.header[i] = "\\language english"
1508 j = find_token(document.body, "\\lang latin", j)
1511 document.body[j] = document.body[j].replace("\\lang latin", "\\lang english")
1515 def revert_samin(document):
1516 "Set language North Sami to English"
1518 if document.language == "samin":
1519 document.language = "english"
1520 i = find_token(document.header, "\\language", 0)
1522 document.header[i] = "\\language english"
1525 j = find_token(document.body, "\\lang samin", j)
1528 document.body[j] = document.body[j].replace("\\lang samin", "\\lang english")
1532 def convert_serbocroatian(document):
1533 "Set language Serbocroatian to Croatian as this was really Croatian in LyX 1.5"
1535 if document.language == "serbocroatian":
1536 document.language = "croatian"
1537 i = find_token(document.header, "\\language", 0)
1539 document.header[i] = "\\language croatian"
1542 j = find_token(document.body, "\\lang serbocroatian", j)
1545 document.body[j] = document.body[j].replace("\\lang serbocroatian", "\\lang croatian")
1549 def convert_framed_notes(document):
1550 "Convert framed notes to boxes. "
1553 i = find_tokens(document.body, ["\\begin_inset Note Framed", "\\begin_inset Note Shaded"], i)
1556 subst = [document.body[i].replace("\\begin_inset Note", "\\begin_inset Box"),
1565 'height_special "totalheight"']
1566 document.body[i:i+1] = subst
1570 def convert_module_names(document):
1571 modulemap = { 'Braille' : 'braille', 'Endnote' : 'endnotes', 'Foot to End' : 'foottoend',\
1572 'Hanging' : 'hanging', 'Linguistics' : 'linguistics', 'Logical Markup' : 'logicalmkup', \
1573 'Theorems (AMS-Extended)' : 'theorems-ams-extended', 'Theorems (AMS)' : 'theorems-ams', \
1574 'Theorems (Order By Chapter)' : 'theorems-chap', 'Theorems (Order By Section)' : 'theorems-sec', \
1575 'Theorems (Starred)' : 'theorems-starred', 'Theorems' : 'theorems-std' }
1576 modlist = document.get_module_list()
1577 if len(modlist) == 0:
1581 if modulemap.has_key(mod):
1582 newmodlist.append(modulemap[mod])
1584 document.warning("Can't find module %s in the module map!" % mod)
1585 newmodlist.append(mod)
1586 document.set_module_list(newmodlist)
1589 def revert_module_names(document):
1590 modulemap = { 'braille' : 'Braille', 'endnotes' : 'Endnote', 'foottoend' : 'Foot to End',\
1591 'hanging' : 'Hanging', 'linguistics' : 'Linguistics', 'logicalmkup' : 'Logical Markup', \
1592 'theorems-ams-extended' : 'Theorems (AMS-Extended)', 'theorems-ams' : 'Theorems (AMS)', \
1593 'theorems-chap' : 'Theorems (Order By Chapter)', 'theorems-sec' : 'Theorems (Order By Section)', \
1594 'theorems-starred' : 'Theorems (Starred)', 'theorems-std' : 'Theorems'}
1595 modlist = document.get_module_list()
1596 if len(modlist) == 0:
1600 if modulemap.has_key(mod):
1601 newmodlist.append(modulemap[mod])
1603 document.warning("Can't find module %s in the module map!" % mod)
1604 newmodlist.append(mod)
1605 document.set_module_list(newmodlist)
1608 def revert_colsep(document):
1609 i = find_token(document.header, "\\columnsep", 0)
1612 colsepline = document.header[i]
1613 r = re.compile(r'\\columnsep (.*)')
1614 m = r.match(colsepline)
1616 document.warning("Malformed column separation line!")
1619 del document.header[i]
1620 #it seems to be safe to add the package even if it is already used
1621 pretext = ["\\usepackage{geometry}", "\\geometry{columnsep=" + colsep + "}"]
1623 add_to_preamble(document, pretext)
1626 def revert_framed_notes(document):
1627 "Revert framed boxes to notes. "
1630 i = find_tokens(document.body, ["\\begin_inset Box Framed", "\\begin_inset Box Shaded"], i)
1634 j = find_end_of_inset(document.body, i + 1)
1637 document.warning("Malformed LyX document: Could not find end of Box inset.")
1638 k = find_token(document.body, "status", i + 1, j)
1640 document.warning("Malformed LyX document: Missing `status' tag in Box inset.")
1642 status = document.body[k]
1643 l = find_default_layout(document, i + 1, j)
1645 document.warning("Malformed LyX document: Missing `\\begin_layout' in Box inset.")
1647 m = find_token(document.body, "\\end_layout", i + 1, j)
1649 document.warning("Malformed LyX document: Missing `\\end_layout' in Box inset.")
1651 ibox = find_token(document.body, "has_inner_box 1", i + 1, k)
1652 pbox = find_token(document.body, "use_parbox 1", i + 1, k)
1653 if ibox == -1 and pbox == -1:
1654 document.body[i] = document.body[i].replace("\\begin_inset Box", "\\begin_inset Note")
1655 del document.body[i+1:k]
1657 document.body[i] = document.body[i].replace("\\begin_inset Box Shaded", "\\begin_inset Box Frameless")
1658 subst1 = [document.body[l],
1659 "\\begin_inset Note Shaded",
1661 '\\begin_layout Standard']
1662 document.body[l:l + 1] = subst1
1663 subst2 = [document.body[m], "\\end_layout", "\\end_inset"]
1664 document.body[m:m + 1] = subst2
1668 def revert_slash(document):
1669 'Revert \\SpecialChar \\slash{} to ERT'
1670 r = re.compile(r'\\SpecialChar \\slash{}')
1672 while i < len(document.body):
1673 m = r.match(document.body[i])
1675 subst = ['\\begin_inset ERT',
1676 'status collapsed', '',
1677 '\\begin_layout Standard',
1678 '', '', '\\backslash',
1682 document.body[i: i+1] = subst
1688 def revert_nobreakdash(document):
1689 'Revert \\SpecialChar \\nobreakdash- to ERT'
1691 while i < len(document.body):
1692 line = document.body[i]
1693 r = re.compile(r'\\SpecialChar \\nobreakdash-')
1696 subst = ['\\begin_inset ERT',
1697 'status collapsed', '',
1698 '\\begin_layout Standard', '', '',
1703 document.body[i:i+1] = subst
1705 j = find_token(document.header, "\\use_amsmath", 0)
1707 document.warning("Malformed LyX document: Missing '\\use_amsmath'.")
1709 document.header[j] = "\\use_amsmath 2"
1714 #Returns number of lines added/removed
1715 def revert_nocite_key(body, start, end):
1716 'key "..." -> \nocite{...}'
1717 r = re.compile(r'^key "(.*)"')
1721 m = r.match(body[i])
1723 body[i:i+1] = ["\\backslash", "nocite{" + m.group(1) + "}"]
1724 j += 1 # because we added a line
1725 i += 2 # skip that line
1728 j -= 1 # because we deleted a line
1729 # no need to change i, since it now points to the next line
1733 def revert_nocite(document):
1734 "Revert LatexCommand nocite to ERT"
1737 i = find_token(document.body, "\\begin_inset CommandInset citation", i)
1740 if (document.body[i+1] != "LatexCommand nocite"):
1741 # note that we already incremented i
1744 insetEnd = find_end_of_inset(document.body, i)
1746 #this should not happen
1747 document.warning("End of CommandInset citation not found in revert_nocite!")
1750 paramLocation = i + 2 #start of the inset's parameters
1752 document.body[i:i+2] = \
1753 ["\\begin_inset ERT", "status collapsed", "", "\\begin_layout Standard"]
1754 # that added two lines
1757 #print insetEnd, document.body[i: insetEnd + 1]
1758 insetEnd += revert_nocite_key(document.body, paramLocation, insetEnd)
1759 #print insetEnd, document.body[i: insetEnd + 1]
1760 document.body.insert(insetEnd, "\\end_layout")
1761 document.body.insert(insetEnd + 1, "")
1765 def revert_btprintall(document):
1766 "Revert (non-bibtopic) btPrintAll option to ERT \nocite{*}"
1767 i = find_token(document.header, '\\use_bibtopic', 0)
1769 document.warning("Malformed lyx document: Missing '\\use_bibtopic'.")
1771 if get_value(document.header, '\\use_bibtopic', 0) == "false":
1773 while i < len(document.body):
1774 i = find_token(document.body, "\\begin_inset CommandInset bibtex", i)
1777 j = find_end_of_inset(document.body, i + 1)
1779 #this should not happen
1780 document.warning("End of CommandInset bibtex not found in revert_btprintall!")
1781 j = len(document.body)
1782 # this range isn't really right, but it should be OK, since we shouldn't
1783 # see more than one matching line in each inset
1785 for k in range(i, j):
1786 if (document.body[k] == 'btprint "btPrintAll"'):
1787 del document.body[k]
1788 subst = ["\\begin_inset ERT",
1789 "status collapsed", "",
1790 "\\begin_layout Standard", "",
1795 document.body[i:i] = subst
1796 addlines = addedlines + len(subst) - 1
1800 def revert_bahasam(document):
1801 "Set language Bahasa Malaysia to Bahasa Indonesia"
1803 if document.language == "bahasam":
1804 document.language = "bahasa"
1805 i = find_token(document.header, "\\language", 0)
1807 document.header[i] = "\\language bahasa"
1810 j = find_token(document.body, "\\lang bahasam", j)
1813 document.body[j] = document.body[j].replace("\\lang bahasam", "\\lang bahasa")
1817 def revert_interlingua(document):
1818 "Set language Interlingua to English"
1820 if document.language == "interlingua":
1821 document.language = "english"
1822 i = find_token(document.header, "\\language", 0)
1824 document.header[i] = "\\language english"
1827 j = find_token(document.body, "\\lang interlingua", j)
1830 document.body[j] = document.body[j].replace("\\lang interlingua", "\\lang english")
1834 def revert_serbianlatin(document):
1835 "Set language Serbian-Latin to Croatian"
1837 if document.language == "serbian-latin":
1838 document.language = "croatian"
1839 i = find_token(document.header, "\\language", 0)
1841 document.header[i] = "\\language croatian"
1844 j = find_token(document.body, "\\lang serbian-latin", j)
1847 document.body[j] = document.body[j].replace("\\lang serbian-latin", "\\lang croatian")
1851 def revert_rotfloat(document):
1852 " Revert sideways custom floats. "
1855 # whitespace intended (exclude \\begin_inset FloatList)
1856 i = find_token(document.body, "\\begin_inset Float ", i)
1859 line = document.body[i]
1860 r = re.compile(r'\\begin_inset Float (.*)$')
1863 document.warning("Unable to match line " + str(i) + " of body!")
1866 floattype = m.group(1)
1867 if floattype == "figure" or floattype == "table":
1870 j = find_end_of_inset(document.body, i)
1872 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_rotfloat.")
1876 if get_value(document.body, 'sideways', i, j) == "false":
1879 l = find_default_layout(document, i + 1, j)
1881 document.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
1883 subst = ['\\begin_layout Standard',
1884 '\\begin_inset ERT',
1885 'status collapsed', '',
1886 '\\begin_layout Standard', '', '',
1888 'end{sideways' + floattype + '}',
1889 '\\end_layout', '', '\\end_inset']
1890 document.body[j : j+1] = subst
1891 addedLines = len(subst) - 1
1892 del document.body[i+1 : l]
1893 addedLines -= (l-1) - (i+1)
1894 subst = ['\\begin_inset ERT', 'status collapsed', '',
1895 '\\begin_layout Standard', '', '', '\\backslash',
1896 'begin{sideways' + floattype + '}',
1897 '\\end_layout', '', '\\end_inset', '',
1899 document.body[i : i+1] = subst
1900 addedLines += len(subst) - 1
1901 if floattype == "algorithm":
1902 add_to_preamble(document,
1903 ['% Commands inserted by lyx2lyx for sideways algorithm float',
1904 '\\usepackage{rotfloat}',
1905 '\\floatstyle{ruled}',
1906 '\\newfloat{algorithm}{tbp}{loa}',
1907 '\\floatname{algorithm}{Algorithm}'])
1909 document.warning("Cannot create preamble definition for custom float" + floattype + ".")
1913 def revert_widesideways(document):
1914 " Revert wide sideways floats. "
1917 # whitespace intended (exclude \\begin_inset FloatList)
1918 i = find_token(document.body, '\\begin_inset Float ', i)
1921 line = document.body[i]
1922 r = re.compile(r'\\begin_inset Float (.*)$')
1925 document.warning("Unable to match line " + str(i) + " of body!")
1928 floattype = m.group(1)
1929 if floattype != "figure" and floattype != "table":
1932 j = find_end_of_inset(document.body, i)
1934 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_widesideways.")
1937 if get_value(document.body, 'sideways', i, j) == "false" or \
1938 get_value(document.body, 'wide', i, j) == "false":
1941 l = find_default_layout(document, i + 1, j)
1943 document.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
1945 subst = ['\\begin_layout Standard', '\\begin_inset ERT',
1946 'status collapsed', '',
1947 '\\begin_layout Standard', '', '', '\\backslash',
1948 'end{sideways' + floattype + '*}',
1949 '\\end_layout', '', '\\end_inset']
1950 document.body[j : j+1] = subst
1951 addedLines = len(subst) - 1
1952 del document.body[i+1:l-1]
1953 addedLines -= (l-1) - (i+1)
1954 subst = ['\\begin_inset ERT', 'status collapsed', '',
1955 '\\begin_layout Standard', '', '', '\\backslash',
1956 'begin{sideways' + floattype + '*}', '\\end_layout', '',
1957 '\\end_inset', '', '\\end_layout', '']
1958 document.body[i : i+1] = subst
1959 addedLines += len(subst) - 1
1960 add_to_preamble(document, ['\\usepackage{rotfloat}\n'])
1964 def revert_inset_embedding(document, type):
1965 ' Remove embed tag from certain type of insets'
1968 i = find_token(document.body, "\\begin_inset %s" % type, i)
1971 j = find_end_of_inset(document.body, i)
1973 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_inset_embedding.")
1976 k = find_token(document.body, "\tembed", i, j)
1978 k = find_token(document.body, "embed", i, j)
1980 del document.body[k]
1984 def revert_external_embedding(document):
1985 ' Remove embed tag from external inset '
1986 revert_inset_embedding(document, 'External')
1989 def convert_subfig(document):
1990 " Convert subfigures to subfloats. "
1993 i = find_token(document.body, '\\begin_inset Graphics', i)
1996 endInset = find_end_of_inset(document.body, i)
1998 document.warning("Malformed lyx document: Missing '\\end_inset' in convert_subfig.")
2001 k = find_token(document.body, '\tsubcaption', i, endInset)
2005 l = find_token(document.body, '\tsubcaptionText', i, endInset)
2007 document.warning("Malformed lyx document: Can't find subcaptionText!")
2010 caption = document.body[l][16:].strip('"')
2011 del document.body[l]
2012 del document.body[k]
2014 subst = ['\\begin_inset Float figure', 'wide false', 'sideways false',
2015 'status open', '', '\\begin_layout Plain Layout', '\\begin_inset Caption',
2016 '', '\\begin_layout Plain Layout'] + latex2lyx(caption) + \
2017 [ '\\end_layout', '', '\\end_inset', '',
2018 '\\end_layout', '', '\\begin_layout Plain Layout']
2019 document.body[i : i] = subst
2020 addedLines += len(subst)
2021 endInset += addedLines
2022 subst = ['', '\\end_inset', '', '\\end_layout']
2023 document.body[endInset : endInset] = subst
2024 addedLines += len(subst)
2028 def revert_subfig(document):
2029 " Revert subfloats. "
2032 # whitespace intended (exclude \\begin_inset FloatList)
2033 i = find_tokens(document.body, ['\\begin_inset Float ', '\\begin_inset Wrap'], i)
2039 j = find_end_of_inset(document.body, i)
2041 document.warning("Malformed lyx document: Missing '\\end_inset' (float) at line " + str(i + len(document.header)) + ".\n\t" + document.body[i])
2042 # document.warning(document.body[i-1] + "\n" + document.body[i+1])
2044 continue # this will get us back to the outer loop, since j == -1
2045 # look for embedded float (= subfloat)
2046 # whitespace intended (exclude \\begin_inset FloatList)
2047 k = find_token(document.body, '\\begin_inset Float ', i + 1, j)
2050 l = find_end_of_inset(document.body, k)
2052 document.warning("Malformed lyx document: Missing '\\end_inset' (embedded float).")
2055 continue # escape to the outer loop
2056 m = find_default_layout(document, k + 1, l)
2058 cap = find_token(document.body, '\\begin_inset Caption', k + 1, l)
2063 capend = find_end_of_inset(document.body, cap)
2065 document.warning("Malformed lyx document: Missing '\\end_inset' (caption).")
2069 lbl = find_token(document.body, '\\begin_inset CommandInset label', cap, capend)
2071 lblend = find_end_of_inset(document.body, lbl + 1)
2073 document.warning("Malformed lyx document: Missing '\\end_inset' (label).")
2075 for line in document.body[lbl:lblend + 1]:
2076 if line.startswith('name '):
2077 label = line.split()[1].strip('"')
2084 opt = find_token(document.body, '\\begin_inset OptArg', cap, capend)
2086 optend = find_end_of_inset(document.body, opt)
2088 document.warning("Malformed lyx document: Missing '\\end_inset' (OptArg).")
2090 optc = find_default_layout(document, opt, optend)
2092 document.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
2094 optcend = find_end_of(document.body, optc, "\\begin_layout", "\\end_layout")
2095 for line in document.body[optc:optcend]:
2096 if not line.startswith('\\'):
2097 shortcap += line.strip()
2101 for line in document.body[cap:capend]:
2102 if line in document.body[lbl:lblend]:
2104 elif line in document.body[opt:optend]:
2106 elif not line.startswith('\\'):
2107 caption += line.strip()
2109 caption += "\\backslash\nlabel{" + label + "}"
2110 subst = '\\begin_layout Plain Layout\n\\begin_inset ERT\nstatus collapsed\n\n' \
2111 '\\begin_layout Plain Layout\n\n}\n\\end_layout\n\n\\end_inset\n\n' \
2112 '\\end_layout\n\n\\begin_layout Plain Layout\n'
2113 subst = subst.split('\n')
2114 document.body[l : l+1] = subst
2115 addedLines = len(subst) - 1
2116 # this is before l and so is unchanged by the multiline insertion
2118 del document.body[cap:capend+1]
2119 addedLines -= (capend + 1 - cap)
2120 del document.body[k+1:m-1]
2121 addedLines -= (m - 1 - (k + 1))
2122 insertion = '\\begin_inset ERT\nstatus collapsed\n\n' \
2123 '\\begin_layout Plain Layout\n\n\\backslash\n' \
2125 if len(shortcap) > 0:
2126 insertion = insertion + "[" + shortcap + "]"
2127 if len(caption) > 0:
2128 insertion = insertion + "[" + caption + "]"
2129 insertion = insertion + '{%\n\\end_layout\n\n\\end_inset\n\n\\end_layout\n'
2130 insertion = insertion.split('\n')
2131 document.body[k : k + 1] = insertion
2132 addedLines += len(insertion) - 1
2133 add_to_preamble(document, ['\\usepackage{subfig}\n'])
2137 def revert_wrapplacement(document):
2138 " Revert placement options wrap floats (wrapfig). "
2141 i = find_token(document.body, "\\begin_inset Wrap figure", i)
2144 e = find_end_of_inset(document.body, i)
2145 j = find_token(document.body, "placement", i + 1, e)
2147 document.warning("Malformed LyX document: Couldn't find placement parameter of wrap float.")
2150 r = re.compile("placement (o|i|l|r)")
2151 m = r.match(document.body[j])
2153 document.warning("Malformed LyX document: Placement option isn't O|I|R|L!")
2154 document.body[j] = "placement " + m.group(1).lower()
2158 def remove_extra_embedded_files(document):
2159 " Remove \extra_embedded_files from buffer params "
2160 i = find_token(document.header, '\\extra_embedded_files', 0)
2163 document.header.pop(i)
2166 def convert_spaceinset(document):
2167 " Convert '\\InsetSpace foo' to '\\begin_inset Space foo\n\\end_inset' "
2169 while i < len(document.body):
2170 m = re.match(r'(.*)\\InsetSpace (.*)', document.body[i])
2174 subst = [before, "\\begin_inset Space " + after, "\\end_inset"]
2175 document.body[i: i+1] = subst
2181 def revert_spaceinset(document):
2182 " Revert '\\begin_inset Space foo\n\\end_inset' to '\\InsetSpace foo' "
2185 i = find_token(document.body, "\\begin_inset Space", i)
2188 j = find_end_of_inset(document.body, i)
2190 document.warning("Malformed LyX document: Could not find end of space inset.")
2192 document.body[i] = document.body[i].replace('\\begin_inset Space', '\\InsetSpace')
2193 del document.body[j]
2196 def convert_hfill(document):
2197 " Convert hfill to space inset "
2200 i = find_token(document.body, "\\hfill", i)
2203 subst = document.body[i].replace('\\hfill', \
2204 '\n\\begin_inset Space \\hfill{}\n\\end_inset')
2205 subst = subst.split('\n')
2206 document.body[i : i+1] = subst
2210 def revert_hfills(document):
2211 ' Revert \\hfill commands '
2212 hfill = re.compile(r'\\hfill')
2213 dotfill = re.compile(r'\\dotfill')
2214 hrulefill = re.compile(r'\\hrulefill')
2217 i = find_token(document.body, "\\InsetSpace", i)
2220 if hfill.search(document.body[i]):
2221 document.body[i] = \
2222 document.body[i].replace('\\InsetSpace \\hfill{}', '\\hfill')
2225 if dotfill.search(document.body[i]):
2226 subst = document.body[i].replace('\\InsetSpace \\dotfill{}', \
2227 '\\begin_inset ERT\nstatus collapsed\n\n' \
2228 '\\begin_layout Standard\n\n\n\\backslash\n' \
2229 'dotfill{}\n\\end_layout\n\n\\end_inset\n\n')
2230 subst = subst.split('\n')
2231 document.body[i : i+1] = subst
2234 if hrulefill.search(document.body[i]):
2235 subst = document.body[i].replace('\\InsetSpace \\hrulefill{}', \
2236 '\\begin_inset ERT\nstatus collapsed\n\n' \
2237 '\\begin_layout Standard\n\n\n\\backslash\n' \
2238 'hrulefill{}\n\\end_layout\n\n\\end_inset\n\n')
2239 subst = subst.split('\n')
2240 document.body[i : i+1] = subst
2245 def revert_hspace(document):
2246 ' Revert \\InsetSpace \\hspace{} to ERT '
2248 hspace = re.compile(r'\\hspace{}')
2249 hstar = re.compile(r'\\hspace\*{}')
2251 i = find_token(document.body, "\\InsetSpace \\hspace", i)
2254 length = get_value(document.body, '\\length', i+1)
2256 document.warning("Malformed lyx document: Missing '\\length' in Space inset.")
2258 del document.body[i+1]
2260 if hstar.search(document.body[i]):
2261 subst = document.body[i].replace('\\InsetSpace \\hspace*{}', \
2262 '\\begin_inset ERT\nstatus collapsed\n\n' \
2263 '\\begin_layout Standard\n\n\n\\backslash\n' \
2264 'hspace*{' + length + '}\n\\end_layout\n\n\\end_inset\n\n')
2265 subst = subst.split('\n')
2266 document.body[i : i+1] = subst
2267 addedLines += len(subst) - 1
2270 if hspace.search(document.body[i]):
2271 subst = document.body[i].replace('\\InsetSpace \\hspace{}', \
2272 '\\begin_inset ERT\nstatus collapsed\n\n' \
2273 '\\begin_layout Standard\n\n\n\\backslash\n' \
2274 'hspace{' + length + '}\n\\end_layout\n\n\\end_inset\n\n')
2275 subst = subst.split('\n')
2276 document.body[i : i+1] = subst
2277 addedLines += len(subst) - 1
2283 def revert_protected_hfill(document):
2284 ' Revert \\begin_inset Space \\hspace*{\\fill} to ERT '
2287 i = find_token(document.body, '\\begin_inset Space \\hspace*{\\fill}', i)
2290 j = find_end_of_inset(document.body, i)
2292 document.warning("Malformed LyX document: Could not find end of space inset.")
2294 del document.body[j]
2295 subst = document.body[i].replace('\\begin_inset Space \\hspace*{\\fill}', \
2296 '\\begin_inset ERT\nstatus collapsed\n\n' \
2297 '\\begin_layout Standard\n\n\n\\backslash\n' \
2298 'hspace*{\n\\backslash\nfill}\n\\end_layout\n\n\\end_inset\n\n')
2299 subst = subst.split('\n')
2300 document.body[i : i+1] = subst
2304 def revert_leftarrowfill(document):
2305 ' Revert \\begin_inset Space \\leftarrowfill{} to ERT '
2308 i = find_token(document.body, '\\begin_inset Space \\leftarrowfill{}', i)
2311 j = find_end_of_inset(document.body, i)
2313 document.warning("Malformed LyX document: Could not find end of space inset.")
2315 del document.body[j]
2316 subst = document.body[i].replace('\\begin_inset Space \\leftarrowfill{}', \
2317 '\\begin_inset ERT\nstatus collapsed\n\n' \
2318 '\\begin_layout Standard\n\n\n\\backslash\n' \
2319 'leftarrowfill{}\n\\end_layout\n\n\\end_inset\n\n')
2320 subst = subst.split('\n')
2321 document.body[i : i+1] = subst
2325 def revert_rightarrowfill(document):
2326 ' Revert \\begin_inset Space \\rightarrowfill{} to ERT '
2329 i = find_token(document.body, '\\begin_inset Space \\rightarrowfill{}', i)
2332 j = find_end_of_inset(document.body, i)
2334 document.warning("Malformed LyX document: Could not find end of space inset.")
2336 del document.body[j]
2337 subst = document.body[i].replace('\\begin_inset Space \\rightarrowfill{}', \
2338 '\\begin_inset ERT\nstatus collapsed\n\n' \
2339 '\\begin_layout Standard\n\n\n\\backslash\n' \
2340 'rightarrowfill{}\n\\end_layout\n\n\\end_inset\n\n')
2341 subst = subst.split('\n')
2342 document.body[i : i+1] = subst
2346 def revert_upbracefill(document):
2347 ' Revert \\begin_inset Space \\upbracefill{} to ERT '
2350 i = find_token(document.body, '\\begin_inset Space \\upbracefill{}', i)
2353 j = find_end_of_inset(document.body, i)
2355 document.warning("Malformed LyX document: Could not find end of space inset.")
2357 del document.body[j]
2358 subst = document.body[i].replace('\\begin_inset Space \\upbracefill{}', \
2359 '\\begin_inset ERT\nstatus collapsed\n\n' \
2360 '\\begin_layout Standard\n\n\n\\backslash\n' \
2361 'upbracefill{}\n\\end_layout\n\n\\end_inset\n\n')
2362 subst = subst.split('\n')
2363 document.body[i : i+1] = subst
2367 def revert_downbracefill(document):
2368 ' Revert \\begin_inset Space \\downbracefill{} to ERT '
2371 i = find_token(document.body, '\\begin_inset Space \\downbracefill{}', i)
2374 j = find_end_of_inset(document.body, i)
2376 document.warning("Malformed LyX document: Could not find end of space inset.")
2378 del document.body[j]
2379 subst = document.body[i].replace('\\begin_inset Space \\downbracefill{}', \
2380 '\\begin_inset ERT\nstatus collapsed\n\n' \
2381 '\\begin_layout Standard\n\n\n\\backslash\n' \
2382 'downbracefill{}\n\\end_layout\n\n\\end_inset\n\n')
2383 subst = subst.split('\n')
2384 document.body[i : i+1] = subst
2388 def revert_local_layout(document):
2389 ' Revert local layout headers.'
2392 i = find_token(document.header, "\\begin_local_layout", i)
2395 j = find_end_of(document.header, i, "\\begin_local_layout", "\\end_local_layout")
2397 # this should not happen
2399 document.header[i : j + 1] = []
2402 def convert_pagebreaks(document):
2403 ' Convert inline Newpage insets to new format '
2406 i = find_token(document.body, '\\newpage', i)
2409 document.body[i:i+1] = ['\\begin_inset Newpage newpage',
2413 i = find_token(document.body, '\\pagebreak', i)
2416 document.body[i:i+1] = ['\\begin_inset Newpage pagebreak',
2420 i = find_token(document.body, '\\clearpage', i)
2423 document.body[i:i+1] = ['\\begin_inset Newpage clearpage',
2427 i = find_token(document.body, '\\cleardoublepage', i)
2430 document.body[i:i+1] = ['\\begin_inset Newpage cleardoublepage',
2434 def revert_pagebreaks(document):
2435 ' Revert \\begin_inset Newpage to previous inline format '
2438 i = find_token(document.body, '\\begin_inset Newpage', i)
2441 j = find_end_of_inset(document.body, i)
2443 document.warning("Malformed LyX document: Could not find end of Newpage inset.")
2445 del document.body[j]
2446 document.body[i] = document.body[i].replace('\\begin_inset Newpage newpage', '\\newpage')
2447 document.body[i] = document.body[i].replace('\\begin_inset Newpage pagebreak', '\\pagebreak')
2448 document.body[i] = document.body[i].replace('\\begin_inset Newpage clearpage', '\\clearpage')
2449 document.body[i] = document.body[i].replace('\\begin_inset Newpage cleardoublepage', '\\cleardoublepage')
2452 def convert_linebreaks(document):
2453 ' Convert inline Newline insets to new format '
2456 i = find_token(document.body, '\\newline', i)
2459 document.body[i:i+1] = ['\\begin_inset Newline newline',
2463 i = find_token(document.body, '\\linebreak', i)
2466 document.body[i:i+1] = ['\\begin_inset Newline linebreak',
2470 def revert_linebreaks(document):
2471 ' Revert \\begin_inset Newline to previous inline format '
2474 i = find_token(document.body, '\\begin_inset Newline', i)
2477 j = find_end_of_inset(document.body, i)
2479 document.warning("Malformed LyX document: Could not find end of Newline inset.")
2481 del document.body[j]
2482 document.body[i] = document.body[i].replace('\\begin_inset Newline newline', '\\newline')
2483 document.body[i] = document.body[i].replace('\\begin_inset Newline linebreak', '\\linebreak')
2486 def convert_japanese_plain(document):
2487 ' Set language japanese-plain to japanese '
2489 if document.language == "japanese-plain":
2490 document.language = "japanese"
2491 i = find_token(document.header, "\\language", 0)
2493 document.header[i] = "\\language japanese"
2496 j = find_token(document.body, "\\lang japanese-plain", j)
2499 document.body[j] = document.body[j].replace("\\lang japanese-plain", "\\lang japanese")
2503 def revert_pdfpages(document):
2504 ' Revert pdfpages external inset to ERT '
2507 i = find_token(document.body, "\\begin_inset External", i)
2510 j = find_end_of_inset(document.body, i)
2512 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_pdfpages.")
2515 if get_value(document.body, 'template', i, j) == "PDFPages":
2516 filename = get_value(document.body, 'filename', i, j)
2518 r = re.compile(r'\textra PDFLaTeX \"(.*)\"$')
2519 for k in range(i, j):
2520 m = r.match(document.body[k])
2523 angle = get_value(document.body, 'rotateAngle', i, j)
2524 width = get_value(document.body, 'width', i, j)
2525 height = get_value(document.body, 'height', i, j)
2526 scale = get_value(document.body, 'scale', i, j)
2527 keepAspectRatio = find_token(document.body, "\tkeepAspectRatio", i, j)
2531 options += ",angle=" + angle
2533 options += "angle=" + angle
2536 options += ",width=" + convert_len(width)
2538 options += "width=" + convert_len(width)
2541 options += ",height=" + convert_len(height)
2543 options += "height=" + convert_len(height)
2546 options += ",scale=" + scale
2548 options += "scale=" + scale
2549 if keepAspectRatio != '':
2551 options += ",keepaspectratio"
2553 options += "keepaspectratio"
2555 options = '[' + options + ']'
2556 del document.body[i+1:j+1]
2557 document.body[i:i+1] = ['\\begin_inset ERT',
2560 '\\begin_layout Standard',
2563 'includepdf' + options + '{' + filename + '}',
2567 add_to_preamble(document, ['\\usepackage{pdfpages}\n'])
2573 def revert_mexican(document):
2574 ' Set language Spanish(Mexico) to Spanish '
2576 if document.language == "spanish-mexico":
2577 document.language = "spanish"
2578 i = find_token(document.header, "\\language", 0)
2580 document.header[i] = "\\language spanish"
2583 j = find_token(document.body, "\\lang spanish-mexico", j)
2586 document.body[j] = document.body[j].replace("\\lang spanish-mexico", "\\lang spanish")
2590 def remove_embedding(document):
2591 ' Remove embed tag from all insets '
2592 revert_inset_embedding(document, 'Graphics')
2593 revert_inset_embedding(document, 'External')
2594 revert_inset_embedding(document, 'CommandInset include')
2595 revert_inset_embedding(document, 'CommandInset bibtex')
2598 def revert_master(document):
2599 ' Remove master param '
2600 i = find_token(document.header, "\\master", 0)
2602 del document.header[i]
2605 def revert_graphics_group(document):
2606 ' Revert group information from graphics insets '
2609 i = find_token(document.body, "\\begin_inset Graphics", i)
2612 j = find_end_of_inset(document.body, i)
2614 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_graphics_group.")
2617 k = find_token(document.body, " groupId", i, j)
2621 del document.body[k]
2625 def update_apa_styles(document):
2626 ' Replace obsolete styles '
2628 if document.textclass != "apa":
2631 obsoletedby = { "Acknowledgments": "Acknowledgements",
2632 "Section*": "Section",
2633 "Subsection*": "Subsection",
2634 "Subsubsection*": "Subsubsection",
2635 "Paragraph*": "Paragraph",
2636 "Subparagraph*": "Subparagraph"}
2639 i = find_token(document.body, "\\begin_layout", i)
2643 layout = document.body[i][14:]
2644 if layout in obsoletedby:
2645 document.body[i] = "\\begin_layout " + obsoletedby[layout]
2650 def convert_paper_sizes(document):
2651 ' exchange size options legalpaper and executivepaper to correct order '
2652 # routine is needed to fix http://bugzilla.lyx.org/show_bug.cgi?id=4868
2655 i = find_token(document.header, "\\papersize executivepaper", 0)
2657 document.header[i] = "\\papersize legalpaper"
2659 j = find_token(document.header, "\\papersize legalpaper", 0)
2661 document.header[j] = "\\papersize executivepaper"
2664 def revert_paper_sizes(document):
2665 ' exchange size options legalpaper and executivepaper to correct order '
2668 i = find_token(document.header, "\\papersize executivepaper", 0)
2670 document.header[i] = "\\papersize legalpaper"
2672 j = find_token(document.header, "\\papersize legalpaper", 0)
2674 document.header[j] = "\\papersize executivepaper"
2677 def convert_InsetSpace(document):
2678 " Convert '\\begin_inset Space foo' to '\\begin_inset space foo'"
2681 i = find_token(document.body, "\\begin_inset Space", i)
2684 document.body[i] = document.body[i].replace('\\begin_inset Space', '\\begin_inset space')
2687 def revert_InsetSpace(document):
2688 " Revert '\\begin_inset space foo' to '\\begin_inset Space foo'"
2691 i = find_token(document.body, "\\begin_inset space", i)
2694 document.body[i] = document.body[i].replace('\\begin_inset space', '\\begin_inset Space')
2697 def convert_display_enum(document):
2698 " Convert 'display foo' to 'display false/true'"
2701 i = find_token(document.body, "\tdisplay", i)
2704 val = get_value(document.body, 'display', i)
2706 document.body[i] = document.body[i].replace('none', 'false')
2707 if val == "default":
2708 document.body[i] = document.body[i].replace('default', 'true')
2709 if val == "monochrome":
2710 document.body[i] = document.body[i].replace('monochrome', 'true')
2711 if val == "grayscale":
2712 document.body[i] = document.body[i].replace('grayscale', 'true')
2714 document.body[i] = document.body[i].replace('color', 'true')
2715 if val == "preview":
2716 document.body[i] = document.body[i].replace('preview', 'true')
2720 def revert_display_enum(document):
2721 " Revert 'display false/true' to 'display none/color'"
2724 i = find_token(document.body, "\tdisplay", i)
2727 val = get_value(document.body, 'display', i)
2729 document.body[i] = document.body[i].replace('false', 'none')
2731 document.body[i] = document.body[i].replace('true', 'default')
2735 def remove_fontsCJK(document):
2736 ' Remove font_cjk param '
2737 i = find_token(document.header, "\\font_cjk", 0)
2739 del document.header[i]
2742 def convert_plain_layout(document):
2743 " Convert 'PlainLayout' to 'Plain Layout'"
2746 i = find_token(document.body, '\\begin_layout PlainLayout', i)
2749 document.body[i] = document.body[i].replace('\\begin_layout PlainLayout', \
2750 '\\begin_layout Plain Layout')
2754 def revert_plain_layout(document):
2755 " Convert 'PlainLayout' to 'Plain Layout'"
2758 i = find_token(document.body, '\\begin_layout Plain Layout', i)
2761 document.body[i] = document.body[i].replace('\\begin_layout Plain Layout', \
2762 '\\begin_layout PlainLayout')
2766 def revert_plainlayout(document):
2767 " Convert 'PlainLayout' to 'Plain Layout'"
2770 i = find_token(document.body, '\\begin_layout PlainLayout', i)
2773 # This will be incorrect for some document classes, since Standard is not always
2774 # the default. But (a) it is probably the best we can do and (b) it will actually
2775 # work, in fact, since an unknown layout will be converted to default.
2776 document.body[i] = document.body[i].replace('\\begin_layout PlainLayout', \
2777 '\\begin_layout Standard')
2781 def revert_polytonicgreek(document):
2782 "Set language polytonic Greek to Greek"
2784 if document.language == "polutonikogreek":
2785 document.language = "greek"
2786 i = find_token(document.header, "\\language", 0)
2788 document.header[i] = "\\language greek"
2791 j = find_token(document.body, "\\lang polutonikogreek", j)
2794 document.body[j] = document.body[j].replace("\\lang polutonikogreek", "\\lang greek")
2802 supported_versions = ["1.6.0","1.6"]
2803 convert = [[277, [fix_wrong_tables]],
2804 [278, [close_begin_deeper]],
2805 [279, [long_charstyle_names]],
2806 [280, [axe_show_label]],
2809 [283, [convert_flex]],
2813 [287, [convert_wrapfig_options]],
2814 [288, [convert_inset_command]],
2815 [289, [convert_latexcommand_index]],
2820 [294, [convert_pdf_options]],
2821 [295, [convert_htmlurl, convert_url]],
2822 [296, [convert_include]],
2823 [297, [convert_usorbian]],
2829 [303, [convert_serbocroatian]],
2830 [304, [convert_framed_notes]],
2837 [311, [convert_ams_classes]],
2839 [313, [convert_module_names]],
2842 [316, [convert_subfig]],
2845 [319, [convert_spaceinset, convert_hfill]],
2847 [321, [convert_tablines]],
2848 [322, [convert_plain_layout]],
2849 [323, [convert_pagebreaks]],
2850 [324, [convert_linebreaks]],
2851 [325, [convert_japanese_plain]],
2854 [328, [remove_embedding, remove_extra_embedded_files, remove_inzip_options]],
2857 [331, [convert_ltcaption]],
2859 [333, [update_apa_styles]],
2860 [334, [convert_paper_sizes]],
2861 [335, [convert_InsetSpace]],
2863 [337, [convert_display_enum]],
2867 revert = [[337, [revert_polytonicgreek]],
2868 [336, [revert_display_enum]],
2869 [335, [remove_fontsCJK]],
2870 [334, [revert_InsetSpace]],
2871 [333, [revert_paper_sizes]],
2873 [331, [revert_graphics_group]],
2874 [330, [revert_ltcaption]],
2875 [329, [revert_leftarrowfill, revert_rightarrowfill, revert_upbracefill, revert_downbracefill]],
2876 [328, [revert_master]],
2878 [326, [revert_mexican]],
2879 [325, [revert_pdfpages]],
2881 [323, [revert_linebreaks]],
2882 [322, [revert_pagebreaks]],
2883 [321, [revert_local_layout, revert_plain_layout]],
2884 [320, [revert_tablines]],
2885 [319, [revert_protected_hfill]],
2886 [318, [revert_spaceinset, revert_hfills, revert_hspace]],
2887 [317, [remove_extra_embedded_files]],
2888 [316, [revert_wrapplacement]],
2889 [315, [revert_subfig]],
2890 [314, [revert_colsep, revert_plainlayout]],
2892 [312, [revert_module_names]],
2893 [311, [revert_rotfloat, revert_widesideways]],
2894 [310, [revert_external_embedding]],
2895 [309, [revert_btprintall]],
2896 [308, [revert_nocite]],
2897 [307, [revert_serbianlatin]],
2898 [306, [revert_slash, revert_nobreakdash]],
2899 [305, [revert_interlingua]],
2900 [304, [revert_bahasam]],
2901 [303, [revert_framed_notes]],
2903 [301, [revert_latin, revert_samin]],
2904 [300, [revert_linebreak]],
2905 [299, [revert_pagebreak]],
2906 [298, [revert_hyperlinktype]],
2907 [297, [revert_macro_optional_params]],
2908 [296, [revert_albanian, revert_lowersorbian, revert_uppersorbian]],
2909 [295, [revert_include]],
2910 [294, [revert_href, revert_url]],
2911 [293, [revert_pdf_options_2]],
2912 [292, [revert_inset_info]],
2913 [291, [revert_japanese, revert_japanese_encoding]],
2914 [290, [revert_vietnamese]],
2915 [289, [revert_wraptable]],
2916 [288, [revert_latexcommand_index]],
2917 [287, [revert_inset_command]],
2918 [286, [revert_wrapfig_options]],
2919 [285, [revert_pdf_options]],
2920 [284, [remove_inzip_options]],
2922 [282, [revert_flex]],
2924 [280, [revert_begin_modules]],
2925 [279, [revert_show_label]],
2926 [278, [revert_long_charstyle_names]],
2932 if __name__ == "__main__":