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 def lyx2latex(lines):
294 'Convert some LyX stuff into corresponding LaTeX stuff, as best we can.'
295 # clean up multiline stuff
298 reps = read_unicodesymbols()
300 for curline in range(len(lines)):
301 line = lines[curline]
302 if line.startswith("\\begin_inset ERT"):
303 # We don't want to replace things inside ERT, so figure out
304 # where the end of the inset is.
305 ert_end = find_end_of_inset(lines, curline + 1)
307 elif line.startswith("\\begin_inset Formula"):
309 elif line.startswith("\\begin_inset Quotes"):
310 # For now, we do a very basic reversion. Someone who understands
311 # quotes is welcome to fix it up.
312 qtype = line[20:].strip()
326 elif line.isspace() or \
327 line.startswith("\\begin_layout") or \
328 line.startswith("\\end_layout") or \
329 line.startswith("\\begin_inset") or \
330 line.startswith("\\end_inset") or \
331 line.startswith("\\lang") or \
332 line.startswith("status collapsed") or \
333 line.startswith("status open"):
337 # a lossless reversion is not possible
338 # try at least to handle some common insets and settings
339 # do not replace inside ERTs
340 if ert_end >= curline:
341 line = line.replace(r'\backslash', r'\\')
343 # Do the LyX text --> LaTeX conversion
345 line = line.replace(rep[1], rep[0])
346 line = line.replace(r'\backslash', r'\textbackslash{}')
347 line = line.replace(r'\series bold', r'\bfseries{}').replace(r'\series default', r'\mdseries{}')
348 line = line.replace(r'\shape italic', r'\itshape{}').replace(r'\shape smallcaps', r'\scshape{}')
349 line = line.replace(r'\shape slanted', r'\slshape{}').replace(r'\shape default', r'\upshape{}')
350 line = line.replace(r'\emph on', r'\em{}').replace(r'\emph default', r'\em{}')
351 line = line.replace(r'\noun on', r'\scshape{}').replace(r'\noun default', r'\upshape{}')
352 line = line.replace(r'\bar under', r'\underbar{').replace(r'\bar default', r'}')
353 line = line.replace(r'\family sans', r'\sffamily{}').replace(r'\family default', r'\normalfont{}')
354 line = line.replace(r'\family typewriter', r'\ttfamily{}').replace(r'\family roman', r'\rmfamily{}')
355 line = line.replace(r'\InsetSpace ', r'').replace(r'\SpecialChar ', r'')
360 ####################################################################
362 def convert_ltcaption(document):
365 i = find_token(document.body, "\\begin_inset Tabular", i)
368 j = find_end_of_inset(document.body, i + 1)
370 document.warning("Malformed LyX document: Could not find end of tabular.")
373 nrows = int(document.body[i+1].split('"')[3])
374 ncols = int(document.body[i+1].split('"')[5])
377 for k in range(nrows):
378 m = find_token(document.body, "<row", m)
381 for k in range(ncols):
382 m = find_token(document.body, "<cell", m)
384 mend = find_token(document.body, "</cell>", m + 1)
385 # first look for caption insets
386 mcap = find_token(document.body, "\\begin_inset Caption", m + 1, mend)
387 # then look for ERT captions
389 mcap = find_token(document.body, "caption", m + 1, mend)
391 mcap = find_token(document.body, "\\backslash", mcap - 1, mcap)
394 if caption == 'true':
396 set_option(document, r, 'caption', 'true')
397 set_option(document, m, 'multicolumn', '1')
398 set_option(document, m, 'bottomline', 'false')
399 set_option(document, m, 'topline', 'false')
400 set_option(document, m, 'rightline', 'false')
401 set_option(document, m, 'leftline', 'false')
402 #j = find_end_of_inset(document.body, j + 1)
404 set_option(document, m, 'multicolumn', '2')
411 #FIXME Use of wrap_into_ert can confuse lyx2lyx
412 def revert_ltcaption(document):
415 i = find_token(document.body, "\\begin_inset Tabular", i)
418 j = find_end_of_inset(document.body, i + 1)
420 document.warning("Malformed LyX document: Could not find end of tabular.")
424 nrows = int(document.body[i+1].split('"')[3])
425 ncols = int(document.body[i+1].split('"')[5])
427 for k in range(nrows):
428 m = find_token(document.body, "<row", m)
429 caption = get_option(document, m, 'caption', 'false')
430 if caption == 'true':
431 remove_option(document, m, 'caption')
432 for k in range(ncols):
433 m = find_token(document.body, "<cell", m)
434 remove_option(document, m, 'multicolumn')
436 m = find_token(document.body, "\\begin_inset Caption", m)
439 m = find_end_of_inset(document.body, m + 1)
440 document.body[m] += wrap_into_ert("","","\\backslash\n\\backslash\n%")
446 def convert_tablines(document):
449 i = find_token(document.body, "\\begin_inset Tabular", i)
451 # LyX 1.3 inserted an extra space between \begin_inset
452 # and Tabular so let us try if this is the case and fix it.
453 i = find_token(document.body, "\\begin_inset Tabular", i)
457 document.body[i] = "\\begin_inset Tabular"
458 j = find_end_of_inset(document.body, i + 1)
460 document.warning("Malformed LyX document: Could not find end of tabular.")
464 nrows = int(document.body[i+1].split('"')[3])
465 ncols = int(document.body[i+1].split('"')[5])
468 for k in range(ncols):
469 m = find_token(document.body, "<column", m)
470 left = get_option(document, m, 'leftline', 'false')
471 right = get_option(document, m, 'rightline', 'false')
472 col_info.append([left, right])
473 remove_option(document, m, 'leftline')
474 remove_option(document, m, 'rightline')
478 for k in range(nrows):
479 m = find_token(document.body, "<row", m)
480 top = get_option(document, m, 'topline', 'false')
481 bottom = get_option(document, m, 'bottomline', 'false')
482 row_info.append([top, bottom])
483 remove_option(document, m, 'topline')
484 remove_option(document, m, 'bottomline')
489 for k in range(nrows*ncols):
490 m = find_token(document.body, "<cell", m)
491 mc_info.append(get_option(document, m, 'multicolumn', '0'))
494 for l in range(nrows):
495 for k in range(ncols):
496 m = find_token(document.body, '<cell', m)
497 if mc_info[l*ncols + k] == '0':
498 r = set_option(document, m, 'topline', row_info[l][0])
499 r = set_option(document, m, 'bottomline', row_info[l][1])
500 r = set_option(document, m, 'leftline', col_info[k][0])
501 r = set_option(document, m, 'rightline', col_info[k][1])
502 elif mc_info[l*ncols + k] == '1':
504 while s < ncols and mc_info[l*ncols + s] == '2':
506 if s < ncols and mc_info[l*ncols + s] != '1':
507 r = set_option(document, m, 'rightline', col_info[k][1])
508 if k > 0 and mc_info[l*ncols + k - 1] == '0':
509 r = set_option(document, m, 'leftline', col_info[k][0])
514 def revert_tablines(document):
517 i = find_token(document.body, "\\begin_inset Tabular", i)
520 j = find_end_of_inset(document.body, i + 1)
522 document.warning("Malformed LyX document: Could not find end of tabular.")
526 nrows = int(document.body[i+1].split('"')[3])
527 ncols = int(document.body[i+1].split('"')[5])
530 for k in range(nrows*ncols):
531 m = find_token(document.body, "<cell", m)
532 top = get_option(document, m, 'topline', 'false')
533 bottom = get_option(document, m, 'bottomline', 'false')
534 left = get_option(document, m, 'leftline', 'false')
535 right = get_option(document, m, 'rightline', 'false')
536 lines.append([top, bottom, left, right])
539 # we will want to ignore longtable captions
542 for k in range(nrows):
543 m = find_token(document.body, "<row", m)
544 caption = get_option(document, m, 'caption', 'false')
545 caption_info.append([caption])
550 for k in range(ncols):
551 m = find_token(document.body, "<column", m)
553 for l in range(nrows):
554 left = lines[l*ncols + k][2]
555 if left == 'false' and caption_info[l] == 'false':
557 set_option(document, m, 'leftline', left)
559 for l in range(nrows):
560 right = lines[l*ncols + k][3]
561 if right == 'false' and caption_info[l] == 'false':
563 set_option(document, m, 'rightline', right)
567 for k in range(nrows):
568 m = find_token(document.body, "<row", m)
570 for l in range(ncols):
571 top = lines[k*ncols + l][0]
574 if caption_info[k] == 'false':
576 set_option(document, m, 'topline', top)
578 for l in range(ncols):
579 bottom = lines[k*ncols + l][1]
580 if bottom == 'false':
582 if caption_info[k] == 'false':
584 set_option(document, m, 'bottomline', bottom)
590 def fix_wrong_tables(document):
593 i = find_token(document.body, "\\begin_inset Tabular", i)
596 j = find_end_of_inset(document.body, i + 1)
598 document.warning("Malformed LyX document: Could not find end of tabular.")
602 nrows = int(document.body[i+1].split('"')[3])
603 ncols = int(document.body[i+1].split('"')[5])
605 for l in range(nrows):
607 for k in range(ncols):
608 m = find_token(document.body, '<cell', m)
610 if document.body[m].find('multicolumn') != -1:
611 multicol_cont = int(document.body[m].split('"')[1])
613 if multicol_cont == 2 and (k == 0 or prev_multicolumn == 0):
614 document.body[m] = document.body[m][:5] + document.body[m][21:]
617 prev_multicolumn = multicol_cont
624 def close_begin_deeper(document):
628 i = find_tokens(document.body, ["\\begin_deeper", "\\end_deeper"], i)
633 if document.body[i][:13] == "\\begin_deeper":
640 document.body[-2:-2] = ['\\end_deeper' for i in range(depth)]
643 def long_charstyle_names(document):
646 i = find_token(document.body, "\\begin_inset CharStyle", i)
649 document.body[i] = document.body[i].replace("CharStyle ", "CharStyle CharStyle:")
652 def revert_long_charstyle_names(document):
655 i = find_token(document.body, "\\begin_inset CharStyle", i)
658 document.body[i] = document.body[i].replace("CharStyle CharStyle:", "CharStyle")
662 def axe_show_label(document):
665 i = find_token(document.body, "\\begin_inset CharStyle", i)
668 if document.body[i + 1].find("show_label") != -1:
669 if document.body[i + 1].find("true") != -1:
670 document.body[i + 1] = "status open"
671 del document.body[ i + 2]
673 if document.body[i + 1].find("false") != -1:
674 document.body[i + 1] = "status collapsed"
675 del document.body[ i + 2]
677 document.warning("Malformed LyX document: show_label neither false nor true.")
679 document.warning("Malformed LyX document: show_label missing in CharStyle.")
684 def revert_show_label(document):
687 i = find_token(document.body, "\\begin_inset CharStyle", i)
690 if document.body[i + 1].find("status open") != -1:
691 document.body.insert(i + 1, "show_label true")
693 if document.body[i + 1].find("status collapsed") != -1:
694 document.body.insert(i + 1, "show_label false")
696 document.warning("Malformed LyX document: no legal status line in CharStyle.")
699 def revert_begin_modules(document):
702 i = find_token(document.header, "\\begin_modules", i)
705 j = find_end_of(document.header, i, "\\begin_modules", "\\end_modules")
707 # this should not happen
709 document.header[i : j + 1] = []
711 def convert_flex(document):
712 "Convert CharStyle to Flex"
715 i = find_token(document.body, "\\begin_inset CharStyle", i)
718 document.body[i] = document.body[i].replace('\\begin_inset CharStyle', '\\begin_inset Flex')
720 def revert_flex(document):
721 "Convert Flex to CharStyle"
724 i = find_token(document.body, "\\begin_inset Flex", i)
727 document.body[i] = document.body[i].replace('\\begin_inset Flex', '\\begin_inset CharStyle')
730 # Discard PDF options for hyperref
731 def revert_pdf_options(document):
732 "Revert PDF options for hyperref."
733 # store the PDF options and delete the entries from the Lyx file
741 bookmarksnumbered = ""
743 bookmarksopenlevel = ""
751 i = find_token(document.header, "\\use_hyperref", i)
753 hyperref = get_value(document.header, "\\use_hyperref", i) == 'true'
754 del document.header[i]
755 i = find_token(document.header, "\\pdf_store_options", i)
757 del document.header[i]
758 i = find_token(document.header, "\\pdf_title", 0)
760 title = get_value_string(document.header, '\\pdf_title', 0, 0, True)
761 title = ' pdftitle={' + title + '}'
762 del document.header[i]
763 i = find_token(document.header, "\\pdf_author", 0)
765 author = get_value_string(document.header, '\\pdf_author', 0, 0, True)
767 author = ' pdfauthor={' + author + '}'
769 author = ',\n pdfauthor={' + author + '}'
770 del document.header[i]
771 i = find_token(document.header, "\\pdf_subject", 0)
773 subject = get_value_string(document.header, '\\pdf_subject', 0, 0, True)
774 if title == "" and author == "":
775 subject = ' pdfsubject={' + subject + '}'
777 subject = ',\n pdfsubject={' + subject + '}'
778 del document.header[i]
779 i = find_token(document.header, "\\pdf_keywords", 0)
781 keywords = get_value_string(document.header, '\\pdf_keywords', 0, 0, True)
782 if title == "" and author == "" and subject == "":
783 keywords = ' pdfkeywords={' + keywords + '}'
785 keywords = ',\n pdfkeywords={' + keywords + '}'
786 del document.header[i]
787 i = find_token(document.header, "\\pdf_bookmarks", 0)
789 bookmarks = get_value_string(document.header, '\\pdf_bookmarks', 0)
790 bookmarks = ',\n bookmarks=' + bookmarks
791 del document.header[i]
792 i = find_token(document.header, "\\pdf_bookmarksnumbered", i)
794 bookmarksnumbered = get_value_string(document.header, '\\pdf_bookmarksnumbered', 0)
795 bookmarksnumbered = ',\n bookmarksnumbered=' + bookmarksnumbered
796 del document.header[i]
797 i = find_token(document.header, "\\pdf_bookmarksopen", i)
799 bookmarksopen = get_value_string(document.header, '\\pdf_bookmarksopen', 0)
800 bookmarksopen = ',\n bookmarksopen=' + bookmarksopen
801 del document.header[i]
802 i = find_token(document.header, "\\pdf_bookmarksopenlevel", i)
804 bookmarksopenlevel = get_value_string(document.header, '\\pdf_bookmarksopenlevel', 0, 0, True)
805 bookmarksopenlevel = ',\n bookmarksopenlevel=' + bookmarksopenlevel
806 del document.header[i]
807 i = find_token(document.header, "\\pdf_breaklinks", i)
809 breaklinks = get_value_string(document.header, '\\pdf_breaklinks', 0)
810 breaklinks = ',\n breaklinks=' + breaklinks
811 del document.header[i]
812 i = find_token(document.header, "\\pdf_pdfborder", i)
814 pdfborder = get_value_string(document.header, '\\pdf_pdfborder', 0)
815 if pdfborder == 'true':
816 pdfborder = ',\n pdfborder={0 0 0}'
818 pdfborder = ',\n pdfborder={0 0 1}'
819 del document.header[i]
820 i = find_token(document.header, "\\pdf_colorlinks", i)
822 colorlinks = get_value_string(document.header, '\\pdf_colorlinks', 0)
823 colorlinks = ',\n colorlinks=' + colorlinks
824 del document.header[i]
825 i = find_token(document.header, "\\pdf_backref", i)
827 backref = get_value_string(document.header, '\\pdf_backref', 0)
828 backref = ',\n backref=' + backref
829 del document.header[i]
830 i = find_token(document.header, "\\pdf_pagebackref", i)
832 pagebackref = get_value_string(document.header, '\\pdf_pagebackref', 0)
833 pagebackref = ',\n pagebackref=' + pagebackref
834 del document.header[i]
835 i = find_token(document.header, "\\pdf_pagemode", 0)
837 pagemode = get_value_string(document.header, '\\pdf_pagemode', 0)
838 pagemode = ',\n pdfpagemode=' + pagemode
839 del document.header[i]
840 i = find_token(document.header, "\\pdf_quoted_options", 0)
842 otheroptions = get_value_string(document.header, '\\pdf_quoted_options', 0, 0, True)
843 if title == "" and author == "" and subject == "" and keywords == "":
844 otheroptions = ' ' + otheroptions
846 otheroptions = ',\n ' + otheroptions
847 del document.header[i]
849 # write to the preamble when hyperref was used
851 # preamble write preparations
852 # bookmark numbers are only output when they are turned on
853 if bookmarksopen == ',\n bookmarksopen=true':
854 bookmarksopen = bookmarksopen + bookmarksopenlevel
855 if bookmarks == ',\n bookmarks=true':
856 bookmarks = bookmarks + bookmarksnumbered + bookmarksopen
858 bookmarks = bookmarks
859 # hypersetup is only output when there are things to be set up
860 setupstart = '\\hypersetup{%\n'
862 if otheroptions == "" and title == "" and author == ""\
863 and subject == "" and keywords == "":
867 add_to_preamble(document,
868 ['% Commands inserted by lyx2lyx for PDF properties',
869 '\\usepackage[unicode=true'
888 def remove_inzip_options(document):
889 "Remove inzipName and embed options from the Graphics inset"
892 i = find_token(document.body, "\\begin_inset Graphics", i)
895 j = find_end_of_inset(document.body, i + 1)
898 document.warning("Malformed LyX document: Could not find end of graphics inset.")
899 # If there's a inzip param, just remove that
900 k = find_token(document.body, "\tinzipName", i + 1, j)
903 # embed option must follow the inzipName option
904 del document.body[k+1]
908 def convert_inset_command(document):
911 \begin_inset LatexCommand cmd
913 \begin_inset CommandInset InsetType
918 i = find_token(document.body, "\\begin_inset LatexCommand", i)
921 line = document.body[i]
922 r = re.compile(r'\\begin_inset LatexCommand (.*)$')
926 #this is adapted from factory.cpp
927 if cmdName[0:4].lower() == "cite":
928 insetName = "citation"
929 elif cmdName == "url" or cmdName == "htmlurl":
931 elif cmdName[-3:] == "ref":
933 elif cmdName == "tableofcontents":
935 elif cmdName == "printnomenclature":
936 insetName = "nomencl_print"
937 elif cmdName == "printindex":
938 insetName = "index_print"
941 insertion = ["\\begin_inset CommandInset " + insetName, "LatexCommand " + cmdName]
942 document.body[i : i+1] = insertion
945 def revert_inset_command(document):
948 \begin_inset CommandInset InsetType
951 \begin_inset LatexCommand cmd
952 Some insets may end up being converted to insets earlier versions of LyX
953 will not be able to recognize. Not sure what to do about that.
957 i = find_token(document.body, "\\begin_inset CommandInset", i)
960 nextline = document.body[i+1]
961 r = re.compile(r'LatexCommand\s+(.*)$')
962 m = r.match(nextline)
964 document.warning("Malformed LyX document: Missing LatexCommand in " + document.body[i] + ".")
967 insertion = ["\\begin_inset LatexCommand " + cmdName]
968 document.body[i : i+2] = insertion
971 def convert_wrapfig_options(document):
972 "Convert optional options for wrap floats (wrapfig)."
973 # adds the tokens "lines", "placement", and "overhang"
976 i = find_token(document.body, "\\begin_inset Wrap figure", i)
979 document.body.insert(i + 1, "lines 0")
980 j = find_token(document.body, "placement", i)
981 # placement can be already set or not; if not, set it
983 document.body.insert(i + 3, "overhang 0col%")
985 document.body.insert(i + 2, "placement o")
986 document.body.insert(i + 3, "overhang 0col%")
990 def revert_wrapfig_options(document):
991 "Revert optional options for wrap floats (wrapfig)."
994 i = find_token(document.body, "\\begin_inset Wrap figure", i)
997 j = find_end_of_inset(document.body, i)
999 document.warning("Can't find end of Wrap inset at line " + str(i))
1002 k = find_default_layout(document, i, j)
1004 document.warning("Can't find default layout for Wrap figure!")
1007 # Options should be between i and k now
1008 l = find_token(document.body, "lines", i, k)
1010 document.warning("Can't find lines option for Wrap figure!")
1013 m = find_token(document.body, "overhang", i + 1, k)
1015 document.warning("Malformed LyX document: Couldn't find overhang parameter of wrap float!")
1018 # Do these in reverse order
1019 del document.body[m]
1020 del document.body[l]
1024 def convert_latexcommand_index(document):
1025 "Convert from LatexCommand form to collapsable form."
1027 r1 = re.compile('name "(.*)"')
1029 i = find_token(document.body, "\\begin_inset CommandInset index", i)
1032 if document.body[i + 1] != "LatexCommand index": # Might also be index_print
1034 m = r1.match(document.body[i + 2])
1036 document.warning("Unable to match: " + document.body[i+2])
1039 fullcontent = m.group(1)
1040 #document.warning(fullcontent)
1041 document.body[i:i + 3] = ["\\begin_inset Index",
1043 "\\begin_layout Standard"]
1045 # We are now on the blank line preceding "\end_inset"
1046 # We will write the content here, into the inset.
1048 linelist = latex2lyx(fullcontent)
1049 document.body[i+1:i+1] = linelist
1052 document.body.insert(i + 1, "\\end_layout")
1056 def revert_latexcommand_index(document):
1057 "Revert from collapsable form to LatexCommand form."
1060 i = find_token(document.body, "\\begin_inset Index", i)
1063 j = find_end_of_inset(document.body, i + 1)
1067 content = lyx2latex(document.body[i:j])
1069 content = content.replace('"', r'\"')
1070 document.body[i:j] = ["\\begin_inset CommandInset index", "LatexCommand index",
1071 "name " + '"' + content + '"', ""]
1075 def revert_wraptable(document):
1076 "Revert wrap table to wrap figure."
1079 i = find_token(document.body, "\\begin_inset Wrap table", i)
1082 document.body[i] = document.body[i].replace('\\begin_inset Wrap table', '\\begin_inset Wrap figure')
1086 def revert_vietnamese(document):
1087 "Set language Vietnamese to English"
1088 # Set document language from Vietnamese to English
1090 if document.language == "vietnamese":
1091 document.language = "english"
1092 i = find_token(document.header, "\\language", 0)
1094 document.header[i] = "\\language english"
1097 j = find_token(document.body, "\\lang vietnamese", j)
1100 document.body[j] = document.body[j].replace("\\lang vietnamese", "\\lang english")
1104 def convert_japanese_cjk(document):
1105 "Set language japanese to japanese-cjk"
1106 # Set document language from japanese-plain to japanese
1108 if document.language == "japanese":
1109 document.language = "japanese-cjk"
1110 i = find_token(document.header, "\\language", 0)
1112 document.header[i] = "\\language japanese-cjk"
1115 j = find_token(document.body, "\\lang japanese", j)
1118 document.body[j] = document.body[j].replace("\\lang japanese", "\\lang japanese-cjk")
1122 def revert_japanese(document):
1123 "Set language japanese-plain to japanese"
1124 # Set document language from japanese-plain to japanese
1126 if document.language == "japanese-plain":
1127 document.language = "japanese"
1128 i = find_token(document.header, "\\language", 0)
1130 document.header[i] = "\\language japanese"
1133 j = find_token(document.body, "\\lang japanese-plain", j)
1136 document.body[j] = document.body[j].replace("\\lang japanese-plain", "\\lang japanese")
1140 def revert_japanese_cjk(document):
1141 "Set language japanese-cjk to japanese"
1142 # Set document language from japanese-plain to japanese
1144 if document.language == "japanese-cjk":
1145 document.language = "japanese"
1146 i = find_token(document.header, "\\language", 0)
1148 document.header[i] = "\\language japanese"
1151 j = find_token(document.body, "\\lang japanese-cjk", j)
1154 document.body[j] = document.body[j].replace("\\lang japanese-cjk", "\\lang japanese")
1158 def revert_japanese_encoding(document):
1159 "Set input encoding form EUC-JP-plain to EUC-JP etc."
1160 # Set input encoding form EUC-JP-plain to EUC-JP etc.
1162 i = find_token(document.header, "\\inputencoding EUC-JP-plain", 0)
1164 document.header[i] = "\\inputencoding EUC-JP"
1166 j = find_token(document.header, "\\inputencoding JIS-plain", 0)
1168 document.header[j] = "\\inputencoding JIS"
1170 k = find_token(document.header, "\\inputencoding SJIS-plain", 0)
1171 if k != -1: # convert to UTF8 since there is currently no SJIS encoding
1172 document.header[k] = "\\inputencoding UTF8"
1175 def revert_inset_info(document):
1176 'Replace info inset with its content'
1179 i = find_token(document.body, '\\begin_inset Info', i)
1182 j = find_end_of_inset(document.body, i + 1)
1185 document.warning("Malformed LyX document: Could not find end of Info inset.")
1188 for k in range(i, j+1):
1189 if document.body[k].startswith("arg"):
1190 arg = document.body[k][3:].strip().strip('"')
1191 if document.body[k].startswith("type"):
1192 type = document.body[k][4:].strip().strip('"')
1193 # I think there is a newline after \\end_inset, which should be removed.
1194 if document.body[j + 1].strip() == "":
1195 document.body[i : (j + 2)] = [type + ':' + arg]
1197 document.body[i : (j + 1)] = [type + ':' + arg]
1200 def convert_pdf_options(document):
1201 # Set the pdfusetitle tag, delete the pdf_store_options,
1202 # set quotes for bookmarksopenlevel"
1203 has_hr = get_value(document.header, "\\use_hyperref", 0, default = "0")
1205 k = find_token(document.header, "\\use_hyperref", 0)
1206 document.header.insert(k + 1, "\\pdf_pdfusetitle true")
1207 k = find_token(document.header, "\\pdf_store_options", 0)
1209 del document.header[k]
1210 i = find_token(document.header, "\\pdf_bookmarksopenlevel", k)
1212 document.header[i] = document.header[i].replace('"', '')
1215 def revert_pdf_options_2(document):
1216 # reset the pdfusetitle tag, set quotes for bookmarksopenlevel"
1217 k = find_token(document.header, "\\use_hyperref", 0)
1218 i = find_token(document.header, "\\pdf_pdfusetitle", k)
1220 del document.header[i]
1221 i = find_token(document.header, "\\pdf_bookmarksopenlevel", k)
1223 values = document.header[i].split()
1224 values[1] = ' "' + values[1] + '"'
1225 document.header[i] = ''.join(values)
1228 def convert_htmlurl(document):
1229 'Convert "htmlurl" to "href" insets for docbook'
1230 if document.backend != "docbook":
1234 i = find_token(document.body, "\\begin_inset CommandInset url", i)
1237 document.body[i] = "\\begin_inset CommandInset href"
1238 document.body[i + 1] = "LatexCommand href"
1242 def convert_url(document):
1243 'Convert url insets to url charstyles'
1244 if document.backend == "docbook":
1248 i = find_token(document.body, "\\begin_inset CommandInset url", i)
1251 n = find_token(document.body, "name", i)
1253 # place the URL name in typewriter before the new URL insert
1254 # grab the name 'bla' from the e.g. the line 'name "bla"',
1255 # therefore start with the 6th character
1256 name = document.body[n][6:-1]
1257 newname = [name + " "]
1258 document.body[i:i] = newname
1260 j = find_token(document.body, "target", i)
1262 document.warning("Malformed LyX document: Can't find target for url inset")
1265 target = document.body[j][8:-1]
1266 k = find_token(document.body, "\\end_inset", j)
1268 document.warning("Malformed LyX document: Can't find end of url inset")
1271 newstuff = ["\\begin_inset Flex URL",
1272 "status collapsed", "",
1273 "\\begin_layout Standard",
1278 document.body[i:k] = newstuff
1281 def convert_ams_classes(document):
1282 tc = document.textclass
1283 if (tc != "amsart" and tc != "amsart-plain" and
1284 tc != "amsart-seq" and tc != "amsbook"):
1286 if tc == "amsart-plain":
1287 document.textclass = "amsart"
1288 document.set_textclass()
1289 document.add_module("Theorems (Starred)")
1291 if tc == "amsart-seq":
1292 document.textclass = "amsart"
1293 document.set_textclass()
1294 document.add_module("Theorems (AMS)")
1296 #Now we want to see if any of the environments in the extended theorems
1297 #module were used in this document. If so, we'll add that module, too.
1298 layouts = ["Criterion", "Algorithm", "Axiom", "Condition", "Note", \
1299 "Notation", "Summary", "Acknowledgement", "Conclusion", "Fact", \
1302 r = re.compile(r'^\\begin_layout (.*?)\*?\s*$')
1305 i = find_token(document.body, "\\begin_layout", i)
1308 m = r.match(document.body[i])
1310 document.warning("Weirdly formed \\begin_layout at line %d of body!" % i)
1314 if layouts.count(m) != 0:
1315 document.add_module("Theorems (AMS-Extended)")
1319 def revert_href(document):
1320 'Reverts hyperlink insets (href) to url insets (url)'
1323 i = find_token(document.body, "\\begin_inset CommandInset href", i)
1326 document.body[i : i + 2] = \
1327 ["\\begin_inset CommandInset url", "LatexCommand url"]
1330 def revert_url(document):
1331 'Reverts Flex URL insets to old-style URL insets'
1334 i = find_token(document.body, "\\begin_inset Flex URL", i)
1337 j = find_end_of_inset(document.body, i)
1339 document.warning("Can't find end of inset in revert_url!")
1341 k = find_default_layout(document, i, j)
1343 document.warning("Can't find default layout in revert_url!")
1346 l = find_end_of(document.body, k, "\\begin_layout", "\\end_layout")
1347 if l == -1 or l >= j:
1348 document.warning("Can't find end of default layout in revert_url!")
1351 # OK, so the inset's data is between lines k and l.
1352 data = " ".join(document.body[k+1:l])
1354 newinset = ["\\begin_inset LatexCommand url", "target \"" + data + "\"",\
1356 document.body[i:j+1] = newinset
1357 i = i + len(newinset)
1360 def convert_include(document):
1361 'Converts include insets to new format.'
1363 r = re.compile(r'\\begin_inset Include\s+\\([^{]+){([^}]*)}(?:\[(.*)\])?')
1365 i = find_token(document.body, "\\begin_inset Include", i)
1368 line = document.body[i]
1369 previewline = document.body[i + 1]
1372 document.warning("Unable to match line " + str(i) + " of body!")
1378 insertion = ["\\begin_inset CommandInset include",
1379 "LatexCommand " + cmd, previewline,
1380 "filename \"" + fn + "\""]
1383 insertion.append("lstparams " + '"' + opt + '"')
1385 document.body[i : i + 2] = insertion
1389 def revert_include(document):
1390 'Reverts include insets to old format.'
1392 r0 = re.compile('preview.*')
1393 r1 = re.compile('LatexCommand (.+)')
1394 r2 = re.compile('filename "(.+)"')
1395 r3 = re.compile('lstparams "(.*)"')
1397 i = find_token(document.body, "\\begin_inset CommandInset include", i)
1401 if r0.match(document.body[nextline]):
1402 previewline = document.body[nextline]
1406 m = r1.match(document.body[nextline])
1408 document.warning("Malformed LyX document: No LatexCommand line for `" +
1409 document.body[i] + "' on line " + str(i) + ".")
1414 m = r2.match(document.body[nextline])
1416 document.warning("Malformed LyX document: No filename line for `" + \
1417 document.body[i] + "' on line " + str(i) + ".")
1423 if (cmd == "lstinputlisting"):
1424 m = r3.match(document.body[nextline])
1426 options = m.group(1)
1429 newline = "\\begin_inset Include \\" + cmd + "{" + fn + "}"
1431 newline += ("[" + options + "]")
1432 insertion = [newline]
1433 if previewline != "":
1434 insertion.append(previewline)
1435 document.body[i : nextline] = insertion
1439 def revert_albanian(document):
1440 "Set language Albanian to English"
1442 if document.language == "albanian":
1443 document.language = "english"
1444 i = find_token(document.header, "\\language", 0)
1446 document.header[i] = "\\language english"
1449 j = find_token(document.body, "\\lang albanian", j)
1452 document.body[j] = document.body[j].replace("\\lang albanian", "\\lang english")
1456 def revert_lowersorbian(document):
1457 "Set language lower Sorbian to English"
1459 if document.language == "lowersorbian":
1460 document.language = "english"
1461 i = find_token(document.header, "\\language", 0)
1463 document.header[i] = "\\language english"
1466 j = find_token(document.body, "\\lang lowersorbian", j)
1469 document.body[j] = document.body[j].replace("\\lang lowersorbian", "\\lang english")
1473 def revert_uppersorbian(document):
1474 "Set language uppersorbian to usorbian as this was used in LyX 1.5"
1476 if document.language == "uppersorbian":
1477 document.language = "usorbian"
1478 i = find_token(document.header, "\\language", 0)
1480 document.header[i] = "\\language usorbian"
1483 j = find_token(document.body, "\\lang uppersorbian", j)
1486 document.body[j] = document.body[j].replace("\\lang uppersorbian", "\\lang usorbian")
1490 def convert_usorbian(document):
1491 "Set language usorbian to uppersorbian"
1493 if document.language == "usorbian":
1494 document.language = "uppersorbian"
1495 i = find_token(document.header, "\\language", 0)
1497 document.header[i] = "\\language uppersorbian"
1500 j = find_token(document.body, "\\lang usorbian", j)
1503 document.body[j] = document.body[j].replace("\\lang usorbian", "\\lang uppersorbian")
1507 def revert_macro_optional_params(document):
1508 "Convert macro definitions with optional parameters into ERTs"
1509 # Stub to convert macro definitions with one or more optional parameters
1510 # into uninterpreted ERT insets
1513 def revert_hyperlinktype(document):
1514 'Reverts hyperlink type'
1518 i = find_token(document.body, "target", i)
1521 j = find_token(document.body, "type", i)
1525 del document.body[j]
1529 def revert_pagebreak(document):
1530 'Reverts pagebreak to ERT'
1533 i = find_token(document.body, "\\pagebreak", i)
1536 document.body[i] = '\\begin_inset ERT\nstatus collapsed\n\n' \
1537 '\\begin_layout Standard\n\n\n\\backslash\n' \
1538 'pagebreak{}\n\\end_layout\n\n\\end_inset\n\n'
1542 def revert_linebreak(document):
1543 'Reverts linebreak to ERT'
1546 i = find_token(document.body, "\\linebreak", i)
1549 document.body[i] = '\\begin_inset ERT\nstatus collapsed\n\n' \
1550 '\\begin_layout Standard\n\n\n\\backslash\n' \
1551 'linebreak{}\n\\end_layout\n\n\\end_inset\n\n'
1555 def revert_latin(document):
1556 "Set language Latin to English"
1558 if document.language == "latin":
1559 document.language = "english"
1560 i = find_token(document.header, "\\language", 0)
1562 document.header[i] = "\\language english"
1565 j = find_token(document.body, "\\lang latin", j)
1568 document.body[j] = document.body[j].replace("\\lang latin", "\\lang english")
1572 def revert_samin(document):
1573 "Set language North Sami to English"
1575 if document.language == "samin":
1576 document.language = "english"
1577 i = find_token(document.header, "\\language", 0)
1579 document.header[i] = "\\language english"
1582 j = find_token(document.body, "\\lang samin", j)
1585 document.body[j] = document.body[j].replace("\\lang samin", "\\lang english")
1589 def convert_serbocroatian(document):
1590 "Set language Serbocroatian to Croatian as this was really Croatian in LyX 1.5"
1592 if document.language == "serbocroatian":
1593 document.language = "croatian"
1594 i = find_token(document.header, "\\language", 0)
1596 document.header[i] = "\\language croatian"
1599 j = find_token(document.body, "\\lang serbocroatian", j)
1602 document.body[j] = document.body[j].replace("\\lang serbocroatian", "\\lang croatian")
1606 def convert_framed_notes(document):
1607 "Convert framed notes to boxes. "
1610 i = find_tokens(document.body, ["\\begin_inset Note Framed", "\\begin_inset Note Shaded"], i)
1613 subst = [document.body[i].replace("\\begin_inset Note", "\\begin_inset Box"),
1622 'height_special "totalheight"']
1623 document.body[i:i+1] = subst
1627 def convert_module_names(document):
1628 modulemap = { 'Braille' : 'braille', 'Endnote' : 'endnotes', 'Foot to End' : 'foottoend',\
1629 'Hanging' : 'hanging', 'Linguistics' : 'linguistics', 'Logical Markup' : 'logicalmkup', \
1630 'Theorems (AMS-Extended)' : 'theorems-ams-extended', 'Theorems (AMS)' : 'theorems-ams', \
1631 'Theorems (Order By Chapter)' : 'theorems-chap', 'Theorems (Order By Section)' : 'theorems-sec', \
1632 'Theorems (Starred)' : 'theorems-starred', 'Theorems' : 'theorems-std' }
1633 modlist = document.get_module_list()
1634 if len(modlist) == 0:
1638 if modulemap.has_key(mod):
1639 newmodlist.append(modulemap[mod])
1641 document.warning("Can't find module %s in the module map!" % mod)
1642 newmodlist.append(mod)
1643 document.set_module_list(newmodlist)
1646 def revert_module_names(document):
1647 modulemap = { 'braille' : 'Braille', 'endnotes' : 'Endnote', 'foottoend' : 'Foot to End',\
1648 'hanging' : 'Hanging', 'linguistics' : 'Linguistics', 'logicalmkup' : 'Logical Markup', \
1649 'theorems-ams-extended' : 'Theorems (AMS-Extended)', 'theorems-ams' : 'Theorems (AMS)', \
1650 'theorems-chap' : 'Theorems (Order By Chapter)', 'theorems-sec' : 'Theorems (Order By Section)', \
1651 'theorems-starred' : 'Theorems (Starred)', 'theorems-std' : 'Theorems'}
1652 modlist = document.get_module_list()
1653 if len(modlist) == 0:
1657 if modulemap.has_key(mod):
1658 newmodlist.append(modulemap[mod])
1660 document.warning("Can't find module %s in the module map!" % mod)
1661 newmodlist.append(mod)
1662 document.set_module_list(newmodlist)
1665 def revert_colsep(document):
1666 i = find_token(document.header, "\\columnsep", 0)
1669 colsepline = document.header[i]
1670 r = re.compile(r'\\columnsep (.*)')
1671 m = r.match(colsepline)
1673 document.warning("Malformed column separation line!")
1676 del document.header[i]
1677 #it seems to be safe to add the package even if it is already used
1678 pretext = ["\\usepackage{geometry}", "\\geometry{columnsep=" + colsep + "}"]
1680 add_to_preamble(document, pretext)
1683 def revert_framed_notes(document):
1684 "Revert framed boxes to notes. "
1687 i = find_tokens(document.body, ["\\begin_inset Box Framed", "\\begin_inset Box Shaded"], i)
1691 j = find_end_of_inset(document.body, i + 1)
1694 document.warning("Malformed LyX document: Could not find end of Box inset.")
1695 k = find_token(document.body, "status", i + 1, j)
1697 document.warning("Malformed LyX document: Missing `status' tag in Box inset.")
1699 status = document.body[k]
1700 l = find_default_layout(document, i + 1, j)
1702 document.warning("Malformed LyX document: Missing `\\begin_layout' in Box inset.")
1704 m = find_token(document.body, "\\end_layout", i + 1, j)
1706 document.warning("Malformed LyX document: Missing `\\end_layout' in Box inset.")
1708 ibox = find_token(document.body, "has_inner_box 1", i + 1, k)
1709 pbox = find_token(document.body, "use_parbox 1", i + 1, k)
1710 if ibox == -1 and pbox == -1:
1711 document.body[i] = document.body[i].replace("\\begin_inset Box", "\\begin_inset Note")
1712 del document.body[i+1:k]
1714 document.body[i] = document.body[i].replace("\\begin_inset Box Shaded", "\\begin_inset Box Frameless")
1715 subst1 = [document.body[l],
1716 "\\begin_inset Note Shaded",
1718 '\\begin_layout Standard']
1719 document.body[l:l + 1] = subst1
1720 subst2 = [document.body[m], "\\end_layout", "\\end_inset"]
1721 document.body[m:m + 1] = subst2
1725 def revert_slash(document):
1726 'Revert \\SpecialChar \\slash{} to ERT'
1727 r = re.compile(r'\\SpecialChar \\slash{}')
1729 while i < len(document.body):
1730 m = r.match(document.body[i])
1732 subst = ['\\begin_inset ERT',
1733 'status collapsed', '',
1734 '\\begin_layout Standard',
1735 '', '', '\\backslash',
1739 document.body[i: i+1] = subst
1745 def revert_nobreakdash(document):
1746 'Revert \\SpecialChar \\nobreakdash- to ERT'
1748 while i < len(document.body):
1749 line = document.body[i]
1750 r = re.compile(r'\\SpecialChar \\nobreakdash-')
1753 subst = ['\\begin_inset ERT',
1754 'status collapsed', '',
1755 '\\begin_layout Standard', '', '',
1760 document.body[i:i+1] = subst
1762 j = find_token(document.header, "\\use_amsmath", 0)
1764 document.warning("Malformed LyX document: Missing '\\use_amsmath'.")
1766 document.header[j] = "\\use_amsmath 2"
1771 #Returns number of lines added/removed
1772 def revert_nocite_key(body, start, end):
1773 'key "..." -> \nocite{...}'
1774 r = re.compile(r'^key "(.*)"')
1778 m = r.match(body[i])
1780 body[i:i+1] = ["\\backslash", "nocite{" + m.group(1) + "}"]
1781 j += 1 # because we added a line
1782 i += 2 # skip that line
1785 j -= 1 # because we deleted a line
1786 # no need to change i, since it now points to the next line
1790 def revert_nocite(document):
1791 "Revert LatexCommand nocite to ERT"
1794 i = find_token(document.body, "\\begin_inset CommandInset citation", i)
1797 if (document.body[i+1] != "LatexCommand nocite"):
1798 # note that we already incremented i
1801 insetEnd = find_end_of_inset(document.body, i)
1803 #this should not happen
1804 document.warning("End of CommandInset citation not found in revert_nocite!")
1807 paramLocation = i + 2 #start of the inset's parameters
1809 document.body[i:i+2] = \
1810 ["\\begin_inset ERT", "status collapsed", "", "\\begin_layout Standard"]
1811 # that added two lines
1814 #print insetEnd, document.body[i: insetEnd + 1]
1815 insetEnd += revert_nocite_key(document.body, paramLocation, insetEnd)
1816 #print insetEnd, document.body[i: insetEnd + 1]
1817 document.body.insert(insetEnd, "\\end_layout")
1818 document.body.insert(insetEnd + 1, "")
1822 def revert_btprintall(document):
1823 "Revert (non-bibtopic) btPrintAll option to ERT \nocite{*}"
1824 i = find_token(document.header, '\\use_bibtopic', 0)
1826 document.warning("Malformed lyx document: Missing '\\use_bibtopic'.")
1828 if get_value(document.header, '\\use_bibtopic', 0) == "false":
1830 while i < len(document.body):
1831 i = find_token(document.body, "\\begin_inset CommandInset bibtex", i)
1834 j = find_end_of_inset(document.body, i + 1)
1836 #this should not happen
1837 document.warning("End of CommandInset bibtex not found in revert_btprintall!")
1838 j = len(document.body)
1839 # this range isn't really right, but it should be OK, since we shouldn't
1840 # see more than one matching line in each inset
1842 for k in range(i, j):
1843 if (document.body[k] == 'btprint "btPrintAll"'):
1844 del document.body[k]
1845 subst = ["\\begin_inset ERT",
1846 "status collapsed", "",
1847 "\\begin_layout Standard", "",
1852 document.body[i:i] = subst
1853 addlines = addedlines + len(subst) - 1
1857 def revert_bahasam(document):
1858 "Set language Bahasa Malaysia to Bahasa Indonesia"
1860 if document.language == "bahasam":
1861 document.language = "bahasa"
1862 i = find_token(document.header, "\\language", 0)
1864 document.header[i] = "\\language bahasa"
1867 j = find_token(document.body, "\\lang bahasam", j)
1870 document.body[j] = document.body[j].replace("\\lang bahasam", "\\lang bahasa")
1874 def revert_interlingua(document):
1875 "Set language Interlingua to English"
1877 if document.language == "interlingua":
1878 document.language = "english"
1879 i = find_token(document.header, "\\language", 0)
1881 document.header[i] = "\\language english"
1884 j = find_token(document.body, "\\lang interlingua", j)
1887 document.body[j] = document.body[j].replace("\\lang interlingua", "\\lang english")
1891 def revert_serbianlatin(document):
1892 "Set language Serbian-Latin to Croatian"
1894 if document.language == "serbian-latin":
1895 document.language = "croatian"
1896 i = find_token(document.header, "\\language", 0)
1898 document.header[i] = "\\language croatian"
1901 j = find_token(document.body, "\\lang serbian-latin", j)
1904 document.body[j] = document.body[j].replace("\\lang serbian-latin", "\\lang croatian")
1908 def revert_rotfloat(document):
1909 " Revert sideways custom floats. "
1912 # whitespace intended (exclude \\begin_inset FloatList)
1913 i = find_token(document.body, "\\begin_inset Float ", i)
1916 line = document.body[i]
1917 r = re.compile(r'\\begin_inset Float (.*)$')
1920 document.warning("Unable to match line " + str(i) + " of body!")
1923 floattype = m.group(1)
1924 if floattype == "figure" or floattype == "table":
1927 j = find_end_of_inset(document.body, i)
1929 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_rotfloat.")
1933 if get_value(document.body, 'sideways', i, j) == "false":
1936 l = find_default_layout(document, i + 1, j)
1938 document.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
1940 subst = ['\\begin_layout Standard',
1941 '\\begin_inset ERT',
1942 'status collapsed', '',
1943 '\\begin_layout Standard', '', '',
1945 'end{sideways' + floattype + '}',
1946 '\\end_layout', '', '\\end_inset']
1947 document.body[j : j+1] = subst
1948 addedLines = len(subst) - 1
1949 del document.body[i+1 : l]
1950 addedLines -= (l-1) - (i+1)
1951 subst = ['\\begin_inset ERT', 'status collapsed', '',
1952 '\\begin_layout Standard', '', '', '\\backslash',
1953 'begin{sideways' + floattype + '}',
1954 '\\end_layout', '', '\\end_inset', '',
1956 document.body[i : i+1] = subst
1957 addedLines += len(subst) - 1
1958 if floattype == "algorithm":
1959 add_to_preamble(document,
1960 ['% Commands inserted by lyx2lyx for sideways algorithm float',
1961 '\\usepackage{rotfloat}',
1962 '\\floatstyle{ruled}',
1963 '\\newfloat{algorithm}{tbp}{loa}',
1964 '\\floatname{algorithm}{Algorithm}'])
1966 document.warning("Cannot create preamble definition for custom float" + floattype + ".")
1970 def revert_widesideways(document):
1971 " Revert wide sideways floats. "
1974 # whitespace intended (exclude \\begin_inset FloatList)
1975 i = find_token(document.body, '\\begin_inset Float ', i)
1978 line = document.body[i]
1979 r = re.compile(r'\\begin_inset Float (.*)$')
1982 document.warning("Unable to match line " + str(i) + " of body!")
1985 floattype = m.group(1)
1986 if floattype != "figure" and floattype != "table":
1989 j = find_end_of_inset(document.body, i)
1991 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_widesideways.")
1994 if get_value(document.body, 'sideways', i, j) == "false" or \
1995 get_value(document.body, 'wide', i, j) == "false":
1998 l = find_default_layout(document, i + 1, j)
2000 document.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
2002 subst = ['\\begin_layout Standard', '\\begin_inset ERT',
2003 'status collapsed', '',
2004 '\\begin_layout Standard', '', '', '\\backslash',
2005 'end{sideways' + floattype + '*}',
2006 '\\end_layout', '', '\\end_inset']
2007 document.body[j : j+1] = subst
2008 addedLines = len(subst) - 1
2009 del document.body[i+1:l-1]
2010 addedLines -= (l-1) - (i+1)
2011 subst = ['\\begin_inset ERT', 'status collapsed', '',
2012 '\\begin_layout Standard', '', '', '\\backslash',
2013 'begin{sideways' + floattype + '*}', '\\end_layout', '',
2014 '\\end_inset', '', '\\end_layout', '']
2015 document.body[i : i+1] = subst
2016 addedLines += len(subst) - 1
2017 add_to_preamble(document, ['\\usepackage{rotfloat}\n'])
2021 def revert_inset_embedding(document, type):
2022 ' Remove embed tag from certain type of insets'
2025 i = find_token(document.body, "\\begin_inset %s" % type, i)
2028 j = find_end_of_inset(document.body, i)
2030 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_inset_embedding.")
2033 k = find_token(document.body, "\tembed", i, j)
2035 k = find_token(document.body, "embed", i, j)
2037 del document.body[k]
2041 def revert_external_embedding(document):
2042 ' Remove embed tag from external inset '
2043 revert_inset_embedding(document, 'External')
2046 def convert_subfig(document):
2047 " Convert subfigures to subfloats. "
2050 i = find_token(document.body, '\\begin_inset Graphics', i)
2053 endInset = find_end_of_inset(document.body, i)
2055 document.warning("Malformed lyx document: Missing '\\end_inset' in convert_subfig.")
2058 k = find_token(document.body, '\tsubcaption', i, endInset)
2062 l = find_token(document.body, '\tsubcaptionText', i, endInset)
2064 document.warning("Malformed lyx document: Can't find subcaptionText!")
2067 caption = document.body[l][16:].strip('"')
2068 del document.body[l]
2069 del document.body[k]
2071 subst = ['\\begin_inset Float figure', 'wide false', 'sideways false',
2072 'status open', '', '\\begin_layout Plain Layout', '\\begin_inset Caption',
2073 '', '\\begin_layout Plain Layout'] + latex2lyx(caption) + \
2074 [ '\\end_layout', '', '\\end_inset', '',
2075 '\\end_layout', '', '\\begin_layout Plain Layout']
2076 document.body[i : i] = subst
2077 addedLines += len(subst)
2078 endInset += addedLines
2079 subst = ['', '\\end_inset', '', '\\end_layout']
2080 document.body[endInset : endInset] = subst
2081 addedLines += len(subst)
2085 def revert_subfig(document):
2086 " Revert subfloats. "
2089 # whitespace intended (exclude \\begin_inset FloatList)
2090 i = find_tokens(document.body, ['\\begin_inset Float ', '\\begin_inset Wrap'], i)
2096 j = find_end_of_inset(document.body, i)
2098 document.warning("Malformed lyx document: Missing '\\end_inset' (float) at line " + str(i + len(document.header)) + ".\n\t" + document.body[i])
2099 # document.warning(document.body[i-1] + "\n" + document.body[i+1])
2101 continue # this will get us back to the outer loop, since j == -1
2102 # look for embedded float (= subfloat)
2103 # whitespace intended (exclude \\begin_inset FloatList)
2104 k = find_token(document.body, '\\begin_inset Float ', i + 1, j)
2107 l = find_end_of_inset(document.body, k)
2109 document.warning("Malformed lyx document: Missing '\\end_inset' (embedded float).")
2112 continue # escape to the outer loop
2113 m = find_default_layout(document, k + 1, l)
2115 cap = find_token(document.body, '\\begin_inset Caption', k + 1, l)
2120 capend = find_end_of_inset(document.body, cap)
2122 document.warning("Malformed lyx document: Missing '\\end_inset' (caption).")
2126 lbl = find_token(document.body, '\\begin_inset CommandInset label', cap, capend)
2128 lblend = find_end_of_inset(document.body, lbl + 1)
2130 document.warning("Malformed lyx document: Missing '\\end_inset' (label).")
2132 for line in document.body[lbl:lblend + 1]:
2133 if line.startswith('name '):
2134 label = line.split()[1].strip('"')
2141 opt = find_token(document.body, '\\begin_inset OptArg', cap, capend)
2143 optend = find_end_of_inset(document.body, opt)
2145 document.warning("Malformed lyx document: Missing '\\end_inset' (OptArg).")
2147 optc = find_default_layout(document, opt, optend)
2149 document.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
2151 optcend = find_end_of(document.body, optc, "\\begin_layout", "\\end_layout")
2152 for line in document.body[optc:optcend]:
2153 if not line.startswith('\\'):
2154 shortcap += line.strip()
2158 for line in document.body[cap:capend]:
2159 if line in document.body[lbl:lblend]:
2161 elif line in document.body[opt:optend]:
2163 elif not line.startswith('\\'):
2164 caption += line.strip()
2166 caption += "\\backslash\nlabel{" + label + "}"
2167 subst = '\\begin_layout Plain Layout\n\\begin_inset ERT\nstatus collapsed\n\n' \
2168 '\\begin_layout Plain Layout\n\n}\n\\end_layout\n\n\\end_inset\n\n' \
2169 '\\end_layout\n\n\\begin_layout Plain Layout\n'
2170 subst = subst.split('\n')
2171 document.body[l : l+1] = subst
2172 addedLines = len(subst) - 1
2173 # this is before l and so is unchanged by the multiline insertion
2175 del document.body[cap:capend+1]
2176 addedLines -= (capend + 1 - cap)
2177 del document.body[k+1:m-1]
2178 addedLines -= (m - 1 - (k + 1))
2179 insertion = '\\begin_inset ERT\nstatus collapsed\n\n' \
2180 '\\begin_layout Plain Layout\n\n\\backslash\n' \
2182 if len(shortcap) > 0:
2183 insertion = insertion + "[" + shortcap + "]"
2184 if len(caption) > 0:
2185 insertion = insertion + "[" + caption + "]"
2186 insertion = insertion + '{%\n\\end_layout\n\n\\end_inset\n\n\\end_layout\n'
2187 insertion = insertion.split('\n')
2188 document.body[k : k + 1] = insertion
2189 addedLines += len(insertion) - 1
2190 add_to_preamble(document, ['\\usepackage{subfig}\n'])
2194 def revert_wrapplacement(document):
2195 " Revert placement options wrap floats (wrapfig). "
2198 i = find_token(document.body, "\\begin_inset Wrap figure", i)
2201 e = find_end_of_inset(document.body, i)
2202 j = find_token(document.body, "placement", i + 1, e)
2204 document.warning("Malformed LyX document: Couldn't find placement parameter of wrap float.")
2207 r = re.compile("placement (o|i|l|r)")
2208 m = r.match(document.body[j])
2210 document.warning("Malformed LyX document: Placement option isn't O|I|R|L!")
2211 document.body[j] = "placement " + m.group(1).lower()
2215 def remove_extra_embedded_files(document):
2216 " Remove \extra_embedded_files from buffer params "
2217 i = find_token(document.header, '\\extra_embedded_files', 0)
2220 document.header.pop(i)
2223 def convert_spaceinset(document):
2224 " Convert '\\InsetSpace foo' to '\\begin_inset Space foo\n\\end_inset' "
2226 while i < len(document.body):
2227 m = re.match(r'(.*)\\InsetSpace (.*)', document.body[i])
2231 subst = [before, "\\begin_inset Space " + after, "\\end_inset"]
2232 document.body[i: i+1] = subst
2238 def revert_spaceinset(document):
2239 " Revert '\\begin_inset Space foo\n\\end_inset' to '\\InsetSpace foo' "
2242 i = find_token(document.body, "\\begin_inset Space", i)
2245 j = find_end_of_inset(document.body, i)
2247 document.warning("Malformed LyX document: Could not find end of space inset.")
2249 document.body[i] = document.body[i].replace('\\begin_inset Space', '\\InsetSpace')
2250 del document.body[j]
2253 def convert_hfill(document):
2254 " Convert hfill to space inset "
2257 i = find_token(document.body, "\\hfill", i)
2260 subst = document.body[i].replace('\\hfill', \
2261 '\n\\begin_inset Space \\hfill{}\n\\end_inset')
2262 subst = subst.split('\n')
2263 document.body[i : i+1] = subst
2267 def revert_hfills(document):
2268 ' Revert \\hfill commands '
2269 hfill = re.compile(r'\\hfill')
2270 dotfill = re.compile(r'\\dotfill')
2271 hrulefill = re.compile(r'\\hrulefill')
2274 i = find_token(document.body, "\\InsetSpace", i)
2277 if hfill.search(document.body[i]):
2278 document.body[i] = \
2279 document.body[i].replace('\\InsetSpace \\hfill{}', '\\hfill')
2282 if dotfill.search(document.body[i]):
2283 subst = document.body[i].replace('\\InsetSpace \\dotfill{}', \
2284 '\\begin_inset ERT\nstatus collapsed\n\n' \
2285 '\\begin_layout Standard\n\n\n\\backslash\n' \
2286 'dotfill{}\n\\end_layout\n\n\\end_inset\n\n')
2287 subst = subst.split('\n')
2288 document.body[i : i+1] = subst
2291 if hrulefill.search(document.body[i]):
2292 subst = document.body[i].replace('\\InsetSpace \\hrulefill{}', \
2293 '\\begin_inset ERT\nstatus collapsed\n\n' \
2294 '\\begin_layout Standard\n\n\n\\backslash\n' \
2295 'hrulefill{}\n\\end_layout\n\n\\end_inset\n\n')
2296 subst = subst.split('\n')
2297 document.body[i : i+1] = subst
2302 def revert_hspace(document):
2303 ' Revert \\InsetSpace \\hspace{} to ERT '
2305 hspace = re.compile(r'\\hspace{}')
2306 hstar = re.compile(r'\\hspace\*{}')
2308 i = find_token(document.body, "\\InsetSpace \\hspace", i)
2311 length = get_value(document.body, '\\length', i+1)
2313 document.warning("Malformed lyx document: Missing '\\length' in Space inset.")
2315 del document.body[i+1]
2317 if hstar.search(document.body[i]):
2318 subst = document.body[i].replace('\\InsetSpace \\hspace*{}', \
2319 '\\begin_inset ERT\nstatus collapsed\n\n' \
2320 '\\begin_layout Standard\n\n\n\\backslash\n' \
2321 'hspace*{' + length + '}\n\\end_layout\n\n\\end_inset\n\n')
2322 subst = subst.split('\n')
2323 document.body[i : i+1] = subst
2324 addedLines += len(subst) - 1
2327 if hspace.search(document.body[i]):
2328 subst = document.body[i].replace('\\InsetSpace \\hspace{}', \
2329 '\\begin_inset ERT\nstatus collapsed\n\n' \
2330 '\\begin_layout Standard\n\n\n\\backslash\n' \
2331 'hspace{' + length + '}\n\\end_layout\n\n\\end_inset\n\n')
2332 subst = subst.split('\n')
2333 document.body[i : i+1] = subst
2334 addedLines += len(subst) - 1
2340 def revert_protected_hfill(document):
2341 ' Revert \\begin_inset Space \\hspace*{\\fill} to ERT '
2344 i = find_token(document.body, '\\begin_inset Space \\hspace*{\\fill}', i)
2347 j = find_end_of_inset(document.body, i)
2349 document.warning("Malformed LyX document: Could not find end of space inset.")
2351 del document.body[j]
2352 subst = document.body[i].replace('\\begin_inset Space \\hspace*{\\fill}', \
2353 '\\begin_inset ERT\nstatus collapsed\n\n' \
2354 '\\begin_layout Standard\n\n\n\\backslash\n' \
2355 'hspace*{\n\\backslash\nfill}\n\\end_layout\n\n\\end_inset\n\n')
2356 subst = subst.split('\n')
2357 document.body[i : i+1] = subst
2361 def revert_leftarrowfill(document):
2362 ' Revert \\begin_inset Space \\leftarrowfill{} to ERT '
2365 i = find_token(document.body, '\\begin_inset Space \\leftarrowfill{}', i)
2368 j = find_end_of_inset(document.body, i)
2370 document.warning("Malformed LyX document: Could not find end of space inset.")
2372 del document.body[j]
2373 subst = document.body[i].replace('\\begin_inset Space \\leftarrowfill{}', \
2374 '\\begin_inset ERT\nstatus collapsed\n\n' \
2375 '\\begin_layout Standard\n\n\n\\backslash\n' \
2376 'leftarrowfill{}\n\\end_layout\n\n\\end_inset\n\n')
2377 subst = subst.split('\n')
2378 document.body[i : i+1] = subst
2382 def revert_rightarrowfill(document):
2383 ' Revert \\begin_inset Space \\rightarrowfill{} to ERT '
2386 i = find_token(document.body, '\\begin_inset Space \\rightarrowfill{}', i)
2389 j = find_end_of_inset(document.body, i)
2391 document.warning("Malformed LyX document: Could not find end of space inset.")
2393 del document.body[j]
2394 subst = document.body[i].replace('\\begin_inset Space \\rightarrowfill{}', \
2395 '\\begin_inset ERT\nstatus collapsed\n\n' \
2396 '\\begin_layout Standard\n\n\n\\backslash\n' \
2397 'rightarrowfill{}\n\\end_layout\n\n\\end_inset\n\n')
2398 subst = subst.split('\n')
2399 document.body[i : i+1] = subst
2403 def revert_upbracefill(document):
2404 ' Revert \\begin_inset Space \\upbracefill{} to ERT '
2407 i = find_token(document.body, '\\begin_inset Space \\upbracefill{}', i)
2410 j = find_end_of_inset(document.body, i)
2412 document.warning("Malformed LyX document: Could not find end of space inset.")
2414 del document.body[j]
2415 subst = document.body[i].replace('\\begin_inset Space \\upbracefill{}', \
2416 '\\begin_inset ERT\nstatus collapsed\n\n' \
2417 '\\begin_layout Standard\n\n\n\\backslash\n' \
2418 'upbracefill{}\n\\end_layout\n\n\\end_inset\n\n')
2419 subst = subst.split('\n')
2420 document.body[i : i+1] = subst
2424 def revert_downbracefill(document):
2425 ' Revert \\begin_inset Space \\downbracefill{} to ERT '
2428 i = find_token(document.body, '\\begin_inset Space \\downbracefill{}', i)
2431 j = find_end_of_inset(document.body, i)
2433 document.warning("Malformed LyX document: Could not find end of space inset.")
2435 del document.body[j]
2436 subst = document.body[i].replace('\\begin_inset Space \\downbracefill{}', \
2437 '\\begin_inset ERT\nstatus collapsed\n\n' \
2438 '\\begin_layout Standard\n\n\n\\backslash\n' \
2439 'downbracefill{}\n\\end_layout\n\n\\end_inset\n\n')
2440 subst = subst.split('\n')
2441 document.body[i : i+1] = subst
2445 def revert_local_layout(document):
2446 ' Revert local layout headers.'
2449 i = find_token(document.header, "\\begin_local_layout", i)
2452 j = find_end_of(document.header, i, "\\begin_local_layout", "\\end_local_layout")
2454 # this should not happen
2456 document.header[i : j + 1] = []
2459 def convert_pagebreaks(document):
2460 ' Convert inline Newpage insets to new format '
2463 i = find_token(document.body, '\\newpage', i)
2466 document.body[i:i+1] = ['\\begin_inset Newpage newpage',
2470 i = find_token(document.body, '\\pagebreak', i)
2473 document.body[i:i+1] = ['\\begin_inset Newpage pagebreak',
2477 i = find_token(document.body, '\\clearpage', i)
2480 document.body[i:i+1] = ['\\begin_inset Newpage clearpage',
2484 i = find_token(document.body, '\\cleardoublepage', i)
2487 document.body[i:i+1] = ['\\begin_inset Newpage cleardoublepage',
2491 def revert_pagebreaks(document):
2492 ' Revert \\begin_inset Newpage to previous inline format '
2495 i = find_token(document.body, '\\begin_inset Newpage', i)
2498 j = find_end_of_inset(document.body, i)
2500 document.warning("Malformed LyX document: Could not find end of Newpage inset.")
2502 del document.body[j]
2503 document.body[i] = document.body[i].replace('\\begin_inset Newpage newpage', '\\newpage')
2504 document.body[i] = document.body[i].replace('\\begin_inset Newpage pagebreak', '\\pagebreak')
2505 document.body[i] = document.body[i].replace('\\begin_inset Newpage clearpage', '\\clearpage')
2506 document.body[i] = document.body[i].replace('\\begin_inset Newpage cleardoublepage', '\\cleardoublepage')
2509 def convert_linebreaks(document):
2510 ' Convert inline Newline insets to new format '
2513 i = find_token(document.body, '\\newline', i)
2516 document.body[i:i+1] = ['\\begin_inset Newline newline',
2520 i = find_token(document.body, '\\linebreak', i)
2523 document.body[i:i+1] = ['\\begin_inset Newline linebreak',
2527 def revert_linebreaks(document):
2528 ' Revert \\begin_inset Newline to previous inline format '
2531 i = find_token(document.body, '\\begin_inset Newline', i)
2534 j = find_end_of_inset(document.body, i)
2536 document.warning("Malformed LyX document: Could not find end of Newline inset.")
2538 del document.body[j]
2539 document.body[i] = document.body[i].replace('\\begin_inset Newline newline', '\\newline')
2540 document.body[i] = document.body[i].replace('\\begin_inset Newline linebreak', '\\linebreak')
2543 def convert_japanese_plain(document):
2544 ' Set language japanese-plain to japanese '
2546 if document.language == "japanese-plain":
2547 document.language = "japanese"
2548 i = find_token(document.header, "\\language", 0)
2550 document.header[i] = "\\language japanese"
2553 j = find_token(document.body, "\\lang japanese-plain", j)
2556 document.body[j] = document.body[j].replace("\\lang japanese-plain", "\\lang japanese")
2560 def revert_pdfpages(document):
2561 ' Revert pdfpages external inset to ERT '
2564 i = find_token(document.body, "\\begin_inset External", i)
2567 j = find_end_of_inset(document.body, i)
2569 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_pdfpages.")
2572 if get_value(document.body, 'template', i, j) == "PDFPages":
2573 filename = get_value(document.body, 'filename', i, j)
2575 r = re.compile(r'\textra PDFLaTeX \"(.*)\"$')
2576 for k in range(i, j):
2577 m = r.match(document.body[k])
2580 angle = get_value(document.body, 'rotateAngle', i, j)
2581 width = get_value(document.body, 'width', i, j)
2582 height = get_value(document.body, 'height', i, j)
2583 scale = get_value(document.body, 'scale', i, j)
2584 keepAspectRatio = find_token(document.body, "\tkeepAspectRatio", i, j)
2588 options += ",angle=" + angle
2590 options += "angle=" + angle
2593 options += ",width=" + convert_len(width)
2595 options += "width=" + convert_len(width)
2598 options += ",height=" + convert_len(height)
2600 options += "height=" + convert_len(height)
2603 options += ",scale=" + scale
2605 options += "scale=" + scale
2606 if keepAspectRatio != '':
2608 options += ",keepaspectratio"
2610 options += "keepaspectratio"
2612 options = '[' + options + ']'
2613 del document.body[i+1:j+1]
2614 document.body[i:i+1] = ['\\begin_inset ERT',
2617 '\\begin_layout Standard',
2620 'includepdf' + options + '{' + filename + '}',
2624 add_to_preamble(document, ['\\usepackage{pdfpages}\n'])
2630 def revert_mexican(document):
2631 ' Set language Spanish(Mexico) to Spanish '
2633 if document.language == "spanish-mexico":
2634 document.language = "spanish"
2635 i = find_token(document.header, "\\language", 0)
2637 document.header[i] = "\\language spanish"
2640 j = find_token(document.body, "\\lang spanish-mexico", j)
2643 document.body[j] = document.body[j].replace("\\lang spanish-mexico", "\\lang spanish")
2647 def remove_embedding(document):
2648 ' Remove embed tag from all insets '
2649 revert_inset_embedding(document, 'Graphics')
2650 revert_inset_embedding(document, 'External')
2651 revert_inset_embedding(document, 'CommandInset include')
2652 revert_inset_embedding(document, 'CommandInset bibtex')
2655 def revert_master(document):
2656 ' Remove master param '
2657 i = find_token(document.header, "\\master", 0)
2659 del document.header[i]
2662 def revert_graphics_group(document):
2663 ' Revert group information from graphics insets '
2666 i = find_token(document.body, "\\begin_inset Graphics", i)
2669 j = find_end_of_inset(document.body, i)
2671 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_graphics_group.")
2674 k = find_token(document.body, " groupId", i, j)
2678 del document.body[k]
2682 def update_apa_styles(document):
2683 ' Replace obsolete styles '
2685 if document.textclass != "apa":
2688 obsoletedby = { "Acknowledgments": "Acknowledgements",
2689 "Section*": "Section",
2690 "Subsection*": "Subsection",
2691 "Subsubsection*": "Subsubsection",
2692 "Paragraph*": "Paragraph",
2693 "Subparagraph*": "Subparagraph"}
2696 i = find_token(document.body, "\\begin_layout", i)
2700 layout = document.body[i][14:]
2701 if layout in obsoletedby:
2702 document.body[i] = "\\begin_layout " + obsoletedby[layout]
2707 def convert_paper_sizes(document):
2708 ' exchange size options legalpaper and executivepaper to correct order '
2709 # routine is needed to fix http://bugzilla.lyx.org/show_bug.cgi?id=4868
2712 i = find_token(document.header, "\\papersize executivepaper", 0)
2714 document.header[i] = "\\papersize legalpaper"
2716 j = find_token(document.header, "\\papersize legalpaper", 0)
2718 document.header[j] = "\\papersize executivepaper"
2721 def revert_paper_sizes(document):
2722 ' exchange size options legalpaper and executivepaper to correct order '
2725 i = find_token(document.header, "\\papersize executivepaper", 0)
2727 document.header[i] = "\\papersize legalpaper"
2729 j = find_token(document.header, "\\papersize legalpaper", 0)
2731 document.header[j] = "\\papersize executivepaper"
2734 def convert_InsetSpace(document):
2735 " Convert '\\begin_inset Space foo' to '\\begin_inset space foo'"
2738 i = find_token(document.body, "\\begin_inset Space", i)
2741 document.body[i] = document.body[i].replace('\\begin_inset Space', '\\begin_inset space')
2744 def revert_InsetSpace(document):
2745 " Revert '\\begin_inset space foo' to '\\begin_inset Space foo'"
2748 i = find_token(document.body, "\\begin_inset space", i)
2751 document.body[i] = document.body[i].replace('\\begin_inset space', '\\begin_inset Space')
2754 def convert_display_enum(document):
2755 " Convert 'display foo' to 'display false/true'"
2758 i = find_token(document.body, "\tdisplay", i)
2761 val = get_value(document.body, 'display', i)
2763 document.body[i] = document.body[i].replace('none', 'false')
2764 if val == "default":
2765 document.body[i] = document.body[i].replace('default', 'true')
2766 if val == "monochrome":
2767 document.body[i] = document.body[i].replace('monochrome', 'true')
2768 if val == "grayscale":
2769 document.body[i] = document.body[i].replace('grayscale', 'true')
2771 document.body[i] = document.body[i].replace('color', 'true')
2772 if val == "preview":
2773 document.body[i] = document.body[i].replace('preview', 'true')
2777 def revert_display_enum(document):
2778 " Revert 'display false/true' to 'display none/color'"
2781 i = find_token(document.body, "\tdisplay", i)
2784 val = get_value(document.body, 'display', i)
2786 document.body[i] = document.body[i].replace('false', 'none')
2788 document.body[i] = document.body[i].replace('true', 'default')
2792 def remove_fontsCJK(document):
2793 ' Remove font_cjk param '
2794 i = find_token(document.header, "\\font_cjk", 0)
2796 del document.header[i]
2799 def convert_plain_layout(document):
2800 " Convert 'PlainLayout' to 'Plain Layout'"
2803 i = find_token(document.body, '\\begin_layout PlainLayout', i)
2806 document.body[i] = document.body[i].replace('\\begin_layout PlainLayout', \
2807 '\\begin_layout Plain Layout')
2811 def revert_plain_layout(document):
2812 " Convert 'PlainLayout' to 'Plain Layout'"
2815 i = find_token(document.body, '\\begin_layout Plain Layout', i)
2818 document.body[i] = document.body[i].replace('\\begin_layout Plain Layout', \
2819 '\\begin_layout PlainLayout')
2823 def revert_plainlayout(document):
2824 " Convert 'PlainLayout' to 'Plain Layout'"
2827 i = find_token(document.body, '\\begin_layout PlainLayout', i)
2830 # This will be incorrect for some document classes, since Standard is not always
2831 # the default. But (a) it is probably the best we can do and (b) it will actually
2832 # work, in fact, since an unknown layout will be converted to default.
2833 document.body[i] = document.body[i].replace('\\begin_layout PlainLayout', \
2834 '\\begin_layout Standard')
2838 def revert_polytonicgreek(document):
2839 "Set language polytonic Greek to Greek"
2841 if document.language == "polutonikogreek":
2842 document.language = "greek"
2843 i = find_token(document.header, "\\language", 0)
2845 document.header[i] = "\\language greek"
2848 j = find_token(document.body, "\\lang polutonikogreek", j)
2851 document.body[j] = document.body[j].replace("\\lang polutonikogreek", "\\lang greek")
2859 supported_versions = ["1.6.0","1.6"]
2860 convert = [[277, [fix_wrong_tables]],
2861 [278, [close_begin_deeper]],
2862 [279, [long_charstyle_names]],
2863 [280, [axe_show_label]],
2866 [283, [convert_flex]],
2870 [287, [convert_wrapfig_options]],
2871 [288, [convert_inset_command]],
2872 [289, [convert_latexcommand_index]],
2875 [292, [convert_japanese_cjk]],
2877 [294, [convert_pdf_options]],
2878 [295, [convert_htmlurl, convert_url]],
2879 [296, [convert_include]],
2880 [297, [convert_usorbian]],
2886 [303, [convert_serbocroatian]],
2887 [304, [convert_framed_notes]],
2894 [311, [convert_ams_classes]],
2896 [313, [convert_module_names]],
2899 [316, [convert_subfig]],
2902 [319, [convert_spaceinset, convert_hfill]],
2904 [321, [convert_tablines]],
2905 [322, [convert_plain_layout]],
2906 [323, [convert_pagebreaks]],
2907 [324, [convert_linebreaks]],
2908 [325, [convert_japanese_plain]],
2911 [328, [remove_embedding, remove_extra_embedded_files, remove_inzip_options]],
2914 [331, [convert_ltcaption]],
2916 [333, [update_apa_styles]],
2917 [334, [convert_paper_sizes]],
2918 [335, [convert_InsetSpace]],
2920 [337, [convert_display_enum]],
2924 revert = [[337, [revert_polytonicgreek]],
2925 [336, [revert_display_enum]],
2926 [335, [remove_fontsCJK]],
2927 [334, [revert_InsetSpace]],
2928 [333, [revert_paper_sizes]],
2930 [331, [revert_graphics_group]],
2931 [330, [revert_ltcaption]],
2932 [329, [revert_leftarrowfill, revert_rightarrowfill, revert_upbracefill, revert_downbracefill]],
2933 [328, [revert_master]],
2935 [326, [revert_mexican]],
2936 [325, [revert_pdfpages]],
2938 [323, [revert_linebreaks]],
2939 [322, [revert_pagebreaks]],
2940 [321, [revert_local_layout, revert_plain_layout]],
2941 [320, [revert_tablines]],
2942 [319, [revert_protected_hfill]],
2943 [318, [revert_spaceinset, revert_hfills, revert_hspace]],
2944 [317, [remove_extra_embedded_files]],
2945 [316, [revert_wrapplacement]],
2946 [315, [revert_subfig]],
2947 [314, [revert_colsep, revert_plainlayout]],
2949 [312, [revert_module_names]],
2950 [311, [revert_rotfloat, revert_widesideways]],
2951 [310, [revert_external_embedding]],
2952 [309, [revert_btprintall]],
2953 [308, [revert_nocite]],
2954 [307, [revert_serbianlatin]],
2955 [306, [revert_slash, revert_nobreakdash]],
2956 [305, [revert_interlingua]],
2957 [304, [revert_bahasam]],
2958 [303, [revert_framed_notes]],
2960 [301, [revert_latin, revert_samin]],
2961 [300, [revert_linebreak]],
2962 [299, [revert_pagebreak]],
2963 [298, [revert_hyperlinktype]],
2964 [297, [revert_macro_optional_params]],
2965 [296, [revert_albanian, revert_lowersorbian, revert_uppersorbian]],
2966 [295, [revert_include]],
2967 [294, [revert_href, revert_url]],
2968 [293, [revert_pdf_options_2]],
2969 [292, [revert_inset_info]],
2970 [291, [revert_japanese, revert_japanese_encoding, revert_japanese_cjk]],
2971 [290, [revert_vietnamese]],
2972 [289, [revert_wraptable]],
2973 [288, [revert_latexcommand_index]],
2974 [287, [revert_inset_command]],
2975 [286, [revert_wrapfig_options]],
2976 [285, [revert_pdf_options]],
2977 [284, [remove_inzip_options]],
2979 [282, [revert_flex]],
2981 [280, [revert_begin_modules]],
2982 [279, [revert_show_label]],
2983 [278, [revert_long_charstyle_names]],
2989 if __name__ == "__main__":