1 # This file is part of lyx2lyx
2 # -*- coding: utf-8 -*-
3 # Copyright (C) 2007-2008 The LyX Team <lyx-devel@lists.lyx.org>
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 """ Convert files to the file format generated by lyx 1.6"""
25 from parser_tools import find_token, find_end_of, find_tokens, get_value, get_value_string
27 ####################################################################
28 # Private helper functions
30 def find_end_of_inset(lines, i):
31 " Find end of inset, where lines[i] is included."
32 return find_end_of(lines, i, "\\begin_inset", "\\end_inset")
36 # document.body[i] = wrap_insert_ert(...)
37 # wrap_into_ert may returns a multiline string, which should NOT appear
38 # in document.body. Insetad, do something like this:
39 # subst = wrap_inset_ert(...)
40 # subst = subst.split('\n')
41 # document.body[i:i+1] = subst
43 # where the last statement resets the counter to accord with the added
45 def wrap_into_ert(string, src, dst):
46 " Wrap a something into an ERT"
47 return string.replace(src, '\n\\begin_inset ERT\nstatus collapsed\n\\begin_layout Standard\n'
48 + dst + '\n\\end_layout\n\\end_inset\n')
50 def add_to_preamble(document, text):
51 """ Add text to the preamble if it is not already there.
52 Only the first line is checked!"""
54 if find_token(document.preamble, text[0], 0) != -1:
57 document.preamble.extend(text)
59 # Convert a LyX length into a LaTeX length
61 units = {"text%":"\\backslash\ntextwidth", "col%":"\\backslash\ncolumnwidth",
62 "page%":"\\backslash\npagewidth", "line%":"\\backslash\nlinewidth",
63 "theight%":"\\backslash\ntextheight", "pheight%":"\\backslash\npageheight"}
65 # Convert LyX units to LaTeX units
66 for unit in units.keys():
67 if len.find(unit) != -1:
68 len = '%f' % (len2value(len) / 100)
69 len = len.strip('0') + units[unit]
74 # Return the value of len without the unit in numerical form.
76 result = re.search('([+-]?[0-9.]+)', len)
78 return float(result.group(1))
82 # Unfortunately, this doesn't really work, since Standard isn't always default.
83 # But it's as good as we can do right now.
84 def find_default_layout(document, start, end):
85 l = find_token(document.body, "\\begin_layout Standard", start, end)
87 l = find_token(document.body, "\\begin_layout PlainLayout", start, end)
89 l = find_token(document.body, "\\begin_layout Plain Layout", start, end)
92 def get_option(document, m, option, default):
93 l = document.body[m].find(option)
96 val = document.body[m][l:].split('"')[1]
99 def remove_option(document, m, option):
100 l = document.body[m].find(option)
102 val = document.body[m][l:].split('"')[1]
103 document.body[m] = document.body[m][:l-1] + document.body[m][l+len(option + '="' + val + '"'):]
106 def set_option(document, m, option, value):
107 l = document.body[m].find(option)
109 oldval = document.body[m][l:].split('"')[1]
110 l = l + len(option + '="')
111 document.body[m] = document.body[m][:l] + value + document.body[m][l+len(oldval):]
113 document.body[m] = document.body[m][:-1] + ' ' + option + '="' + value + '">'
117 ####################################################################
119 def convert_ltcaption(document):
122 i = find_token(document.body, "\\begin_inset Tabular", i)
125 j = find_end_of_inset(document.body, i + 1)
127 document.warning("Malformed LyX document: Could not find end of tabular.")
130 nrows = int(document.body[i+1].split('"')[3])
131 ncols = int(document.body[i+1].split('"')[5])
134 for k in range(nrows):
135 m = find_token(document.body, "<row", m)
138 for k in range(ncols):
139 m = find_token(document.body, "<cell", m)
141 mend = find_token(document.body, "</cell>", m + 1)
142 # first look for caption insets
143 mcap = find_token(document.body, "\\begin_inset Caption", m + 1, mend)
144 # then look for ERT captions
146 mcap = find_token(document.body, "caption", m + 1, mend)
148 mcap = find_token(document.body, "\\backslash", mcap - 1, mcap)
151 if caption == 'true':
153 set_option(document, r, 'caption', 'true')
154 set_option(document, m, 'multicolumn', '1')
155 set_option(document, m, 'bottomline', 'false')
156 set_option(document, m, 'topline', 'false')
157 set_option(document, m, 'rightline', 'false')
158 set_option(document, m, 'leftline', 'false')
159 #j = find_end_of_inset(document.body, j + 1)
161 set_option(document, m, 'multicolumn', '2')
168 #FIXME Use of wrap_into_ert can confuse lyx2lyx
169 def revert_ltcaption(document):
172 i = find_token(document.body, "\\begin_inset Tabular", i)
175 j = find_end_of_inset(document.body, i + 1)
177 document.warning("Malformed LyX document: Could not find end of tabular.")
181 nrows = int(document.body[i+1].split('"')[3])
182 ncols = int(document.body[i+1].split('"')[5])
184 for k in range(nrows):
185 m = find_token(document.body, "<row", m)
186 caption = get_option(document, m, 'caption', 'false')
187 if caption == 'true':
188 remove_option(document, m, 'caption')
189 for k in range(ncols):
190 m = find_token(document.body, "<cell", m)
191 remove_option(document, m, 'multicolumn')
193 m = find_token(document.body, "\\begin_inset Caption", m)
196 m = find_end_of_inset(document.body, m + 1)
197 document.body[m] += wrap_into_ert("","","\\backslash\n\\backslash\n%")
203 def convert_tablines(document):
206 i = find_token(document.body, "\\begin_inset Tabular", i)
208 # LyX 1.3 inserted an extra space between \begin_inset
209 # and Tabular so let us try if this is the case and fix it.
210 i = find_token(document.body, "\\begin_inset Tabular", i)
214 document.body[i] = "\\begin_inset Tabular"
215 j = find_end_of_inset(document.body, i + 1)
217 document.warning("Malformed LyX document: Could not find end of tabular.")
221 nrows = int(document.body[i+1].split('"')[3])
222 ncols = int(document.body[i+1].split('"')[5])
225 for k in range(ncols):
226 m = find_token(document.body, "<column", m)
227 left = get_option(document, m, 'leftline', 'false')
228 right = get_option(document, m, 'rightline', 'false')
229 col_info.append([left, right])
230 remove_option(document, m, 'leftline')
231 remove_option(document, m, 'rightline')
235 for k in range(nrows):
236 m = find_token(document.body, "<row", m)
237 top = get_option(document, m, 'topline', 'false')
238 bottom = get_option(document, m, 'bottomline', 'false')
239 row_info.append([top, bottom])
240 remove_option(document, m, 'topline')
241 remove_option(document, m, 'bottomline')
246 for k in range(nrows*ncols):
247 m = find_token(document.body, "<cell", m)
248 mc_info.append(get_option(document, m, 'multicolumn', '0'))
251 for l in range(nrows):
252 for k in range(ncols):
253 m = find_token(document.body, '<cell', m)
254 if mc_info[l*ncols + k] == '0':
255 r = set_option(document, m, 'topline', row_info[l][0])
256 r = set_option(document, m, 'bottomline', row_info[l][1])
257 r = set_option(document, m, 'leftline', col_info[k][0])
258 r = set_option(document, m, 'rightline', col_info[k][1])
259 elif mc_info[l*ncols + k] == '1':
261 while s < ncols and mc_info[l*ncols + s] == '2':
263 if s < ncols and mc_info[l*ncols + s] != '1':
264 r = set_option(document, m, 'rightline', col_info[k][1])
265 if k > 0 and mc_info[l*ncols + k - 1] == '0':
266 r = set_option(document, m, 'leftline', col_info[k][0])
271 def revert_tablines(document):
274 i = find_token(document.body, "\\begin_inset Tabular", i)
277 j = find_end_of_inset(document.body, i + 1)
279 document.warning("Malformed LyX document: Could not find end of tabular.")
283 nrows = int(document.body[i+1].split('"')[3])
284 ncols = int(document.body[i+1].split('"')[5])
287 for k in range(nrows*ncols):
288 m = find_token(document.body, "<cell", m)
289 top = get_option(document, m, 'topline', 'false')
290 bottom = get_option(document, m, 'bottomline', 'false')
291 left = get_option(document, m, 'leftline', 'false')
292 right = get_option(document, m, 'rightline', 'false')
293 lines.append([top, bottom, left, right])
296 # we will want to ignore longtable captions
299 for k in range(nrows):
300 m = find_token(document.body, "<row", m)
301 caption = get_option(document, m, 'caption', 'false')
302 caption_info.append([caption])
307 for k in range(ncols):
308 m = find_token(document.body, "<column", m)
310 for l in range(nrows):
311 left = lines[l*ncols + k][2]
312 if left == 'false' and caption_info[l] == 'false':
314 set_option(document, m, 'leftline', left)
316 for l in range(nrows):
317 right = lines[l*ncols + k][3]
318 if right == 'false' and caption_info[l] == 'false':
320 set_option(document, m, 'rightline', right)
324 for k in range(nrows):
325 m = find_token(document.body, "<row", m)
327 for l in range(ncols):
328 top = lines[k*ncols + l][0]
331 if caption_info[k] == 'false':
333 set_option(document, m, 'topline', top)
335 for l in range(ncols):
336 bottom = lines[k*ncols + l][1]
337 if bottom == 'false':
339 if caption_info[k] == 'false':
341 set_option(document, m, 'bottomline', bottom)
347 def fix_wrong_tables(document):
350 i = find_token(document.body, "\\begin_inset Tabular", i)
353 j = find_end_of_inset(document.body, i + 1)
355 document.warning("Malformed LyX document: Could not find end of tabular.")
359 nrows = int(document.body[i+1].split('"')[3])
360 ncols = int(document.body[i+1].split('"')[5])
362 for l in range(nrows):
364 for k in range(ncols):
365 m = find_token(document.body, '<cell', m)
367 if document.body[m].find('multicolumn') != -1:
368 multicol_cont = int(document.body[m].split('"')[1])
370 if multicol_cont == 2 and (k == 0 or prev_multicolumn == 0):
371 document.body[m] = document.body[m][:5] + document.body[m][21:]
374 prev_multicolumn = multicol_cont
381 def close_begin_deeper(document):
385 i = find_tokens(document.body, ["\\begin_deeper", "\\end_deeper"], i)
390 if document.body[i][:13] == "\\begin_deeper":
397 document.body[-2:-2] = ['\\end_deeper' for i in range(depth)]
400 def long_charstyle_names(document):
403 i = find_token(document.body, "\\begin_inset CharStyle", i)
406 document.body[i] = document.body[i].replace("CharStyle ", "CharStyle CharStyle:")
409 def revert_long_charstyle_names(document):
412 i = find_token(document.body, "\\begin_inset CharStyle", i)
415 document.body[i] = document.body[i].replace("CharStyle CharStyle:", "CharStyle")
419 def axe_show_label(document):
422 i = find_token(document.body, "\\begin_inset CharStyle", i)
425 if document.body[i + 1].find("show_label") != -1:
426 if document.body[i + 1].find("true") != -1:
427 document.body[i + 1] = "status open"
428 del document.body[ i + 2]
430 if document.body[i + 1].find("false") != -1:
431 document.body[i + 1] = "status collapsed"
432 del document.body[ i + 2]
434 document.warning("Malformed LyX document: show_label neither false nor true.")
436 document.warning("Malformed LyX document: show_label missing in CharStyle.")
441 def revert_show_label(document):
444 i = find_token(document.body, "\\begin_inset CharStyle", i)
447 if document.body[i + 1].find("status open") != -1:
448 document.body.insert(i + 1, "show_label true")
450 if document.body[i + 1].find("status collapsed") != -1:
451 document.body.insert(i + 1, "show_label false")
453 document.warning("Malformed LyX document: no legal status line in CharStyle.")
456 def revert_begin_modules(document):
459 i = find_token(document.header, "\\begin_modules", i)
462 j = find_end_of(document.header, i, "\\begin_modules", "\\end_modules")
464 # this should not happen
466 document.header[i : j + 1] = []
468 def convert_flex(document):
469 "Convert CharStyle to Flex"
472 i = find_token(document.body, "\\begin_inset CharStyle", i)
475 document.body[i] = document.body[i].replace('\\begin_inset CharStyle', '\\begin_inset Flex')
477 def revert_flex(document):
478 "Convert Flex to CharStyle"
481 i = find_token(document.body, "\\begin_inset Flex", i)
484 document.body[i] = document.body[i].replace('\\begin_inset Flex', '\\begin_inset CharStyle')
487 # Discard PDF options for hyperref
488 def revert_pdf_options(document):
489 "Revert PDF options for hyperref."
490 # store the PDF options and delete the entries from the Lyx file
498 bookmarksnumbered = ""
500 bookmarksopenlevel = ""
508 i = find_token(document.header, "\\use_hyperref", i)
510 hyperref = get_value(document.header, "\\use_hyperref", i) == 'true'
511 del document.header[i]
512 i = find_token(document.header, "\\pdf_store_options", i)
514 del document.header[i]
515 i = find_token(document.header, "\\pdf_title", 0)
517 title = get_value_string(document.header, '\\pdf_title', 0, 0, True)
518 title = ' pdftitle={' + title + '}'
519 del document.header[i]
520 i = find_token(document.header, "\\pdf_author", 0)
522 author = get_value_string(document.header, '\\pdf_author', 0, 0, True)
524 author = ' pdfauthor={' + author + '}'
526 author = ',\n pdfauthor={' + author + '}'
527 del document.header[i]
528 i = find_token(document.header, "\\pdf_subject", 0)
530 subject = get_value_string(document.header, '\\pdf_subject', 0, 0, True)
531 if title == "" and author == "":
532 subject = ' pdfsubject={' + subject + '}'
534 subject = ',\n pdfsubject={' + subject + '}'
535 del document.header[i]
536 i = find_token(document.header, "\\pdf_keywords", 0)
538 keywords = get_value_string(document.header, '\\pdf_keywords', 0, 0, True)
539 if title == "" and author == "" and subject == "":
540 keywords = ' pdfkeywords={' + keywords + '}'
542 keywords = ',\n pdfkeywords={' + keywords + '}'
543 del document.header[i]
544 i = find_token(document.header, "\\pdf_bookmarks", 0)
546 bookmarks = get_value_string(document.header, '\\pdf_bookmarks', 0)
547 bookmarks = ',\n bookmarks=' + bookmarks
548 del document.header[i]
549 i = find_token(document.header, "\\pdf_bookmarksnumbered", i)
551 bookmarksnumbered = get_value_string(document.header, '\\pdf_bookmarksnumbered', 0)
552 bookmarksnumbered = ',\n bookmarksnumbered=' + bookmarksnumbered
553 del document.header[i]
554 i = find_token(document.header, "\\pdf_bookmarksopen", i)
556 bookmarksopen = get_value_string(document.header, '\\pdf_bookmarksopen', 0)
557 bookmarksopen = ',\n bookmarksopen=' + bookmarksopen
558 del document.header[i]
559 i = find_token(document.header, "\\pdf_bookmarksopenlevel", i)
561 bookmarksopenlevel = get_value_string(document.header, '\\pdf_bookmarksopenlevel', 0, 0, True)
562 bookmarksopenlevel = ',\n bookmarksopenlevel=' + bookmarksopenlevel
563 del document.header[i]
564 i = find_token(document.header, "\\pdf_breaklinks", i)
566 breaklinks = get_value_string(document.header, '\\pdf_breaklinks', 0)
567 breaklinks = ',\n breaklinks=' + breaklinks
568 del document.header[i]
569 i = find_token(document.header, "\\pdf_pdfborder", i)
571 pdfborder = get_value_string(document.header, '\\pdf_pdfborder', 0)
572 if pdfborder == 'true':
573 pdfborder = ',\n pdfborder={0 0 0}'
575 pdfborder = ',\n pdfborder={0 0 1}'
576 del document.header[i]
577 i = find_token(document.header, "\\pdf_colorlinks", i)
579 colorlinks = get_value_string(document.header, '\\pdf_colorlinks', 0)
580 colorlinks = ',\n colorlinks=' + colorlinks
581 del document.header[i]
582 i = find_token(document.header, "\\pdf_backref", i)
584 backref = get_value_string(document.header, '\\pdf_backref', 0)
585 backref = ',\n backref=' + backref
586 del document.header[i]
587 i = find_token(document.header, "\\pdf_pagebackref", i)
589 pagebackref = get_value_string(document.header, '\\pdf_pagebackref', 0)
590 pagebackref = ',\n pagebackref=' + pagebackref
591 del document.header[i]
592 i = find_token(document.header, "\\pdf_pagemode", 0)
594 pagemode = get_value_string(document.header, '\\pdf_pagemode', 0)
595 pagemode = ',\n pdfpagemode=' + pagemode
596 del document.header[i]
597 i = find_token(document.header, "\\pdf_quoted_options", 0)
599 otheroptions = get_value_string(document.header, '\\pdf_quoted_options', 0, 0, True)
600 if title == "" and author == "" and subject == "" and keywords == "":
601 otheroptions = ' ' + otheroptions
603 otheroptions = ',\n ' + otheroptions
604 del document.header[i]
606 # write to the preamble when hyperref was used
608 # preamble write preparations
609 # bookmark numbers are only output when they are turned on
610 if bookmarksopen == ',\n bookmarksopen=true':
611 bookmarksopen = bookmarksopen + bookmarksopenlevel
612 if bookmarks == ',\n bookmarks=true':
613 bookmarks = bookmarks + bookmarksnumbered + bookmarksopen
615 bookmarks = bookmarks
616 # hypersetup is only output when there are things to be set up
617 setupstart = '\\hypersetup{%\n'
619 if otheroptions == "" and title == "" and author == ""\
620 and subject == "" and keywords == "":
624 add_to_preamble(document,
625 ['% Commands inserted by lyx2lyx for PDF properties',
626 '\\usepackage[unicode=true'
645 def remove_inzip_options(document):
646 "Remove inzipName and embed options from the Graphics inset"
649 i = find_token(document.body, "\\begin_inset Graphics", i)
652 j = find_end_of_inset(document.body, i + 1)
655 document.warning("Malformed LyX document: Could not find end of graphics inset.")
656 # If there's a inzip param, just remove that
657 k = find_token(document.body, "\tinzipName", i + 1, j)
660 # embed option must follow the inzipName option
661 del document.body[k+1]
665 def convert_inset_command(document):
668 \begin_inset LatexCommand cmd
670 \begin_inset CommandInset InsetType
675 i = find_token(document.body, "\\begin_inset LatexCommand", i)
678 line = document.body[i]
679 r = re.compile(r'\\begin_inset LatexCommand (.*)$')
683 #this is adapted from factory.cpp
684 if cmdName[0:4].lower() == "cite":
685 insetName = "citation"
686 elif cmdName == "url" or cmdName == "htmlurl":
688 elif cmdName[-3:] == "ref":
690 elif cmdName == "tableofcontents":
692 elif cmdName == "printnomenclature":
693 insetName = "nomencl_print"
694 elif cmdName == "printindex":
695 insetName = "index_print"
698 insertion = ["\\begin_inset CommandInset " + insetName, "LatexCommand " + cmdName]
699 document.body[i : i+1] = insertion
702 def revert_inset_command(document):
705 \begin_inset CommandInset InsetType
708 \begin_inset LatexCommand cmd
709 Some insets may end up being converted to insets earlier versions of LyX
710 will not be able to recognize. Not sure what to do about that.
714 i = find_token(document.body, "\\begin_inset CommandInset", i)
717 nextline = document.body[i+1]
718 r = re.compile(r'LatexCommand\s+(.*)$')
719 m = r.match(nextline)
721 document.warning("Malformed LyX document: Missing LatexCommand in " + document.body[i] + ".")
724 insertion = ["\\begin_inset LatexCommand " + cmdName]
725 document.body[i : i+2] = insertion
728 def convert_wrapfig_options(document):
729 "Convert optional options for wrap floats (wrapfig)."
730 # adds the tokens "lines", "placement", and "overhang"
733 i = find_token(document.body, "\\begin_inset Wrap figure", i)
736 document.body.insert(i + 1, "lines 0")
737 j = find_token(document.body, "placement", i)
738 # placement can be already set or not; if not, set it
740 document.body.insert(i + 3, "overhang 0col%")
742 document.body.insert(i + 2, "placement o")
743 document.body.insert(i + 3, "overhang 0col%")
747 def revert_wrapfig_options(document):
748 "Revert optional options for wrap floats (wrapfig)."
751 i = find_token(document.body, "lines", i)
754 j = find_token(document.body, "overhang", i+1)
755 if j != i + 2 and j != -1:
756 document.warning("Malformed LyX document: Couldn't find overhang parameter of wrap float.")
760 del document.body[j-1]
764 # To convert and revert indices, we need to convert between LaTeX
765 # strings and LyXText. Here we do a minimal conversion to prevent
766 # crashes and data loss. Manual patch-up may be needed.
778 def convert_latexcommand_index(document):
779 "Convert from LatexCommand form to collapsable form."
782 i = find_token(document.body, "\\begin_inset CommandInset index", i)
785 if document.body[i + 1] != "LatexCommand index": # Might also be index_print
787 fullcontent = document.body[i + 2][5:]
789 fullcontent = fullcontent[1:-1]
790 document.body[i:i + 3] = ["\\begin_inset Index",
792 "\\begin_layout Standard"]
794 # We are now on the blank line preceding "\end_inset"
795 # We will write the content here, into the inset.
797 # Do the LaTeX --> LyX text conversion
798 for rep in replacements:
799 fullcontent = fullcontent.replace(rep[0], rep[1])
801 fullcontent = wrap_into_ert(fullcontent, r'\"', '"')
803 r = re.compile('^(.*?)(\$.*?\$)(.*)')
804 lines = fullcontent.split('\n')
806 #document.warning("LINE: " + line)
807 #document.warning(str(i) + ":" + document.body[i])
808 #document.warning("LAST: " + document.body[-1])
813 f = m.group(2).replace('\\\\', '\\')
817 s = wrap_into_ert(s, r'\\', '\\backslash')
818 s = wrap_into_ert(s, '{', '{')
819 s = wrap_into_ert(s, '}', '}')
820 subst = s.split('\n')
821 document.body[i:i] = subst
823 document.body.insert(i + 1, "\\begin_inset Formula " + f)
824 document.body.insert(i + 2, "\\end_inset")
826 # Generic, \\ -> \backslash:
827 g = wrap_into_ert(g, r'\\', '\\backslash')
828 g = wrap_into_ert(g, '{', '{')
829 g = wrap_into_ert(g, '}', '}')
830 subst = g.split('\n')
831 document.body[i+1:i+1] = subst
833 document.body.insert(i + 1, "\\end_layout")
836 def revert_latexcommand_index(document):
837 "Revert from collapsable form to LatexCommand form."
840 i = find_token(document.body, "\\begin_inset Index", i)
843 j = find_end_of_inset(document.body, i + 1)
846 del document.body[j - 1]
847 del document.body[j - 2] # \end_layout
848 document.body[i] = "\\begin_inset CommandInset index"
849 document.body[i + 1] = "LatexCommand index"
850 # clean up multiline stuff
853 for k in range(i + 3, j - 2):
854 line = document.body[k]
855 if line.startswith("\\begin_inset ERT"):
856 ert_end = find_end_of_inset(document.body, k + 1)
858 if line.startswith("\\begin_inset Formula"):
860 if line.startswith("\\begin_layout Standard"):
862 if line.startswith("\\begin_layout Plain Layout"):
864 if line.startswith("\\end_layout"):
866 if line.startswith("\\end_inset"):
868 if line.startswith("status collapsed"):
870 if line.startswith("status open"):
872 # a lossless reversion is not possible
873 # try at least to handle some common insets and settings
874 # do not replace inside ERTs
876 # Do the LyX text --> LaTeX conversion
877 for rep in replacements:
878 line = line.replace(rep[1], rep[0])
879 line = line.replace(r'\backslash', r'\textbackslash{}')
880 line = line.replace(r'\series bold', r'\bfseries{}').replace(r'\series default', r'\mdseries{}')
881 line = line.replace(r'\shape italic', r'\itshape{}').replace(r'\shape smallcaps', r'\scshape{}')
882 line = line.replace(r'\shape slanted', r'\slshape{}').replace(r'\shape default', r'\upshape{}')
883 line = line.replace(r'\emph on', r'\em{}').replace(r'\emph default', r'\em{}')
884 line = line.replace(r'\noun on', r'\scshape{}').replace(r'\noun default', r'\upshape{}')
885 line = line.replace(r'\bar under', r'\underbar{').replace(r'\bar default', r'}')
886 line = line.replace(r'\family sans', r'\sffamily{}').replace(r'\family default', r'\normalfont{}')
887 line = line.replace(r'\family typewriter', r'\ttfamily{}').replace(r'\family roman', r'\rmfamily{}')
888 line = line.replace(r'\InsetSpace ', r'').replace(r'\SpecialChar ', r'')
890 line = line.replace(r'\backslash', r'\\')
891 content = content + line;
892 document.body[i + 3] = "name " + '"' + content + '"'
893 for k in range(i + 4, j - 2):
894 del document.body[i + 4]
895 document.body.insert(i + 4, "")
896 del document.body[i + 2] # \begin_layout standard
900 def revert_wraptable(document):
901 "Revert wrap table to wrap figure."
904 i = find_token(document.body, "\\begin_inset Wrap table", i)
907 document.body[i] = document.body[i].replace('\\begin_inset Wrap table', '\\begin_inset Wrap figure')
911 def revert_vietnamese(document):
912 "Set language Vietnamese to English"
913 # Set document language from Vietnamese to English
915 if document.language == "vietnamese":
916 document.language = "english"
917 i = find_token(document.header, "\\language", 0)
919 document.header[i] = "\\language english"
922 j = find_token(document.body, "\\lang vietnamese", j)
925 document.body[j] = document.body[j].replace("\\lang vietnamese", "\\lang english")
929 def revert_japanese(document):
930 "Set language japanese-plain to japanese"
931 # Set document language from japanese-plain to japanese
933 if document.language == "japanese-plain":
934 document.language = "japanese"
935 i = find_token(document.header, "\\language", 0)
937 document.header[i] = "\\language japanese"
940 j = find_token(document.body, "\\lang japanese-plain", j)
943 document.body[j] = document.body[j].replace("\\lang japanese-plain", "\\lang japanese")
947 def revert_japanese_encoding(document):
948 "Set input encoding form EUC-JP-plain to EUC-JP etc."
949 # Set input encoding form EUC-JP-plain to EUC-JP etc.
951 i = find_token(document.header, "\\inputencoding EUC-JP-plain", 0)
953 document.header[i] = "\\inputencoding EUC-JP"
955 j = find_token(document.header, "\\inputencoding JIS-plain", 0)
957 document.header[j] = "\\inputencoding JIS"
959 k = find_token(document.header, "\\inputencoding SJIS-plain", 0)
960 if k != -1: # convert to UTF8 since there is currently no SJIS encoding
961 document.header[k] = "\\inputencoding UTF8"
964 def revert_inset_info(document):
965 'Replace info inset with its content'
968 i = find_token(document.body, '\\begin_inset Info', i)
971 j = find_end_of_inset(document.body, i + 1)
974 document.warning("Malformed LyX document: Could not find end of Info inset.")
977 for k in range(i, j+1):
978 if document.body[k].startswith("arg"):
979 arg = document.body[k][3:].strip().strip('"')
980 if document.body[k].startswith("type"):
981 type = document.body[k][4:].strip().strip('"')
982 # I think there is a newline after \\end_inset, which should be removed.
983 if document.body[j + 1].strip() == "":
984 document.body[i : (j + 2)] = [type + ':' + arg]
986 document.body[i : (j + 1)] = [type + ':' + arg]
989 def convert_pdf_options(document):
990 # Set the pdfusetitle tag, delete the pdf_store_options,
991 # set quotes for bookmarksopenlevel"
992 has_hr = get_value(document.header, "\\use_hyperref", 0, default = "0")
994 k = find_token(document.header, "\\use_hyperref", 0)
995 document.header.insert(k + 1, "\\pdf_pdfusetitle true")
996 k = find_token(document.header, "\\pdf_store_options", 0)
998 del document.header[k]
999 i = find_token(document.header, "\\pdf_bookmarksopenlevel", k)
1001 document.header[i] = document.header[i].replace('"', '')
1004 def revert_pdf_options_2(document):
1005 # reset the pdfusetitle tag, set quotes for bookmarksopenlevel"
1006 k = find_token(document.header, "\\use_hyperref", 0)
1007 i = find_token(document.header, "\\pdf_pdfusetitle", k)
1009 del document.header[i]
1010 i = find_token(document.header, "\\pdf_bookmarksopenlevel", k)
1012 values = document.header[i].split()
1013 values[1] = ' "' + values[1] + '"'
1014 document.header[i] = ''.join(values)
1017 def convert_htmlurl(document):
1018 'Convert "htmlurl" to "href" insets for docbook'
1019 if document.backend != "docbook":
1023 i = find_token(document.body, "\\begin_inset CommandInset url", i)
1026 document.body[i] = "\\begin_inset CommandInset href"
1027 document.body[i + 1] = "LatexCommand href"
1031 def convert_url(document):
1032 'Convert url insets to url charstyles'
1033 if document.backend == "docbook":
1037 i = find_token(document.body, "\\begin_inset CommandInset url", i)
1040 n = find_token(document.body, "name", i)
1042 # place the URL name in typewriter before the new URL insert
1043 # grab the name 'bla' from the e.g. the line 'name "bla"',
1044 # therefore start with the 6th character
1045 name = document.body[n][6:-1]
1046 newname = [name + " "]
1047 document.body[i:i] = newname
1049 j = find_token(document.body, "target", i)
1051 document.warning("Malformed LyX document: Can't find target for url inset")
1054 target = document.body[j][8:-1]
1055 k = find_token(document.body, "\\end_inset", j)
1057 document.warning("Malformed LyX document: Can't find end of url inset")
1060 newstuff = ["\\begin_inset Flex URL",
1061 "status collapsed", "",
1062 "\\begin_layout Standard",
1067 document.body[i:k] = newstuff
1070 def convert_ams_classes(document):
1071 tc = document.textclass
1072 if (tc != "amsart" and tc != "amsart-plain" and
1073 tc != "amsart-seq" and tc != "amsbook"):
1075 if tc == "amsart-plain":
1076 document.textclass = "amsart"
1077 document.set_textclass()
1078 document.add_module("Theorems (Starred)")
1080 if tc == "amsart-seq":
1081 document.textclass = "amsart"
1082 document.set_textclass()
1083 document.add_module("Theorems (AMS)")
1085 #Now we want to see if any of the environments in the extended theorems
1086 #module were used in this document. If so, we'll add that module, too.
1087 layouts = ["Criterion", "Algorithm", "Axiom", "Condition", "Note", \
1088 "Notation", "Summary", "Acknowledgement", "Conclusion", "Fact", \
1091 r = re.compile(r'^\\begin_layout (.*?)\*?\s*$')
1094 i = find_token(document.body, "\\begin_layout", i)
1097 m = r.match(document.body[i])
1099 document.warning("Weirdly formed \\begin_layout at line %d of body!" % i)
1103 if layouts.count(m) != 0:
1104 document.add_module("Theorems (AMS-Extended)")
1108 def revert_href(document):
1109 'Reverts hyperlink insets (href) to url insets (url)'
1112 i = find_token(document.body, "\\begin_inset CommandInset href", i)
1115 document.body[i : i + 2] = \
1116 ["\\begin_inset CommandInset url", "LatexCommand url"]
1119 def revert_url(document):
1120 'Reverts Flex URL insets to old-style URL insets'
1123 i = find_token(document.body, "\\begin_inset Flex URL", i)
1126 j = find_end_of_inset(document.body, i)
1128 document.warning("Can't find end of inset in revert_url!")
1130 k = find_default_layout(document, i, j)
1132 document.warning("Can't find default layout in revert_url!")
1135 l = find_end_of(document.body, k, "\\begin_layout", "\\end_layout")
1136 if l == -1 or l >= j:
1137 document.warning("Can't find end of default layout in revert_url!")
1140 # OK, so the inset's data is between lines k and l.
1141 data = " ".join(document.body[k+1:l])
1143 newinset = ["\\begin_inset LatexCommand url", "target \"" + data + "\"",\
1145 document.body[i:j+1] = newinset
1146 i = i + len(newinset)
1149 def convert_include(document):
1150 'Converts include insets to new format.'
1152 r = re.compile(r'\\begin_inset Include\s+\\([^{]+){([^}]*)}(?:\[(.*)\])?')
1154 i = find_token(document.body, "\\begin_inset Include", i)
1157 line = document.body[i]
1158 previewline = document.body[i + 1]
1161 document.warning("Unable to match line " + str(i) + " of body!")
1167 insertion = ["\\begin_inset CommandInset include",
1168 "LatexCommand " + cmd, previewline,
1169 "filename \"" + fn + "\""]
1172 insertion.append("lstparams " + '"' + opt + '"')
1174 document.body[i : i + 2] = insertion
1178 def revert_include(document):
1179 'Reverts include insets to old format.'
1181 r0 = re.compile('preview.*')
1182 r1 = re.compile('LatexCommand (.+)')
1183 r2 = re.compile('filename (.+)')
1184 r3 = re.compile('options (.*)')
1186 i = find_token(document.body, "\\begin_inset CommandInset include", i)
1190 if r0.match(document.body[nextline]):
1191 previewline = document.body[nextline]
1195 m = r1.match(document.body[nextline])
1197 document.warning("Malformed LyX document: No LatexCommand line for `" +
1198 document.body[i] + "' on line " + str(i) + ".")
1203 m = r2.match(document.body[nextline])
1205 document.warning("Malformed LyX document: No filename line for `" + \
1206 document.body[i] + "' on line " + str(i) + ".")
1212 if (cmd == "lstinputlisting"):
1213 m = r3.match(document.body[nextline])
1215 options = m.group(1)
1218 newline = "\\begin_inset Include \\" + cmd + "{" + fn + "}"
1220 newline += ("[" + options + "]")
1221 insertion = [newline]
1222 if previewline != "":
1223 insertion.append(previewline)
1224 document.body[i : nextline] = insertion
1228 def revert_albanian(document):
1229 "Set language Albanian to English"
1231 if document.language == "albanian":
1232 document.language = "english"
1233 i = find_token(document.header, "\\language", 0)
1235 document.header[i] = "\\language english"
1238 j = find_token(document.body, "\\lang albanian", j)
1241 document.body[j] = document.body[j].replace("\\lang albanian", "\\lang english")
1245 def revert_lowersorbian(document):
1246 "Set language lower Sorbian to English"
1248 if document.language == "lowersorbian":
1249 document.language = "english"
1250 i = find_token(document.header, "\\language", 0)
1252 document.header[i] = "\\language english"
1255 j = find_token(document.body, "\\lang lowersorbian", j)
1258 document.body[j] = document.body[j].replace("\\lang lowersorbian", "\\lang english")
1262 def revert_uppersorbian(document):
1263 "Set language uppersorbian to usorbian as this was used in LyX 1.5"
1265 if document.language == "uppersorbian":
1266 document.language = "usorbian"
1267 i = find_token(document.header, "\\language", 0)
1269 document.header[i] = "\\language usorbian"
1272 j = find_token(document.body, "\\lang uppersorbian", j)
1275 document.body[j] = document.body[j].replace("\\lang uppersorbian", "\\lang usorbian")
1279 def convert_usorbian(document):
1280 "Set language usorbian to uppersorbian"
1282 if document.language == "usorbian":
1283 document.language = "uppersorbian"
1284 i = find_token(document.header, "\\language", 0)
1286 document.header[i] = "\\language uppersorbian"
1289 j = find_token(document.body, "\\lang usorbian", j)
1292 document.body[j] = document.body[j].replace("\\lang usorbian", "\\lang uppersorbian")
1296 def revert_macro_optional_params(document):
1297 "Convert macro definitions with optional parameters into ERTs"
1298 # Stub to convert macro definitions with one or more optional parameters
1299 # into uninterpreted ERT insets
1302 def revert_hyperlinktype(document):
1303 'Reverts hyperlink type'
1307 i = find_token(document.body, "target", i)
1310 j = find_token(document.body, "type", i)
1314 del document.body[j]
1318 def revert_pagebreak(document):
1319 'Reverts pagebreak to ERT'
1322 i = find_token(document.body, "\\pagebreak", i)
1325 document.body[i] = '\\begin_inset ERT\nstatus collapsed\n\n' \
1326 '\\begin_layout Standard\n\n\n\\backslash\n' \
1327 'pagebreak{}\n\\end_layout\n\n\\end_inset\n\n'
1331 def revert_linebreak(document):
1332 'Reverts linebreak to ERT'
1335 i = find_token(document.body, "\\linebreak", i)
1338 document.body[i] = '\\begin_inset ERT\nstatus collapsed\n\n' \
1339 '\\begin_layout Standard\n\n\n\\backslash\n' \
1340 'linebreak{}\n\\end_layout\n\n\\end_inset\n\n'
1344 def revert_latin(document):
1345 "Set language Latin to English"
1347 if document.language == "latin":
1348 document.language = "english"
1349 i = find_token(document.header, "\\language", 0)
1351 document.header[i] = "\\language english"
1354 j = find_token(document.body, "\\lang latin", j)
1357 document.body[j] = document.body[j].replace("\\lang latin", "\\lang english")
1361 def revert_samin(document):
1362 "Set language North Sami to English"
1364 if document.language == "samin":
1365 document.language = "english"
1366 i = find_token(document.header, "\\language", 0)
1368 document.header[i] = "\\language english"
1371 j = find_token(document.body, "\\lang samin", j)
1374 document.body[j] = document.body[j].replace("\\lang samin", "\\lang english")
1378 def convert_serbocroatian(document):
1379 "Set language Serbocroatian to Croatian as this was really Croatian in LyX 1.5"
1381 if document.language == "serbocroatian":
1382 document.language = "croatian"
1383 i = find_token(document.header, "\\language", 0)
1385 document.header[i] = "\\language croatian"
1388 j = find_token(document.body, "\\lang serbocroatian", j)
1391 document.body[j] = document.body[j].replace("\\lang serbocroatian", "\\lang croatian")
1395 def convert_framed_notes(document):
1396 "Convert framed notes to boxes. "
1399 i = find_tokens(document.body, ["\\begin_inset Note Framed", "\\begin_inset Note Shaded"], i)
1402 subst = [document.body[i].replace("\\begin_inset Note", "\\begin_inset Box"),
1411 'height_special "totalheight"']
1412 document.body[i:i+1] = subst
1416 def convert_module_names(document):
1417 modulemap = { 'Braille' : 'braille', 'Endnote' : 'endnotes', 'Foot to End' : 'foottoend',\
1418 'Hanging' : 'hanging', 'Linguistics' : 'linguistics', 'Logical Markup' : 'logicalmkup', \
1419 'Theorems (AMS-Extended)' : 'theorems-ams-extended', 'Theorems (AMS)' : 'theorems-ams', \
1420 'Theorems (Order By Chapter)' : 'theorems-chap', 'Theorems (Order By Section)' : 'theorems-sec', \
1421 'Theorems (Starred)' : 'theorems-starred', 'Theorems' : 'theorems-std' }
1422 modlist = document.get_module_list()
1423 if len(modlist) == 0:
1427 if modulemap.has_key(mod):
1428 newmodlist.append(modulemap[mod])
1430 document.warning("Can't find module %s in the module map!" % mod)
1431 newmodlist.append(mod)
1432 document.set_module_list(newmodlist)
1435 def revert_module_names(document):
1436 modulemap = { 'braille' : 'Braille', 'endnotes' : 'Endnote', 'foottoend' : 'Foot to End',\
1437 'hanging' : 'Hanging', 'linguistics' : 'Linguistics', 'logicalmkup' : 'Logical Markup', \
1438 'theorems-ams-extended' : 'Theorems (AMS-Extended)', 'theorems-ams' : 'Theorems (AMS)', \
1439 'theorems-chap' : 'Theorems (Order By Chapter)', 'theorems-sec' : 'Theorems (Order By Section)', \
1440 'theorems-starred' : 'Theorems (Starred)', 'theorems-std' : 'Theorems'}
1441 modlist = document.get_module_list()
1442 if len(modlist) == 0:
1446 if modulemap.has_key(mod):
1447 newmodlist.append(modulemap[mod])
1449 document.warning("Can't find module %s in the module map!" % mod)
1450 newmodlist.append(mod)
1451 document.set_module_list(newmodlist)
1454 def revert_colsep(document):
1455 i = find_token(document.header, "\\columnsep", 0)
1458 colsepline = document.header[i]
1459 r = re.compile(r'\\columnsep (.*)')
1460 m = r.match(colsepline)
1462 document.warning("Malformed column separation line!")
1465 del document.header[i]
1466 #it seems to be safe to add the package even if it is already used
1467 pretext = ["\\usepackage{geometry}", "\\geometry{columnsep=" + colsep + "}"]
1469 add_to_preamble(document, pretext)
1472 def revert_framed_notes(document):
1473 "Revert framed boxes to notes. "
1476 i = find_tokens(document.body, ["\\begin_inset Box Framed", "\\begin_inset Box Shaded"], i)
1480 j = find_end_of_inset(document.body, i + 1)
1483 document.warning("Malformed LyX document: Could not find end of Box inset.")
1484 k = find_token(document.body, "status", i + 1, j)
1486 document.warning("Malformed LyX document: Missing `status' tag in Box inset.")
1488 status = document.body[k]
1489 l = find_default_layout(document, i + 1, j)
1491 document.warning("Malformed LyX document: Missing `\\begin_layout' in Box inset.")
1493 m = find_token(document.body, "\\end_layout", i + 1, j)
1495 document.warning("Malformed LyX document: Missing `\\end_layout' in Box inset.")
1497 ibox = find_token(document.body, "has_inner_box 1", i + 1, k)
1498 pbox = find_token(document.body, "use_parbox 1", i + 1, k)
1499 if ibox == -1 and pbox == -1:
1500 document.body[i] = document.body[i].replace("\\begin_inset Box", "\\begin_inset Note")
1501 del document.body[i+1:k]
1503 document.body[i] = document.body[i].replace("\\begin_inset Box Shaded", "\\begin_inset Box Frameless")
1504 subst1 = [document.body[l],
1505 "\\begin_inset Note Shaded",
1507 '\\begin_layout Standard']
1508 document.body[l:l + 1] = subst1
1509 subst2 = [document.body[m], "\\end_layout", "\\end_inset"]
1510 document.body[m:m + 1] = subst2
1514 def revert_slash(document):
1515 'Revert \\SpecialChar \\slash{} to ERT'
1516 r = re.compile(r'\\SpecialChar \\slash{}')
1518 while i < len(document.body):
1519 m = r.match(document.body[i])
1521 subst = ['\\begin_inset ERT',
1522 'status collapsed', '',
1523 '\\begin_layout Standard',
1524 '', '', '\\backslash',
1528 document.body[i: i+1] = subst
1534 def revert_nobreakdash(document):
1535 'Revert \\SpecialChar \\nobreakdash- to ERT'
1537 while i < len(document.body):
1538 line = document.body[i]
1539 r = re.compile(r'\\SpecialChar \\nobreakdash-')
1542 subst = ['\\begin_inset ERT',
1543 'status collapsed', '',
1544 '\\begin_layout Standard', '', '',
1549 document.body[i:i+1] = subst
1551 j = find_token(document.header, "\\use_amsmath", 0)
1553 document.warning("Malformed LyX document: Missing '\\use_amsmath'.")
1555 document.header[j] = "\\use_amsmath 2"
1560 #Returns number of lines added/removed
1561 def revert_nocite_key(body, start, end):
1562 'key "..." -> \nocite{...}'
1563 r = re.compile(r'^key "(.*)"')
1567 m = r.match(body[i])
1569 body[i:i+1] = ["\\backslash", "nocite{" + m.group(1) + "}"]
1570 j += 1 # because we added a line
1571 i += 2 # skip that line
1574 j -= 1 # because we deleted a line
1575 # no need to change i, since it now points to the next line
1579 def revert_nocite(document):
1580 "Revert LatexCommand nocite to ERT"
1583 i = find_token(document.body, "\\begin_inset CommandInset citation", i)
1586 if (document.body[i+1] != "LatexCommand nocite"):
1587 # note that we already incremented i
1590 insetEnd = find_end_of_inset(document.body, i)
1592 #this should not happen
1593 document.warning("End of CommandInset citation not found in revert_nocite!")
1596 paramLocation = i + 2 #start of the inset's parameters
1598 document.body[i:i+2] = \
1599 ["\\begin_inset ERT", "status collapsed", "", "\\begin_layout Standard"]
1600 # that added two lines
1603 #print insetEnd, document.body[i: insetEnd + 1]
1604 insetEnd += revert_nocite_key(document.body, paramLocation, insetEnd)
1605 #print insetEnd, document.body[i: insetEnd + 1]
1606 document.body.insert(insetEnd, "\\end_layout")
1607 document.body.insert(insetEnd + 1, "")
1611 def revert_btprintall(document):
1612 "Revert (non-bibtopic) btPrintAll option to ERT \nocite{*}"
1613 i = find_token(document.header, '\\use_bibtopic', 0)
1615 document.warning("Malformed lyx document: Missing '\\use_bibtopic'.")
1617 if get_value(document.header, '\\use_bibtopic', 0) == "false":
1619 while i < len(document.body):
1620 i = find_token(document.body, "\\begin_inset CommandInset bibtex", i)
1623 j = find_end_of_inset(document.body, i + 1)
1625 #this should not happen
1626 document.warning("End of CommandInset bibtex not found in revert_btprintall!")
1627 j = len(document.body)
1628 # this range isn't really right, but it should be OK, since we shouldn't
1629 # see more than one matching line in each inset
1631 for k in range(i, j):
1632 if (document.body[k] == 'btprint "btPrintAll"'):
1633 del document.body[k]
1634 subst = ["\\begin_inset ERT",
1635 "status collapsed", "",
1636 "\\begin_layout Standard", "",
1641 document.body[i:i] = subst
1642 addlines = addedlines + len(subst) - 1
1646 def revert_bahasam(document):
1647 "Set language Bahasa Malaysia to Bahasa Indonesia"
1649 if document.language == "bahasam":
1650 document.language = "bahasa"
1651 i = find_token(document.header, "\\language", 0)
1653 document.header[i] = "\\language bahasa"
1656 j = find_token(document.body, "\\lang bahasam", j)
1659 document.body[j] = document.body[j].replace("\\lang bahasam", "\\lang bahasa")
1663 def revert_interlingua(document):
1664 "Set language Interlingua to English"
1666 if document.language == "interlingua":
1667 document.language = "english"
1668 i = find_token(document.header, "\\language", 0)
1670 document.header[i] = "\\language english"
1673 j = find_token(document.body, "\\lang interlingua", j)
1676 document.body[j] = document.body[j].replace("\\lang interlingua", "\\lang english")
1680 def revert_serbianlatin(document):
1681 "Set language Serbian-Latin to Croatian"
1683 if document.language == "serbian-latin":
1684 document.language = "croatian"
1685 i = find_token(document.header, "\\language", 0)
1687 document.header[i] = "\\language croatian"
1690 j = find_token(document.body, "\\lang serbian-latin", j)
1693 document.body[j] = document.body[j].replace("\\lang serbian-latin", "\\lang croatian")
1697 def revert_rotfloat(document):
1698 " Revert sideways custom floats. "
1701 # whitespace intended (exclude \\begin_inset FloatList)
1702 i = find_token(document.body, "\\begin_inset Float ", i)
1705 line = document.body[i]
1706 r = re.compile(r'\\begin_inset Float (.*)$')
1709 document.warning("Unable to match line " + str(i) + " of body!")
1712 floattype = m.group(1)
1713 if floattype == "figure" or floattype == "table":
1716 j = find_end_of_inset(document.body, i)
1718 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_rotfloat.")
1722 if get_value(document.body, 'sideways', i, j) == "false":
1725 l = find_default_layout(document, i + 1, j)
1727 document.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
1729 subst = ['\\begin_layout Standard',
1730 '\\begin_inset ERT',
1731 'status collapsed', '',
1732 '\\begin_layout Standard', '', '',
1734 'end{sideways' + floattype + '}',
1735 '\\end_layout', '', '\\end_inset']
1736 document.body[j : j+1] = subst
1737 addedLines = len(subst) - 1
1738 del document.body[i+1 : l]
1739 addedLines -= (l-1) - (i+1)
1740 subst = ['\\begin_inset ERT', 'status collapsed', '',
1741 '\\begin_layout Standard', '', '', '\\backslash',
1742 'begin{sideways' + floattype + '}',
1743 '\\end_layout', '', '\\end_inset', '',
1745 document.body[i : i+1] = subst
1746 addedLines += len(subst) - 1
1747 if floattype == "algorithm":
1748 add_to_preamble(document,
1749 ['% Commands inserted by lyx2lyx for sideways algorithm float',
1750 '\\usepackage{rotfloat}',
1751 '\\floatstyle{ruled}',
1752 '\\newfloat{algorithm}{tbp}{loa}',
1753 '\\floatname{algorithm}{Algorithm}'])
1755 document.warning("Cannot create preamble definition for custom float" + floattype + ".")
1759 def revert_widesideways(document):
1760 " Revert wide sideways floats. "
1763 # whitespace intended (exclude \\begin_inset FloatList)
1764 i = find_token(document.body, '\\begin_inset Float ', i)
1767 line = document.body[i]
1768 r = re.compile(r'\\begin_inset Float (.*)$')
1771 document.warning("Unable to match line " + str(i) + " of body!")
1774 floattype = m.group(1)
1775 if floattype != "figure" and floattype != "table":
1778 j = find_end_of_inset(document.body, i)
1780 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_widesideways.")
1783 if get_value(document.body, 'sideways', i, j) == "false" or \
1784 get_value(document.body, 'wide', i, j) == "false":
1787 l = find_default_layout(document, i + 1, j)
1789 document.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
1791 subst = ['\\begin_layout Standard', '\\begin_inset ERT',
1792 'status collapsed', '',
1793 '\\begin_layout Standard', '', '', '\\backslash',
1794 'end{sideways' + floattype + '*}',
1795 '\\end_layout', '', '\\end_inset']
1796 document.body[j : j+1] = subst
1797 addedLines = len(subst) - 1
1798 del document.body[i+1:l-1]
1799 addedLines -= (l-1) - (i+1)
1800 subst = ['\\begin_inset ERT', 'status collapsed', '',
1801 '\\begin_layout Standard', '', '', '\\backslash',
1802 'begin{sideways' + floattype + '*}', '\\end_layout', '',
1803 '\\end_inset', '', '\\end_layout', '']
1804 document.body[i : i+1] = subst
1805 addedLines += len(subst) - 1
1806 add_to_preamble(document, ['\\usepackage{rotfloat}\n'])
1810 def revert_inset_embedding(document, type):
1811 ' Remove embed tag from certain type of insets'
1814 i = find_token(document.body, "\\begin_inset %s" % type, i)
1817 j = find_end_of_inset(document.body, i)
1819 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_inset_embedding.")
1822 k = find_token(document.body, "\tembed", i, j)
1824 k = find_token(document.body, "embed", i, j)
1826 del document.body[k]
1830 def revert_external_embedding(document):
1831 ' Remove embed tag from external inset '
1832 revert_inset_embedding(document, 'External')
1835 # FIXME This code can still be cleaned up a fair bit.
1836 def convert_subfig(document):
1837 " Convert subfigures to subfloats. "
1840 i = find_token(document.body, '\\begin_inset Graphics', i)
1843 endInset = find_end_of_inset(document.body, i)
1845 document.warning("Malformed lyx document: Missing '\\end_inset' in convert_subfig.")
1848 k = find_token(document.body, '\tsubcaption', i, endInset)
1852 l = find_token(document.body, '\tsubcaptionText', i, endInset)
1853 caption = document.body[l][16:].strip('"')
1854 savestr = document.body[i]
1855 laststr = document.body[endInset]
1856 del document.body[l]
1857 del document.body[k]
1859 # savestr should no longer be needed here.
1860 subst = ['\\begin_inset Float figure', 'wide false', 'sideways false',
1861 'status open', '', '\\begin_layout Plain Layout', '\\begin_inset Caption',
1862 '', '\\begin_layout Plain Layout',
1863 caption, '\\end_layout', '', '\\end_inset', '',
1864 '\\end_layout', '', '\\begin_layout Plain Layout', savestr]
1865 document.body[i : i+1] = subst
1866 addedLines += len(subst) - 1
1867 endInset += addedLines
1868 # There should be an easier way to do this.
1869 subst = ['', '\\end_inset', '', '\\end_layout', laststr]
1870 document.body[endInset : endInset+1] = subst
1871 addedLines += len(subst) - 1
1875 def revert_subfig(document):
1876 " Revert subfloats. "
1879 # whitespace intended (exclude \\begin_inset FloatList)
1880 i = find_tokens(document.body, ['\\begin_inset Float ', '\\begin_inset Wrap'], i)
1886 j = find_end_of_inset(document.body, i)
1888 document.warning("Malformed lyx document: Missing '\\end_inset' (float) at line " + str(i + len(document.header)) + ".\n\t" + document.body[i])
1889 # document.warning(document.body[i-1] + "\n" + document.body[i+1])
1891 continue # this will get us back to the outer loop, since j == -1
1892 # look for embedded float (= subfloat)
1893 # whitespace intended (exclude \\begin_inset FloatList)
1894 k = find_token(document.body, '\\begin_inset Float ', i + 1, j)
1897 l = find_end_of_inset(document.body, k)
1899 document.warning("Malformed lyx document: Missing '\\end_inset' (embedded float).")
1902 continue # escape to the outer loop
1903 m = find_default_layout(document, k + 1, l)
1905 cap = find_token(document.body, '\\begin_inset Caption', k + 1, l)
1910 capend = find_end_of_inset(document.body, cap)
1912 document.warning("Malformed lyx document: Missing '\\end_inset' (caption).")
1916 lbl = find_token(document.body, '\\begin_inset CommandInset label', cap, capend)
1918 lblend = find_end_of_inset(document.body, lbl + 1)
1920 document.warning("Malformed lyx document: Missing '\\end_inset' (label).")
1922 for line in document.body[lbl:lblend + 1]:
1923 if line.startswith('name '):
1924 label = line.split()[1].strip('"')
1931 opt = find_token(document.body, '\\begin_inset OptArg', cap, capend)
1933 optend = find_end_of_inset(document.body, opt)
1935 document.warning("Malformed lyx document: Missing '\\end_inset' (OptArg).")
1937 optc = find_default_layout(document, opt, optend)
1939 document.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
1941 optcend = find_end_of(document.body, optc, "\\begin_layout", "\\end_layout")
1942 for line in document.body[optc:optcend]:
1943 if not line.startswith('\\'):
1944 shortcap += line.strip()
1948 for line in document.body[cap:capend]:
1949 if line in document.body[lbl:lblend]:
1951 elif line in document.body[opt:optend]:
1953 elif not line.startswith('\\'):
1954 caption += line.strip()
1956 caption += "\\backslash\nlabel{" + label + "}"
1957 subst = '\\begin_layout Plain Layout\n\\begin_inset ERT\nstatus collapsed\n\n' \
1958 '\\begin_layout Plain Layout\n\n}\n\\end_layout\n\n\\end_inset\n\n' \
1959 '\\end_layout\n\n\\begin_layout Plain Layout\n'
1960 subst = subst.split('\n')
1961 document.body[l : l+1] = subst
1962 addedLines = len(subst) - 1
1963 # this is before l and so is unchanged by the multiline insertion
1965 del document.body[cap:capend+1]
1966 addedLines -= (capend + 1 - cap)
1967 del document.body[k+1:m-1]
1968 addedLines -= (m - 1 - (k + 1))
1969 insertion = '\\begin_inset ERT\nstatus collapsed\n\n' \
1970 '\\begin_layout Plain Layout\n\n\\backslash\n' \
1972 if len(shortcap) > 0:
1973 insertion = insertion + "[" + shortcap + "]"
1974 if len(caption) > 0:
1975 insertion = insertion + "[" + caption + "]"
1976 insertion = insertion + '{%\n\\end_layout\n\n\\end_inset\n\n\\end_layout\n'
1977 insertion = insertion.split('\n')
1978 document.body[k : k + 1] = insertion
1979 addedLines += len(insertion) - 1
1980 add_to_preamble(document,
1981 ['\\usepackage{subfig}\n'])
1985 def revert_wrapplacement(document):
1986 " Revert placement options wrap floats (wrapfig). "
1989 i = find_token(document.body, "lines", i)
1992 j = find_token(document.body, "placement", i+1)
1994 document.warning("Malformed LyX document: Couldn't find placement parameter of wrap float.")
1996 document.body[j] = document.body[j].replace("placement O", "placement o")
1997 document.body[j] = document.body[j].replace("placement I", "placement i")
1998 document.body[j] = document.body[j].replace("placement L", "placement l")
1999 document.body[j] = document.body[j].replace("placement R", "placement r")
2003 def remove_extra_embedded_files(document):
2004 " Remove \extra_embedded_files from buffer params "
2005 i = find_token(document.header, '\\extra_embedded_files', 0)
2008 document.header.pop(i)
2011 def convert_spaceinset(document):
2012 " Convert '\\InsetSpace foo' to '\\begin_inset Space foo\n\\end_inset' "
2014 while i < len(document.body):
2015 m = re.match(r'(.*)\\InsetSpace (.*)', document.body[i])
2019 subst = [before, "\\begin_inset Space " + after, "\\end_inset"]
2020 document.body[i: i+1] = subst
2026 def revert_spaceinset(document):
2027 " Revert '\\begin_inset Space foo\n\\end_inset' to '\\InsetSpace foo' "
2030 i = find_token(document.body, "\\begin_inset Space", i)
2033 j = find_end_of_inset(document.body, i)
2035 document.warning("Malformed LyX document: Could not find end of space inset.")
2037 document.body[i] = document.body[i].replace('\\begin_inset Space', '\\InsetSpace')
2038 del document.body[j]
2041 def convert_hfill(document):
2042 " Convert hfill to space inset "
2045 i = find_token(document.body, "\\hfill", i)
2048 subst = document.body[i].replace('\\hfill', \
2049 '\n\\begin_inset Space \\hfill{}\n\\end_inset')
2050 subst = subst.split('\n')
2051 document.body[i : i+1] = subst
2055 def revert_hfills(document):
2056 ' Revert \\hfill commands '
2057 hfill = re.compile(r'\\hfill')
2058 dotfill = re.compile(r'\\dotfill')
2059 hrulefill = re.compile(r'\\hrulefill')
2062 i = find_token(document.body, "\\InsetSpace", i)
2065 if hfill.search(document.body[i]):
2066 document.body[i] = \
2067 document.body[i].replace('\\InsetSpace \\hfill{}', '\\hfill')
2070 if dotfill.search(document.body[i]):
2071 subst = document.body[i].replace('\\InsetSpace \\dotfill{}', \
2072 '\\begin_inset ERT\nstatus collapsed\n\n' \
2073 '\\begin_layout Standard\n\n\n\\backslash\n' \
2074 'dotfill{}\n\\end_layout\n\n\\end_inset\n\n')
2075 subst = subst.split('\n')
2076 document.body[i : i+1] = subst
2079 if hrulefill.search(document.body[i]):
2080 subst = document.body[i].replace('\\InsetSpace \\hrulefill{}', \
2081 '\\begin_inset ERT\nstatus collapsed\n\n' \
2082 '\\begin_layout Standard\n\n\n\\backslash\n' \
2083 'hrulefill{}\n\\end_layout\n\n\\end_inset\n\n')
2084 subst = subst.split('\n')
2085 document.body[i : i+1] = subst
2090 def revert_hspace(document):
2091 ' Revert \\InsetSpace \\hspace{} to ERT '
2093 hspace = re.compile(r'\\hspace{}')
2094 hstar = re.compile(r'\\hspace\*{}')
2096 i = find_token(document.body, "\\InsetSpace \\hspace", i)
2099 length = get_value(document.body, '\\length', i+1)
2101 document.warning("Malformed lyx document: Missing '\\length' in Space inset.")
2103 del document.body[i+1]
2105 if hstar.search(document.body[i]):
2106 subst = document.body[i].replace('\\InsetSpace \\hspace*{}', \
2107 '\\begin_inset ERT\nstatus collapsed\n\n' \
2108 '\\begin_layout Standard\n\n\n\\backslash\n' \
2109 'hspace*{' + length + '}\n\\end_layout\n\n\\end_inset\n\n')
2110 subst = subst.split('\n')
2111 document.body[i : i+1] = subst
2112 addedLines += len(subst) - 1
2115 if hspace.search(document.body[i]):
2116 subst = document.body[i].replace('\\InsetSpace \\hspace{}', \
2117 '\\begin_inset ERT\nstatus collapsed\n\n' \
2118 '\\begin_layout Standard\n\n\n\\backslash\n' \
2119 'hspace{' + length + '}\n\\end_layout\n\n\\end_inset\n\n')
2120 subst = subst.split('\n')
2121 document.body[i : i+1] = subst
2122 addedLines += len(subst) - 1
2128 def revert_protected_hfill(document):
2129 ' Revert \\begin_inset Space \\hspace*{\\fill} to ERT '
2132 i = find_token(document.body, '\\begin_inset Space \\hspace*{\\fill}', i)
2135 j = find_end_of_inset(document.body, i)
2137 document.warning("Malformed LyX document: Could not find end of space inset.")
2139 del document.body[j]
2140 subst = document.body[i].replace('\\begin_inset Space \\hspace*{\\fill}', \
2141 '\\begin_inset ERT\nstatus collapsed\n\n' \
2142 '\\begin_layout Standard\n\n\n\\backslash\n' \
2143 'hspace*{\n\\backslash\nfill}\n\\end_layout\n\n\\end_inset\n\n')
2144 subst = subst.split('\n')
2145 document.body[i : i+1] = subst
2149 def revert_leftarrowfill(document):
2150 ' Revert \\begin_inset Space \\leftarrowfill{} to ERT '
2153 i = find_token(document.body, '\\begin_inset Space \\leftarrowfill{}', i)
2156 j = find_end_of_inset(document.body, i)
2158 document.warning("Malformed LyX document: Could not find end of space inset.")
2160 del document.body[j]
2161 subst = document.body[i].replace('\\begin_inset Space \\leftarrowfill{}', \
2162 '\\begin_inset ERT\nstatus collapsed\n\n' \
2163 '\\begin_layout Standard\n\n\n\\backslash\n' \
2164 'leftarrowfill{}\n\\end_layout\n\n\\end_inset\n\n')
2165 subst = subst.split('\n')
2166 document.body[i : i+1] = subst
2170 def revert_rightarrowfill(document):
2171 ' Revert \\begin_inset Space \\rightarrowfill{} to ERT '
2174 i = find_token(document.body, '\\begin_inset Space \\rightarrowfill{}', i)
2177 j = find_end_of_inset(document.body, i)
2179 document.warning("Malformed LyX document: Could not find end of space inset.")
2181 del document.body[j]
2182 subst = document.body[i].replace('\\begin_inset Space \\rightarrowfill{}', \
2183 '\\begin_inset ERT\nstatus collapsed\n\n' \
2184 '\\begin_layout Standard\n\n\n\\backslash\n' \
2185 'rightarrowfill{}\n\\end_layout\n\n\\end_inset\n\n')
2186 subst = subst.split('\n')
2187 document.body[i : i+1] = subst
2191 def revert_upbracefill(document):
2192 ' Revert \\begin_inset Space \\upbracefill{} to ERT '
2195 i = find_token(document.body, '\\begin_inset Space \\upbracefill{}', i)
2198 j = find_end_of_inset(document.body, i)
2200 document.warning("Malformed LyX document: Could not find end of space inset.")
2202 del document.body[j]
2203 subst = document.body[i].replace('\\begin_inset Space \\upbracefill{}', \
2204 '\\begin_inset ERT\nstatus collapsed\n\n' \
2205 '\\begin_layout Standard\n\n\n\\backslash\n' \
2206 'upbracefill{}\n\\end_layout\n\n\\end_inset\n\n')
2207 subst = subst.split('\n')
2208 document.body[i : i+1] = subst
2212 def revert_downbracefill(document):
2213 ' Revert \\begin_inset Space \\downbracefill{} to ERT '
2216 i = find_token(document.body, '\\begin_inset Space \\downbracefill{}', i)
2219 j = find_end_of_inset(document.body, i)
2221 document.warning("Malformed LyX document: Could not find end of space inset.")
2223 del document.body[j]
2224 subst = document.body[i].replace('\\begin_inset Space \\downbracefill{}', \
2225 '\\begin_inset ERT\nstatus collapsed\n\n' \
2226 '\\begin_layout Standard\n\n\n\\backslash\n' \
2227 'downbracefill{}\n\\end_layout\n\n\\end_inset\n\n')
2228 subst = subst.split('\n')
2229 document.body[i : i+1] = subst
2233 def revert_local_layout(document):
2234 ' Revert local layout headers.'
2237 i = find_token(document.header, "\\begin_local_layout", i)
2240 j = find_end_of(document.header, i, "\\begin_local_layout", "\\end_local_layout")
2242 # this should not happen
2244 document.header[i : j + 1] = []
2247 def convert_pagebreaks(document):
2248 ' Convert inline Newpage insets to new format '
2251 i = find_token(document.body, '\\newpage', i)
2254 document.body[i:i+1] = ['\\begin_inset Newpage newpage',
2258 i = find_token(document.body, '\\pagebreak', i)
2261 document.body[i:i+1] = ['\\begin_inset Newpage pagebreak',
2265 i = find_token(document.body, '\\clearpage', i)
2268 document.body[i:i+1] = ['\\begin_inset Newpage clearpage',
2272 i = find_token(document.body, '\\cleardoublepage', i)
2275 document.body[i:i+1] = ['\\begin_inset Newpage cleardoublepage',
2279 def revert_pagebreaks(document):
2280 ' Revert \\begin_inset Newpage to previous inline format '
2283 i = find_token(document.body, '\\begin_inset Newpage', i)
2286 j = find_end_of_inset(document.body, i)
2288 document.warning("Malformed LyX document: Could not find end of Newpage inset.")
2290 del document.body[j]
2291 document.body[i] = document.body[i].replace('\\begin_inset Newpage newpage', '\\newpage')
2292 document.body[i] = document.body[i].replace('\\begin_inset Newpage pagebreak', '\\pagebreak')
2293 document.body[i] = document.body[i].replace('\\begin_inset Newpage clearpage', '\\clearpage')
2294 document.body[i] = document.body[i].replace('\\begin_inset Newpage cleardoublepage', '\\cleardoublepage')
2297 def convert_linebreaks(document):
2298 ' Convert inline Newline insets to new format '
2301 i = find_token(document.body, '\\newline', i)
2304 document.body[i:i+1] = ['\\begin_inset Newline newline',
2308 i = find_token(document.body, '\\linebreak', i)
2311 document.body[i:i+1] = ['\\begin_inset Newline linebreak',
2315 def revert_linebreaks(document):
2316 ' Revert \\begin_inset Newline to previous inline format '
2319 i = find_token(document.body, '\\begin_inset Newline', i)
2322 j = find_end_of_inset(document.body, i)
2324 document.warning("Malformed LyX document: Could not find end of Newline inset.")
2326 del document.body[j]
2327 document.body[i] = document.body[i].replace('\\begin_inset Newline newline', '\\newline')
2328 document.body[i] = document.body[i].replace('\\begin_inset Newline linebreak', '\\linebreak')
2331 def convert_japanese_plain(document):
2332 ' Set language japanese-plain to japanese '
2334 if document.language == "japanese-plain":
2335 document.language = "japanese"
2336 i = find_token(document.header, "\\language", 0)
2338 document.header[i] = "\\language japanese"
2341 j = find_token(document.body, "\\lang japanese-plain", j)
2344 document.body[j] = document.body[j].replace("\\lang japanese-plain", "\\lang japanese")
2348 def revert_pdfpages(document):
2349 ' Revert pdfpages external inset to ERT '
2352 i = find_token(document.body, "\\begin_inset External", i)
2355 j = find_end_of_inset(document.body, i)
2357 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_pdfpages.")
2360 if get_value(document.body, 'template', i, j) == "PDFPages":
2361 filename = get_value(document.body, 'filename', i, j)
2363 r = re.compile(r'\textra PDFLaTeX \"(.*)\"$')
2364 for k in range(i, j):
2365 m = r.match(document.body[k])
2368 angle = get_value(document.body, 'rotateAngle', i, j)
2369 width = get_value(document.body, 'width', i, j)
2370 height = get_value(document.body, 'height', i, j)
2371 scale = get_value(document.body, 'scale', i, j)
2372 keepAspectRatio = find_token(document.body, "\tkeepAspectRatio", i, j)
2376 options += ",angle=" + angle
2378 options += "angle=" + angle
2381 options += ",width=" + convert_len(width)
2383 options += "width=" + convert_len(width)
2386 options += ",height=" + convert_len(height)
2388 options += "height=" + convert_len(height)
2391 options += ",scale=" + scale
2393 options += "scale=" + scale
2394 if keepAspectRatio != '':
2396 options += ",keepaspectratio"
2398 options += "keepaspectratio"
2400 options = '[' + options + ']'
2401 del document.body[i+1:j+1]
2402 document.body[i:i+1] = ['\\begin_inset ERT',
2405 '\\begin_layout Standard',
2408 'includepdf' + options + '{' + filename + '}',
2412 add_to_preamble(document, ['\\usepackage{pdfpages}\n'])
2418 def revert_mexican(document):
2419 ' Set language Spanish(Mexico) to Spanish '
2421 if document.language == "spanish-mexico":
2422 document.language = "spanish"
2423 i = find_token(document.header, "\\language", 0)
2425 document.header[i] = "\\language spanish"
2428 j = find_token(document.body, "\\lang spanish-mexico", j)
2431 document.body[j] = document.body[j].replace("\\lang spanish-mexico", "\\lang spanish")
2435 def remove_embedding(document):
2436 ' Remove embed tag from all insets '
2437 revert_inset_embedding(document, 'Graphics')
2438 revert_inset_embedding(document, 'External')
2439 revert_inset_embedding(document, 'CommandInset include')
2440 revert_inset_embedding(document, 'CommandInset bibtex')
2443 def revert_master(document):
2444 ' Remove master param '
2445 i = find_token(document.header, "\\master", 0)
2447 del document.header[i]
2450 def revert_graphics_group(document):
2451 ' Revert group information from graphics insets '
2454 i = find_token(document.body, "\\begin_inset Graphics", i)
2457 j = find_end_of_inset(document.body, i)
2459 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_graphics_group.")
2462 k = find_token(document.body, " groupId", i, j)
2466 del document.body[k]
2470 def update_apa_styles(document):
2471 ' Replace obsolete styles '
2473 if document.textclass != "apa":
2476 obsoletedby = { "Acknowledgments": "Acknowledgements",
2477 "Section*": "Section",
2478 "Subsection*": "Subsection",
2479 "Subsubsection*": "Subsubsection",
2480 "Paragraph*": "Paragraph",
2481 "Subparagraph*": "Subparagraph"}
2484 i = find_token(document.body, "\\begin_layout", i)
2488 layout = document.body[i][14:]
2489 if layout in obsoletedby:
2490 document.body[i] = "\\begin_layout " + obsoletedby[layout]
2495 def convert_paper_sizes(document):
2496 ' exchange size options legalpaper and executivepaper to correct order '
2497 # routine is needed to fix http://bugzilla.lyx.org/show_bug.cgi?id=4868
2500 i = find_token(document.header, "\\papersize executivepaper", 0)
2502 document.header[i] = "\\papersize legalpaper"
2504 j = find_token(document.header, "\\papersize legalpaper", 0)
2506 document.header[j] = "\\papersize executivepaper"
2509 def revert_paper_sizes(document):
2510 ' exchange size options legalpaper and executivepaper to correct order '
2513 i = find_token(document.header, "\\papersize executivepaper", 0)
2515 document.header[i] = "\\papersize legalpaper"
2517 j = find_token(document.header, "\\papersize legalpaper", 0)
2519 document.header[j] = "\\papersize executivepaper"
2522 def convert_InsetSpace(document):
2523 " Convert '\\begin_inset Space foo' to '\\begin_inset space foo'"
2526 i = find_token(document.body, "\\begin_inset Space", i)
2529 document.body[i] = document.body[i].replace('\\begin_inset Space', '\\begin_inset space')
2532 def revert_InsetSpace(document):
2533 " Revert '\\begin_inset space foo' to '\\begin_inset Space foo'"
2536 i = find_token(document.body, "\\begin_inset space", i)
2539 document.body[i] = document.body[i].replace('\\begin_inset space', '\\begin_inset Space')
2542 def convert_display_enum(document):
2543 " Convert 'display foo' to 'display false/true'"
2546 i = find_token(document.body, "\tdisplay", i)
2549 val = get_value(document.body, 'display', i)
2551 document.body[i] = document.body[i].replace('none', 'false')
2552 if val == "default":
2553 document.body[i] = document.body[i].replace('default', 'true')
2554 if val == "monochrome":
2555 document.body[i] = document.body[i].replace('monochrome', 'true')
2556 if val == "grayscale":
2557 document.body[i] = document.body[i].replace('grayscale', 'true')
2559 document.body[i] = document.body[i].replace('color', 'true')
2560 if val == "preview":
2561 document.body[i] = document.body[i].replace('preview', 'true')
2565 def revert_display_enum(document):
2566 " Revert 'display false/true' to 'display none/color'"
2569 i = find_token(document.body, "\tdisplay", i)
2572 val = get_value(document.body, 'display', i)
2574 document.body[i] = document.body[i].replace('false', 'none')
2576 document.body[i] = document.body[i].replace('true', 'default')
2580 def remove_fontsCJK(document):
2581 ' Remove font_cjk param '
2582 i = find_token(document.header, "\\font_cjk", 0)
2584 del document.header[i]
2587 def convert_plain_layout(document):
2588 " Convert 'PlainLayout' to 'Plain Layout'"
2591 i = find_token(document.body, '\\begin_layout PlainLayout', i)
2594 document.body[i] = document.body[i].replace('\\begin_layout PlainLayout', \
2595 '\\begin_layout Plain Layout')
2599 def revert_plain_layout(document):
2600 " Convert 'PlainLayout' to 'Plain Layout'"
2603 i = find_token(document.body, '\\begin_layout Plain Layout', i)
2606 document.body[i] = document.body[i].replace('\\begin_layout Plain Layout', \
2607 '\\begin_layout PlainLayout')
2611 def revert_plainlayout(document):
2612 " Convert 'PlainLayout' to 'Plain Layout'"
2615 i = find_token(document.body, '\\begin_layout PlainLayout', i)
2618 # This will be incorrect for some document classes, since Standard is not always
2619 # the default. But (a) it is probably the best we can do and (b) it will actually
2620 # work, in fact, since an unknown layout will be converted to default.
2621 document.body[i] = document.body[i].replace('\\begin_layout PlainLayout', \
2622 '\\begin_layout Standard')
2626 def revert_polytonicgreek(document):
2627 "Set language polytonic Greek to Greek"
2629 if document.language == "polutonikogreek":
2630 document.language = "greek"
2631 i = find_token(document.header, "\\language", 0)
2633 document.header[i] = "\\language greek"
2636 j = find_token(document.body, "\\lang polutonikogreek", j)
2639 document.body[j] = document.body[j].replace("\\lang polutonikogreek", "\\lang greek")
2647 supported_versions = ["1.6.0","1.6"]
2648 convert = [[277, [fix_wrong_tables]],
2649 [278, [close_begin_deeper]],
2650 [279, [long_charstyle_names]],
2651 [280, [axe_show_label]],
2654 [283, [convert_flex]],
2658 [287, [convert_wrapfig_options]],
2659 [288, [convert_inset_command]],
2660 [289, [convert_latexcommand_index]],
2665 [294, [convert_pdf_options]],
2666 [295, [convert_htmlurl, convert_url]],
2667 [296, [convert_include]],
2668 [297, [convert_usorbian]],
2674 [303, [convert_serbocroatian]],
2675 [304, [convert_framed_notes]],
2682 [311, [convert_ams_classes]],
2684 [313, [convert_module_names]],
2687 [316, [convert_subfig]],
2690 [319, [convert_spaceinset, convert_hfill]],
2692 [321, [convert_tablines]],
2693 [322, [convert_plain_layout]],
2694 [323, [convert_pagebreaks]],
2695 [324, [convert_linebreaks]],
2696 [325, [convert_japanese_plain]],
2699 [328, [remove_embedding, remove_extra_embedded_files, remove_inzip_options]],
2702 [331, [convert_ltcaption]],
2704 [333, [update_apa_styles]],
2705 [334, [convert_paper_sizes]],
2706 [335, [convert_InsetSpace]],
2708 [337, [convert_display_enum]],
2712 revert = [[337, [revert_polytonicgreek]],
2713 [336, [revert_display_enum]],
2714 [335, [remove_fontsCJK]],
2715 [334, [revert_InsetSpace]],
2716 [333, [revert_paper_sizes]],
2718 [331, [revert_graphics_group]],
2719 [330, [revert_ltcaption]],
2720 [329, [revert_leftarrowfill, revert_rightarrowfill, revert_upbracefill, revert_downbracefill]],
2721 [328, [revert_master]],
2723 [326, [revert_mexican]],
2724 [325, [revert_pdfpages]],
2726 [323, [revert_linebreaks]],
2727 [322, [revert_pagebreaks]],
2728 [321, [revert_local_layout, revert_plain_layout]],
2729 [320, [revert_tablines]],
2730 [319, [revert_protected_hfill]],
2731 [318, [revert_spaceinset, revert_hfills, revert_hspace]],
2732 [317, [remove_extra_embedded_files]],
2733 [316, [revert_wrapplacement]],
2734 [315, [revert_subfig]],
2735 [314, [revert_colsep, revert_plainlayout]],
2737 [312, [revert_module_names]],
2738 [311, [revert_rotfloat, revert_widesideways]],
2739 [310, [revert_external_embedding]],
2740 [309, [revert_btprintall]],
2741 [308, [revert_nocite]],
2742 [307, [revert_serbianlatin]],
2743 [306, [revert_slash, revert_nobreakdash]],
2744 [305, [revert_interlingua]],
2745 [304, [revert_bahasam]],
2746 [303, [revert_framed_notes]],
2748 [301, [revert_latin, revert_samin]],
2749 [300, [revert_linebreak]],
2750 [299, [revert_pagebreak]],
2751 [298, [revert_hyperlinktype]],
2752 [297, [revert_macro_optional_params]],
2753 [296, [revert_albanian, revert_lowersorbian, revert_uppersorbian]],
2754 [295, [revert_include]],
2755 [294, [revert_href, revert_url]],
2756 [293, [revert_pdf_options_2]],
2757 [292, [revert_inset_info]],
2758 [291, [revert_japanese, revert_japanese_encoding]],
2759 [290, [revert_vietnamese]],
2760 [289, [revert_wraptable]],
2761 [288, [revert_latexcommand_index]],
2762 [287, [revert_inset_command]],
2763 [286, [revert_wrapfig_options]],
2764 [285, [revert_pdf_options]],
2765 [284, [remove_inzip_options]],
2767 [282, [revert_flex]],
2769 [280, [revert_begin_modules]],
2770 [279, [revert_show_label]],
2771 [278, [revert_long_charstyle_names]],
2777 if __name__ == "__main__":