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 # To convert and revert indices, we need to convert between LaTeX
118 # strings and LyXText. Here we do a minimal conversion to prevent
119 # crashes and data loss. Manual patch-up may be needed.
132 '''Takes a string, possibly multi-line, and returns the result of
133 converting LaTeX constructs into LyX constructs. Returns a list of
134 lines, suitable for insertion into document.body.'''
135 # Do the LaTeX --> LyX text conversion
136 r2 = re.compile('^(.*?)(\$.*?\$)(.*)')
139 # Convert LaTeX to Unicode
140 # FIXME This should probably use the list we have elsewhere
141 for rep in replacements:
142 data = data.replace(rep[0], rep[1])
144 data = wrap_into_ert(data, r'\"', '"')
146 lines = data.split('\n')
148 #document.warning("LINE: " + line)
149 #document.warning(str(i) + ":" + document.body[i])
150 #document.warning("LAST: " + document.body[-1])
155 f = m.group(2).replace('\\\\', '\\')
159 s = wrap_into_ert(s, r'\\', '\\backslash')
160 s = wrap_into_ert(s, '{', '{')
161 s = wrap_into_ert(s, '}', '}')
162 subst = s.split('\n')
164 retval.append("\\begin_inset Formula " + f)
165 retval.append("\\end_inset")
166 # Generic, \\ -> \backslash:
167 g = wrap_into_ert(g, r'\\', '\\backslash')
168 g = wrap_into_ert(g, '{', '{')
169 g = wrap_into_ert(g, '}', '}')
170 subst = g.split('\n')
175 ####################################################################
177 def convert_ltcaption(document):
180 i = find_token(document.body, "\\begin_inset Tabular", i)
183 j = find_end_of_inset(document.body, i + 1)
185 document.warning("Malformed LyX document: Could not find end of tabular.")
188 nrows = int(document.body[i+1].split('"')[3])
189 ncols = int(document.body[i+1].split('"')[5])
192 for k in range(nrows):
193 m = find_token(document.body, "<row", m)
196 for k in range(ncols):
197 m = find_token(document.body, "<cell", m)
199 mend = find_token(document.body, "</cell>", m + 1)
200 # first look for caption insets
201 mcap = find_token(document.body, "\\begin_inset Caption", m + 1, mend)
202 # then look for ERT captions
204 mcap = find_token(document.body, "caption", m + 1, mend)
206 mcap = find_token(document.body, "\\backslash", mcap - 1, mcap)
209 if caption == 'true':
211 set_option(document, r, 'caption', 'true')
212 set_option(document, m, 'multicolumn', '1')
213 set_option(document, m, 'bottomline', 'false')
214 set_option(document, m, 'topline', 'false')
215 set_option(document, m, 'rightline', 'false')
216 set_option(document, m, 'leftline', 'false')
217 #j = find_end_of_inset(document.body, j + 1)
219 set_option(document, m, 'multicolumn', '2')
226 #FIXME Use of wrap_into_ert can confuse lyx2lyx
227 def revert_ltcaption(document):
230 i = find_token(document.body, "\\begin_inset Tabular", i)
233 j = find_end_of_inset(document.body, i + 1)
235 document.warning("Malformed LyX document: Could not find end of tabular.")
239 nrows = int(document.body[i+1].split('"')[3])
240 ncols = int(document.body[i+1].split('"')[5])
242 for k in range(nrows):
243 m = find_token(document.body, "<row", m)
244 caption = get_option(document, m, 'caption', 'false')
245 if caption == 'true':
246 remove_option(document, m, 'caption')
247 for k in range(ncols):
248 m = find_token(document.body, "<cell", m)
249 remove_option(document, m, 'multicolumn')
251 m = find_token(document.body, "\\begin_inset Caption", m)
254 m = find_end_of_inset(document.body, m + 1)
255 document.body[m] += wrap_into_ert("","","\\backslash\n\\backslash\n%")
261 def convert_tablines(document):
264 i = find_token(document.body, "\\begin_inset Tabular", i)
266 # LyX 1.3 inserted an extra space between \begin_inset
267 # and Tabular so let us try if this is the case and fix it.
268 i = find_token(document.body, "\\begin_inset Tabular", i)
272 document.body[i] = "\\begin_inset Tabular"
273 j = find_end_of_inset(document.body, i + 1)
275 document.warning("Malformed LyX document: Could not find end of tabular.")
279 nrows = int(document.body[i+1].split('"')[3])
280 ncols = int(document.body[i+1].split('"')[5])
283 for k in range(ncols):
284 m = find_token(document.body, "<column", m)
285 left = get_option(document, m, 'leftline', 'false')
286 right = get_option(document, m, 'rightline', 'false')
287 col_info.append([left, right])
288 remove_option(document, m, 'leftline')
289 remove_option(document, m, 'rightline')
293 for k in range(nrows):
294 m = find_token(document.body, "<row", m)
295 top = get_option(document, m, 'topline', 'false')
296 bottom = get_option(document, m, 'bottomline', 'false')
297 row_info.append([top, bottom])
298 remove_option(document, m, 'topline')
299 remove_option(document, m, 'bottomline')
304 for k in range(nrows*ncols):
305 m = find_token(document.body, "<cell", m)
306 mc_info.append(get_option(document, m, 'multicolumn', '0'))
309 for l in range(nrows):
310 for k in range(ncols):
311 m = find_token(document.body, '<cell', m)
312 if mc_info[l*ncols + k] == '0':
313 r = set_option(document, m, 'topline', row_info[l][0])
314 r = set_option(document, m, 'bottomline', row_info[l][1])
315 r = set_option(document, m, 'leftline', col_info[k][0])
316 r = set_option(document, m, 'rightline', col_info[k][1])
317 elif mc_info[l*ncols + k] == '1':
319 while s < ncols and mc_info[l*ncols + s] == '2':
321 if s < ncols and mc_info[l*ncols + s] != '1':
322 r = set_option(document, m, 'rightline', col_info[k][1])
323 if k > 0 and mc_info[l*ncols + k - 1] == '0':
324 r = set_option(document, m, 'leftline', col_info[k][0])
329 def revert_tablines(document):
332 i = find_token(document.body, "\\begin_inset Tabular", i)
335 j = find_end_of_inset(document.body, i + 1)
337 document.warning("Malformed LyX document: Could not find end of tabular.")
341 nrows = int(document.body[i+1].split('"')[3])
342 ncols = int(document.body[i+1].split('"')[5])
345 for k in range(nrows*ncols):
346 m = find_token(document.body, "<cell", m)
347 top = get_option(document, m, 'topline', 'false')
348 bottom = get_option(document, m, 'bottomline', 'false')
349 left = get_option(document, m, 'leftline', 'false')
350 right = get_option(document, m, 'rightline', 'false')
351 lines.append([top, bottom, left, right])
354 # we will want to ignore longtable captions
357 for k in range(nrows):
358 m = find_token(document.body, "<row", m)
359 caption = get_option(document, m, 'caption', 'false')
360 caption_info.append([caption])
365 for k in range(ncols):
366 m = find_token(document.body, "<column", m)
368 for l in range(nrows):
369 left = lines[l*ncols + k][2]
370 if left == 'false' and caption_info[l] == 'false':
372 set_option(document, m, 'leftline', left)
374 for l in range(nrows):
375 right = lines[l*ncols + k][3]
376 if right == 'false' and caption_info[l] == 'false':
378 set_option(document, m, 'rightline', right)
382 for k in range(nrows):
383 m = find_token(document.body, "<row", m)
385 for l in range(ncols):
386 top = lines[k*ncols + l][0]
389 if caption_info[k] == 'false':
391 set_option(document, m, 'topline', top)
393 for l in range(ncols):
394 bottom = lines[k*ncols + l][1]
395 if bottom == 'false':
397 if caption_info[k] == 'false':
399 set_option(document, m, 'bottomline', bottom)
405 def fix_wrong_tables(document):
408 i = find_token(document.body, "\\begin_inset Tabular", i)
411 j = find_end_of_inset(document.body, i + 1)
413 document.warning("Malformed LyX document: Could not find end of tabular.")
417 nrows = int(document.body[i+1].split('"')[3])
418 ncols = int(document.body[i+1].split('"')[5])
420 for l in range(nrows):
422 for k in range(ncols):
423 m = find_token(document.body, '<cell', m)
425 if document.body[m].find('multicolumn') != -1:
426 multicol_cont = int(document.body[m].split('"')[1])
428 if multicol_cont == 2 and (k == 0 or prev_multicolumn == 0):
429 document.body[m] = document.body[m][:5] + document.body[m][21:]
432 prev_multicolumn = multicol_cont
439 def close_begin_deeper(document):
443 i = find_tokens(document.body, ["\\begin_deeper", "\\end_deeper"], i)
448 if document.body[i][:13] == "\\begin_deeper":
455 document.body[-2:-2] = ['\\end_deeper' for i in range(depth)]
458 def long_charstyle_names(document):
461 i = find_token(document.body, "\\begin_inset CharStyle", i)
464 document.body[i] = document.body[i].replace("CharStyle ", "CharStyle CharStyle:")
467 def revert_long_charstyle_names(document):
470 i = find_token(document.body, "\\begin_inset CharStyle", i)
473 document.body[i] = document.body[i].replace("CharStyle CharStyle:", "CharStyle")
477 def axe_show_label(document):
480 i = find_token(document.body, "\\begin_inset CharStyle", i)
483 if document.body[i + 1].find("show_label") != -1:
484 if document.body[i + 1].find("true") != -1:
485 document.body[i + 1] = "status open"
486 del document.body[ i + 2]
488 if document.body[i + 1].find("false") != -1:
489 document.body[i + 1] = "status collapsed"
490 del document.body[ i + 2]
492 document.warning("Malformed LyX document: show_label neither false nor true.")
494 document.warning("Malformed LyX document: show_label missing in CharStyle.")
499 def revert_show_label(document):
502 i = find_token(document.body, "\\begin_inset CharStyle", i)
505 if document.body[i + 1].find("status open") != -1:
506 document.body.insert(i + 1, "show_label true")
508 if document.body[i + 1].find("status collapsed") != -1:
509 document.body.insert(i + 1, "show_label false")
511 document.warning("Malformed LyX document: no legal status line in CharStyle.")
514 def revert_begin_modules(document):
517 i = find_token(document.header, "\\begin_modules", i)
520 j = find_end_of(document.header, i, "\\begin_modules", "\\end_modules")
522 # this should not happen
524 document.header[i : j + 1] = []
526 def convert_flex(document):
527 "Convert CharStyle to Flex"
530 i = find_token(document.body, "\\begin_inset CharStyle", i)
533 document.body[i] = document.body[i].replace('\\begin_inset CharStyle', '\\begin_inset Flex')
535 def revert_flex(document):
536 "Convert Flex to CharStyle"
539 i = find_token(document.body, "\\begin_inset Flex", i)
542 document.body[i] = document.body[i].replace('\\begin_inset Flex', '\\begin_inset CharStyle')
545 # Discard PDF options for hyperref
546 def revert_pdf_options(document):
547 "Revert PDF options for hyperref."
548 # store the PDF options and delete the entries from the Lyx file
556 bookmarksnumbered = ""
558 bookmarksopenlevel = ""
566 i = find_token(document.header, "\\use_hyperref", i)
568 hyperref = get_value(document.header, "\\use_hyperref", i) == 'true'
569 del document.header[i]
570 i = find_token(document.header, "\\pdf_store_options", i)
572 del document.header[i]
573 i = find_token(document.header, "\\pdf_title", 0)
575 title = get_value_string(document.header, '\\pdf_title', 0, 0, True)
576 title = ' pdftitle={' + title + '}'
577 del document.header[i]
578 i = find_token(document.header, "\\pdf_author", 0)
580 author = get_value_string(document.header, '\\pdf_author', 0, 0, True)
582 author = ' pdfauthor={' + author + '}'
584 author = ',\n pdfauthor={' + author + '}'
585 del document.header[i]
586 i = find_token(document.header, "\\pdf_subject", 0)
588 subject = get_value_string(document.header, '\\pdf_subject', 0, 0, True)
589 if title == "" and author == "":
590 subject = ' pdfsubject={' + subject + '}'
592 subject = ',\n pdfsubject={' + subject + '}'
593 del document.header[i]
594 i = find_token(document.header, "\\pdf_keywords", 0)
596 keywords = get_value_string(document.header, '\\pdf_keywords', 0, 0, True)
597 if title == "" and author == "" and subject == "":
598 keywords = ' pdfkeywords={' + keywords + '}'
600 keywords = ',\n pdfkeywords={' + keywords + '}'
601 del document.header[i]
602 i = find_token(document.header, "\\pdf_bookmarks", 0)
604 bookmarks = get_value_string(document.header, '\\pdf_bookmarks', 0)
605 bookmarks = ',\n bookmarks=' + bookmarks
606 del document.header[i]
607 i = find_token(document.header, "\\pdf_bookmarksnumbered", i)
609 bookmarksnumbered = get_value_string(document.header, '\\pdf_bookmarksnumbered', 0)
610 bookmarksnumbered = ',\n bookmarksnumbered=' + bookmarksnumbered
611 del document.header[i]
612 i = find_token(document.header, "\\pdf_bookmarksopen", i)
614 bookmarksopen = get_value_string(document.header, '\\pdf_bookmarksopen', 0)
615 bookmarksopen = ',\n bookmarksopen=' + bookmarksopen
616 del document.header[i]
617 i = find_token(document.header, "\\pdf_bookmarksopenlevel", i)
619 bookmarksopenlevel = get_value_string(document.header, '\\pdf_bookmarksopenlevel', 0, 0, True)
620 bookmarksopenlevel = ',\n bookmarksopenlevel=' + bookmarksopenlevel
621 del document.header[i]
622 i = find_token(document.header, "\\pdf_breaklinks", i)
624 breaklinks = get_value_string(document.header, '\\pdf_breaklinks', 0)
625 breaklinks = ',\n breaklinks=' + breaklinks
626 del document.header[i]
627 i = find_token(document.header, "\\pdf_pdfborder", i)
629 pdfborder = get_value_string(document.header, '\\pdf_pdfborder', 0)
630 if pdfborder == 'true':
631 pdfborder = ',\n pdfborder={0 0 0}'
633 pdfborder = ',\n pdfborder={0 0 1}'
634 del document.header[i]
635 i = find_token(document.header, "\\pdf_colorlinks", i)
637 colorlinks = get_value_string(document.header, '\\pdf_colorlinks', 0)
638 colorlinks = ',\n colorlinks=' + colorlinks
639 del document.header[i]
640 i = find_token(document.header, "\\pdf_backref", i)
642 backref = get_value_string(document.header, '\\pdf_backref', 0)
643 backref = ',\n backref=' + backref
644 del document.header[i]
645 i = find_token(document.header, "\\pdf_pagebackref", i)
647 pagebackref = get_value_string(document.header, '\\pdf_pagebackref', 0)
648 pagebackref = ',\n pagebackref=' + pagebackref
649 del document.header[i]
650 i = find_token(document.header, "\\pdf_pagemode", 0)
652 pagemode = get_value_string(document.header, '\\pdf_pagemode', 0)
653 pagemode = ',\n pdfpagemode=' + pagemode
654 del document.header[i]
655 i = find_token(document.header, "\\pdf_quoted_options", 0)
657 otheroptions = get_value_string(document.header, '\\pdf_quoted_options', 0, 0, True)
658 if title == "" and author == "" and subject == "" and keywords == "":
659 otheroptions = ' ' + otheroptions
661 otheroptions = ',\n ' + otheroptions
662 del document.header[i]
664 # write to the preamble when hyperref was used
666 # preamble write preparations
667 # bookmark numbers are only output when they are turned on
668 if bookmarksopen == ',\n bookmarksopen=true':
669 bookmarksopen = bookmarksopen + bookmarksopenlevel
670 if bookmarks == ',\n bookmarks=true':
671 bookmarks = bookmarks + bookmarksnumbered + bookmarksopen
673 bookmarks = bookmarks
674 # hypersetup is only output when there are things to be set up
675 setupstart = '\\hypersetup{%\n'
677 if otheroptions == "" and title == "" and author == ""\
678 and subject == "" and keywords == "":
682 add_to_preamble(document,
683 ['% Commands inserted by lyx2lyx for PDF properties',
684 '\\usepackage[unicode=true'
703 def remove_inzip_options(document):
704 "Remove inzipName and embed options from the Graphics inset"
707 i = find_token(document.body, "\\begin_inset Graphics", i)
710 j = find_end_of_inset(document.body, i + 1)
713 document.warning("Malformed LyX document: Could not find end of graphics inset.")
714 # If there's a inzip param, just remove that
715 k = find_token(document.body, "\tinzipName", i + 1, j)
718 # embed option must follow the inzipName option
719 del document.body[k+1]
723 def convert_inset_command(document):
726 \begin_inset LatexCommand cmd
728 \begin_inset CommandInset InsetType
733 i = find_token(document.body, "\\begin_inset LatexCommand", i)
736 line = document.body[i]
737 r = re.compile(r'\\begin_inset LatexCommand (.*)$')
741 #this is adapted from factory.cpp
742 if cmdName[0:4].lower() == "cite":
743 insetName = "citation"
744 elif cmdName == "url" or cmdName == "htmlurl":
746 elif cmdName[-3:] == "ref":
748 elif cmdName == "tableofcontents":
750 elif cmdName == "printnomenclature":
751 insetName = "nomencl_print"
752 elif cmdName == "printindex":
753 insetName = "index_print"
756 insertion = ["\\begin_inset CommandInset " + insetName, "LatexCommand " + cmdName]
757 document.body[i : i+1] = insertion
760 def revert_inset_command(document):
763 \begin_inset CommandInset InsetType
766 \begin_inset LatexCommand cmd
767 Some insets may end up being converted to insets earlier versions of LyX
768 will not be able to recognize. Not sure what to do about that.
772 i = find_token(document.body, "\\begin_inset CommandInset", i)
775 nextline = document.body[i+1]
776 r = re.compile(r'LatexCommand\s+(.*)$')
777 m = r.match(nextline)
779 document.warning("Malformed LyX document: Missing LatexCommand in " + document.body[i] + ".")
782 insertion = ["\\begin_inset LatexCommand " + cmdName]
783 document.body[i : i+2] = insertion
786 def convert_wrapfig_options(document):
787 "Convert optional options for wrap floats (wrapfig)."
788 # adds the tokens "lines", "placement", and "overhang"
791 i = find_token(document.body, "\\begin_inset Wrap figure", i)
794 document.body.insert(i + 1, "lines 0")
795 j = find_token(document.body, "placement", i)
796 # placement can be already set or not; if not, set it
798 document.body.insert(i + 3, "overhang 0col%")
800 document.body.insert(i + 2, "placement o")
801 document.body.insert(i + 3, "overhang 0col%")
805 def revert_wrapfig_options(document):
806 "Revert optional options for wrap floats (wrapfig)."
809 i = find_token(document.body, "\\begin_inset Wrap figure", i)
812 j = find_end_of_inset(document.body, i)
814 document.warning("Can't find end of Wrap inset at line " + str(i))
817 k = find_default_layout(document, i, j)
819 document.warning("Can't find default layout for Wrap figure!")
822 # Options should be between i and k now
823 l = find_token(document.body, "lines", i, k)
825 document.warning("Can't find lines option for Wrap figure!")
828 m = find_token(document.body, "overhang", i + 1, k)
830 document.warning("Malformed LyX document: Couldn't find overhang parameter of wrap float!")
833 # Do these in reverse order
839 def convert_latexcommand_index(document):
840 "Convert from LatexCommand form to collapsable form."
842 r1 = re.compile('name "(.*)"')
844 i = find_token(document.body, "\\begin_inset CommandInset index", i)
847 if document.body[i + 1] != "LatexCommand index": # Might also be index_print
849 m = r1.match(document.body[i + 2])
851 document.warning("Unable to match: " + document.body[i+2])
854 fullcontent = m.group(1)
855 #document.warning(fullcontent)
856 document.body[i:i + 3] = ["\\begin_inset Index",
858 "\\begin_layout Standard"]
860 # We are now on the blank line preceding "\end_inset"
861 # We will write the content here, into the inset.
863 linelist = latex2lyx(fullcontent)
864 document.body[i+1:i+1] = linelist
867 document.body.insert(i + 1, "\\end_layout")
871 def revert_latexcommand_index(document):
872 "Revert from collapsable form to LatexCommand form."
875 i = find_token(document.body, "\\begin_inset Index", i)
878 j = find_end_of_inset(document.body, i + 1)
881 del document.body[j - 1]
882 del document.body[j - 2] # \end_layout
883 document.body[i] = "\\begin_inset CommandInset index"
884 document.body[i + 1] = "LatexCommand index"
885 # clean up multiline stuff
888 for k in range(i + 3, j - 2):
889 line = document.body[k]
890 if line.startswith("\\begin_inset ERT"):
891 ert_end = find_end_of_inset(document.body, k + 1)
893 if line.startswith("\\begin_inset Formula"):
895 if line.startswith("\\begin_layout Standard"):
897 if line.startswith("\\begin_layout Plain Layout"):
899 if line.startswith("\\end_layout"):
901 if line.startswith("\\end_inset"):
903 if line.startswith("status collapsed"):
905 if line.startswith("status open"):
907 # a lossless reversion is not possible
908 # try at least to handle some common insets and settings
909 # do not replace inside ERTs
911 # Do the LyX text --> LaTeX conversion
912 for rep in replacements:
913 line = line.replace(rep[1], rep[0])
914 line = line.replace(r'\backslash', r'\textbackslash{}')
915 line = line.replace(r'\series bold', r'\bfseries{}').replace(r'\series default', r'\mdseries{}')
916 line = line.replace(r'\shape italic', r'\itshape{}').replace(r'\shape smallcaps', r'\scshape{}')
917 line = line.replace(r'\shape slanted', r'\slshape{}').replace(r'\shape default', r'\upshape{}')
918 line = line.replace(r'\emph on', r'\em{}').replace(r'\emph default', r'\em{}')
919 line = line.replace(r'\noun on', r'\scshape{}').replace(r'\noun default', r'\upshape{}')
920 line = line.replace(r'\bar under', r'\underbar{').replace(r'\bar default', r'}')
921 line = line.replace(r'\family sans', r'\sffamily{}').replace(r'\family default', r'\normalfont{}')
922 line = line.replace(r'\family typewriter', r'\ttfamily{}').replace(r'\family roman', r'\rmfamily{}')
923 line = line.replace(r'\InsetSpace ', r'').replace(r'\SpecialChar ', r'')
925 line = line.replace(r'\backslash', r'\\')
926 content = content + line;
927 document.body[i + 3] = "name " + '"' + content + '"'
928 for k in range(i + 4, j - 2):
929 del document.body[i + 4]
930 document.body.insert(i + 4, "")
931 del document.body[i + 2] # \begin_layout standard
935 def revert_wraptable(document):
936 "Revert wrap table to wrap figure."
939 i = find_token(document.body, "\\begin_inset Wrap table", i)
942 document.body[i] = document.body[i].replace('\\begin_inset Wrap table', '\\begin_inset Wrap figure')
946 def revert_vietnamese(document):
947 "Set language Vietnamese to English"
948 # Set document language from Vietnamese to English
950 if document.language == "vietnamese":
951 document.language = "english"
952 i = find_token(document.header, "\\language", 0)
954 document.header[i] = "\\language english"
957 j = find_token(document.body, "\\lang vietnamese", j)
960 document.body[j] = document.body[j].replace("\\lang vietnamese", "\\lang english")
964 def revert_japanese(document):
965 "Set language japanese-plain to japanese"
966 # Set document language from japanese-plain to japanese
968 if document.language == "japanese-plain":
969 document.language = "japanese"
970 i = find_token(document.header, "\\language", 0)
972 document.header[i] = "\\language japanese"
975 j = find_token(document.body, "\\lang japanese-plain", j)
978 document.body[j] = document.body[j].replace("\\lang japanese-plain", "\\lang japanese")
982 def revert_japanese_encoding(document):
983 "Set input encoding form EUC-JP-plain to EUC-JP etc."
984 # Set input encoding form EUC-JP-plain to EUC-JP etc.
986 i = find_token(document.header, "\\inputencoding EUC-JP-plain", 0)
988 document.header[i] = "\\inputencoding EUC-JP"
990 j = find_token(document.header, "\\inputencoding JIS-plain", 0)
992 document.header[j] = "\\inputencoding JIS"
994 k = find_token(document.header, "\\inputencoding SJIS-plain", 0)
995 if k != -1: # convert to UTF8 since there is currently no SJIS encoding
996 document.header[k] = "\\inputencoding UTF8"
999 def revert_inset_info(document):
1000 'Replace info inset with its content'
1003 i = find_token(document.body, '\\begin_inset Info', i)
1006 j = find_end_of_inset(document.body, i + 1)
1009 document.warning("Malformed LyX document: Could not find end of Info inset.")
1012 for k in range(i, j+1):
1013 if document.body[k].startswith("arg"):
1014 arg = document.body[k][3:].strip().strip('"')
1015 if document.body[k].startswith("type"):
1016 type = document.body[k][4:].strip().strip('"')
1017 # I think there is a newline after \\end_inset, which should be removed.
1018 if document.body[j + 1].strip() == "":
1019 document.body[i : (j + 2)] = [type + ':' + arg]
1021 document.body[i : (j + 1)] = [type + ':' + arg]
1024 def convert_pdf_options(document):
1025 # Set the pdfusetitle tag, delete the pdf_store_options,
1026 # set quotes for bookmarksopenlevel"
1027 has_hr = get_value(document.header, "\\use_hyperref", 0, default = "0")
1029 k = find_token(document.header, "\\use_hyperref", 0)
1030 document.header.insert(k + 1, "\\pdf_pdfusetitle true")
1031 k = find_token(document.header, "\\pdf_store_options", 0)
1033 del document.header[k]
1034 i = find_token(document.header, "\\pdf_bookmarksopenlevel", k)
1036 document.header[i] = document.header[i].replace('"', '')
1039 def revert_pdf_options_2(document):
1040 # reset the pdfusetitle tag, set quotes for bookmarksopenlevel"
1041 k = find_token(document.header, "\\use_hyperref", 0)
1042 i = find_token(document.header, "\\pdf_pdfusetitle", k)
1044 del document.header[i]
1045 i = find_token(document.header, "\\pdf_bookmarksopenlevel", k)
1047 values = document.header[i].split()
1048 values[1] = ' "' + values[1] + '"'
1049 document.header[i] = ''.join(values)
1052 def convert_htmlurl(document):
1053 'Convert "htmlurl" to "href" insets for docbook'
1054 if document.backend != "docbook":
1058 i = find_token(document.body, "\\begin_inset CommandInset url", i)
1061 document.body[i] = "\\begin_inset CommandInset href"
1062 document.body[i + 1] = "LatexCommand href"
1066 def convert_url(document):
1067 'Convert url insets to url charstyles'
1068 if document.backend == "docbook":
1072 i = find_token(document.body, "\\begin_inset CommandInset url", i)
1075 n = find_token(document.body, "name", i)
1077 # place the URL name in typewriter before the new URL insert
1078 # grab the name 'bla' from the e.g. the line 'name "bla"',
1079 # therefore start with the 6th character
1080 name = document.body[n][6:-1]
1081 newname = [name + " "]
1082 document.body[i:i] = newname
1084 j = find_token(document.body, "target", i)
1086 document.warning("Malformed LyX document: Can't find target for url inset")
1089 target = document.body[j][8:-1]
1090 k = find_token(document.body, "\\end_inset", j)
1092 document.warning("Malformed LyX document: Can't find end of url inset")
1095 newstuff = ["\\begin_inset Flex URL",
1096 "status collapsed", "",
1097 "\\begin_layout Standard",
1102 document.body[i:k] = newstuff
1105 def convert_ams_classes(document):
1106 tc = document.textclass
1107 if (tc != "amsart" and tc != "amsart-plain" and
1108 tc != "amsart-seq" and tc != "amsbook"):
1110 if tc == "amsart-plain":
1111 document.textclass = "amsart"
1112 document.set_textclass()
1113 document.add_module("Theorems (Starred)")
1115 if tc == "amsart-seq":
1116 document.textclass = "amsart"
1117 document.set_textclass()
1118 document.add_module("Theorems (AMS)")
1120 #Now we want to see if any of the environments in the extended theorems
1121 #module were used in this document. If so, we'll add that module, too.
1122 layouts = ["Criterion", "Algorithm", "Axiom", "Condition", "Note", \
1123 "Notation", "Summary", "Acknowledgement", "Conclusion", "Fact", \
1126 r = re.compile(r'^\\begin_layout (.*?)\*?\s*$')
1129 i = find_token(document.body, "\\begin_layout", i)
1132 m = r.match(document.body[i])
1134 document.warning("Weirdly formed \\begin_layout at line %d of body!" % i)
1138 if layouts.count(m) != 0:
1139 document.add_module("Theorems (AMS-Extended)")
1143 def revert_href(document):
1144 'Reverts hyperlink insets (href) to url insets (url)'
1147 i = find_token(document.body, "\\begin_inset CommandInset href", i)
1150 document.body[i : i + 2] = \
1151 ["\\begin_inset CommandInset url", "LatexCommand url"]
1154 def revert_url(document):
1155 'Reverts Flex URL insets to old-style URL insets'
1158 i = find_token(document.body, "\\begin_inset Flex URL", i)
1161 j = find_end_of_inset(document.body, i)
1163 document.warning("Can't find end of inset in revert_url!")
1165 k = find_default_layout(document, i, j)
1167 document.warning("Can't find default layout in revert_url!")
1170 l = find_end_of(document.body, k, "\\begin_layout", "\\end_layout")
1171 if l == -1 or l >= j:
1172 document.warning("Can't find end of default layout in revert_url!")
1175 # OK, so the inset's data is between lines k and l.
1176 data = " ".join(document.body[k+1:l])
1178 newinset = ["\\begin_inset LatexCommand url", "target \"" + data + "\"",\
1180 document.body[i:j+1] = newinset
1181 i = i + len(newinset)
1184 def convert_include(document):
1185 'Converts include insets to new format.'
1187 r = re.compile(r'\\begin_inset Include\s+\\([^{]+){([^}]*)}(?:\[(.*)\])?')
1189 i = find_token(document.body, "\\begin_inset Include", i)
1192 line = document.body[i]
1193 previewline = document.body[i + 1]
1196 document.warning("Unable to match line " + str(i) + " of body!")
1202 insertion = ["\\begin_inset CommandInset include",
1203 "LatexCommand " + cmd, previewline,
1204 "filename \"" + fn + "\""]
1207 insertion.append("lstparams " + '"' + opt + '"')
1209 document.body[i : i + 2] = insertion
1213 def revert_include(document):
1214 'Reverts include insets to old format.'
1216 r0 = re.compile('preview.*')
1217 r1 = re.compile('LatexCommand (.+)')
1218 r2 = re.compile('filename "(.+)"')
1219 r3 = re.compile('lstparams "(.*)"')
1221 i = find_token(document.body, "\\begin_inset CommandInset include", i)
1225 if r0.match(document.body[nextline]):
1226 previewline = document.body[nextline]
1230 m = r1.match(document.body[nextline])
1232 document.warning("Malformed LyX document: No LatexCommand line for `" +
1233 document.body[i] + "' on line " + str(i) + ".")
1238 m = r2.match(document.body[nextline])
1240 document.warning("Malformed LyX document: No filename line for `" + \
1241 document.body[i] + "' on line " + str(i) + ".")
1247 if (cmd == "lstinputlisting"):
1248 m = r3.match(document.body[nextline])
1250 options = m.group(1)
1253 newline = "\\begin_inset Include \\" + cmd + "{" + fn + "}"
1255 newline += ("[" + options + "]")
1256 insertion = [newline]
1257 if previewline != "":
1258 insertion.append(previewline)
1259 document.body[i : nextline] = insertion
1263 def revert_albanian(document):
1264 "Set language Albanian to English"
1266 if document.language == "albanian":
1267 document.language = "english"
1268 i = find_token(document.header, "\\language", 0)
1270 document.header[i] = "\\language english"
1273 j = find_token(document.body, "\\lang albanian", j)
1276 document.body[j] = document.body[j].replace("\\lang albanian", "\\lang english")
1280 def revert_lowersorbian(document):
1281 "Set language lower Sorbian to English"
1283 if document.language == "lowersorbian":
1284 document.language = "english"
1285 i = find_token(document.header, "\\language", 0)
1287 document.header[i] = "\\language english"
1290 j = find_token(document.body, "\\lang lowersorbian", j)
1293 document.body[j] = document.body[j].replace("\\lang lowersorbian", "\\lang english")
1297 def revert_uppersorbian(document):
1298 "Set language uppersorbian to usorbian as this was used in LyX 1.5"
1300 if document.language == "uppersorbian":
1301 document.language = "usorbian"
1302 i = find_token(document.header, "\\language", 0)
1304 document.header[i] = "\\language usorbian"
1307 j = find_token(document.body, "\\lang uppersorbian", j)
1310 document.body[j] = document.body[j].replace("\\lang uppersorbian", "\\lang usorbian")
1314 def convert_usorbian(document):
1315 "Set language usorbian to uppersorbian"
1317 if document.language == "usorbian":
1318 document.language = "uppersorbian"
1319 i = find_token(document.header, "\\language", 0)
1321 document.header[i] = "\\language uppersorbian"
1324 j = find_token(document.body, "\\lang usorbian", j)
1327 document.body[j] = document.body[j].replace("\\lang usorbian", "\\lang uppersorbian")
1331 def revert_macro_optional_params(document):
1332 "Convert macro definitions with optional parameters into ERTs"
1333 # Stub to convert macro definitions with one or more optional parameters
1334 # into uninterpreted ERT insets
1337 def revert_hyperlinktype(document):
1338 'Reverts hyperlink type'
1342 i = find_token(document.body, "target", i)
1345 j = find_token(document.body, "type", i)
1349 del document.body[j]
1353 def revert_pagebreak(document):
1354 'Reverts pagebreak to ERT'
1357 i = find_token(document.body, "\\pagebreak", i)
1360 document.body[i] = '\\begin_inset ERT\nstatus collapsed\n\n' \
1361 '\\begin_layout Standard\n\n\n\\backslash\n' \
1362 'pagebreak{}\n\\end_layout\n\n\\end_inset\n\n'
1366 def revert_linebreak(document):
1367 'Reverts linebreak to ERT'
1370 i = find_token(document.body, "\\linebreak", i)
1373 document.body[i] = '\\begin_inset ERT\nstatus collapsed\n\n' \
1374 '\\begin_layout Standard\n\n\n\\backslash\n' \
1375 'linebreak{}\n\\end_layout\n\n\\end_inset\n\n'
1379 def revert_latin(document):
1380 "Set language Latin to English"
1382 if document.language == "latin":
1383 document.language = "english"
1384 i = find_token(document.header, "\\language", 0)
1386 document.header[i] = "\\language english"
1389 j = find_token(document.body, "\\lang latin", j)
1392 document.body[j] = document.body[j].replace("\\lang latin", "\\lang english")
1396 def revert_samin(document):
1397 "Set language North Sami to English"
1399 if document.language == "samin":
1400 document.language = "english"
1401 i = find_token(document.header, "\\language", 0)
1403 document.header[i] = "\\language english"
1406 j = find_token(document.body, "\\lang samin", j)
1409 document.body[j] = document.body[j].replace("\\lang samin", "\\lang english")
1413 def convert_serbocroatian(document):
1414 "Set language Serbocroatian to Croatian as this was really Croatian in LyX 1.5"
1416 if document.language == "serbocroatian":
1417 document.language = "croatian"
1418 i = find_token(document.header, "\\language", 0)
1420 document.header[i] = "\\language croatian"
1423 j = find_token(document.body, "\\lang serbocroatian", j)
1426 document.body[j] = document.body[j].replace("\\lang serbocroatian", "\\lang croatian")
1430 def convert_framed_notes(document):
1431 "Convert framed notes to boxes. "
1434 i = find_tokens(document.body, ["\\begin_inset Note Framed", "\\begin_inset Note Shaded"], i)
1437 subst = [document.body[i].replace("\\begin_inset Note", "\\begin_inset Box"),
1446 'height_special "totalheight"']
1447 document.body[i:i+1] = subst
1451 def convert_module_names(document):
1452 modulemap = { 'Braille' : 'braille', 'Endnote' : 'endnotes', 'Foot to End' : 'foottoend',\
1453 'Hanging' : 'hanging', 'Linguistics' : 'linguistics', 'Logical Markup' : 'logicalmkup', \
1454 'Theorems (AMS-Extended)' : 'theorems-ams-extended', 'Theorems (AMS)' : 'theorems-ams', \
1455 'Theorems (Order By Chapter)' : 'theorems-chap', 'Theorems (Order By Section)' : 'theorems-sec', \
1456 'Theorems (Starred)' : 'theorems-starred', 'Theorems' : 'theorems-std' }
1457 modlist = document.get_module_list()
1458 if len(modlist) == 0:
1462 if modulemap.has_key(mod):
1463 newmodlist.append(modulemap[mod])
1465 document.warning("Can't find module %s in the module map!" % mod)
1466 newmodlist.append(mod)
1467 document.set_module_list(newmodlist)
1470 def revert_module_names(document):
1471 modulemap = { 'braille' : 'Braille', 'endnotes' : 'Endnote', 'foottoend' : 'Foot to End',\
1472 'hanging' : 'Hanging', 'linguistics' : 'Linguistics', 'logicalmkup' : 'Logical Markup', \
1473 'theorems-ams-extended' : 'Theorems (AMS-Extended)', 'theorems-ams' : 'Theorems (AMS)', \
1474 'theorems-chap' : 'Theorems (Order By Chapter)', 'theorems-sec' : 'Theorems (Order By Section)', \
1475 'theorems-starred' : 'Theorems (Starred)', 'theorems-std' : 'Theorems'}
1476 modlist = document.get_module_list()
1477 if len(modlist) == 0:
1481 if modulemap.has_key(mod):
1482 newmodlist.append(modulemap[mod])
1484 document.warning("Can't find module %s in the module map!" % mod)
1485 newmodlist.append(mod)
1486 document.set_module_list(newmodlist)
1489 def revert_colsep(document):
1490 i = find_token(document.header, "\\columnsep", 0)
1493 colsepline = document.header[i]
1494 r = re.compile(r'\\columnsep (.*)')
1495 m = r.match(colsepline)
1497 document.warning("Malformed column separation line!")
1500 del document.header[i]
1501 #it seems to be safe to add the package even if it is already used
1502 pretext = ["\\usepackage{geometry}", "\\geometry{columnsep=" + colsep + "}"]
1504 add_to_preamble(document, pretext)
1507 def revert_framed_notes(document):
1508 "Revert framed boxes to notes. "
1511 i = find_tokens(document.body, ["\\begin_inset Box Framed", "\\begin_inset Box Shaded"], i)
1515 j = find_end_of_inset(document.body, i + 1)
1518 document.warning("Malformed LyX document: Could not find end of Box inset.")
1519 k = find_token(document.body, "status", i + 1, j)
1521 document.warning("Malformed LyX document: Missing `status' tag in Box inset.")
1523 status = document.body[k]
1524 l = find_default_layout(document, i + 1, j)
1526 document.warning("Malformed LyX document: Missing `\\begin_layout' in Box inset.")
1528 m = find_token(document.body, "\\end_layout", i + 1, j)
1530 document.warning("Malformed LyX document: Missing `\\end_layout' in Box inset.")
1532 ibox = find_token(document.body, "has_inner_box 1", i + 1, k)
1533 pbox = find_token(document.body, "use_parbox 1", i + 1, k)
1534 if ibox == -1 and pbox == -1:
1535 document.body[i] = document.body[i].replace("\\begin_inset Box", "\\begin_inset Note")
1536 del document.body[i+1:k]
1538 document.body[i] = document.body[i].replace("\\begin_inset Box Shaded", "\\begin_inset Box Frameless")
1539 subst1 = [document.body[l],
1540 "\\begin_inset Note Shaded",
1542 '\\begin_layout Standard']
1543 document.body[l:l + 1] = subst1
1544 subst2 = [document.body[m], "\\end_layout", "\\end_inset"]
1545 document.body[m:m + 1] = subst2
1549 def revert_slash(document):
1550 'Revert \\SpecialChar \\slash{} to ERT'
1551 r = re.compile(r'\\SpecialChar \\slash{}')
1553 while i < len(document.body):
1554 m = r.match(document.body[i])
1556 subst = ['\\begin_inset ERT',
1557 'status collapsed', '',
1558 '\\begin_layout Standard',
1559 '', '', '\\backslash',
1563 document.body[i: i+1] = subst
1569 def revert_nobreakdash(document):
1570 'Revert \\SpecialChar \\nobreakdash- to ERT'
1572 while i < len(document.body):
1573 line = document.body[i]
1574 r = re.compile(r'\\SpecialChar \\nobreakdash-')
1577 subst = ['\\begin_inset ERT',
1578 'status collapsed', '',
1579 '\\begin_layout Standard', '', '',
1584 document.body[i:i+1] = subst
1586 j = find_token(document.header, "\\use_amsmath", 0)
1588 document.warning("Malformed LyX document: Missing '\\use_amsmath'.")
1590 document.header[j] = "\\use_amsmath 2"
1595 #Returns number of lines added/removed
1596 def revert_nocite_key(body, start, end):
1597 'key "..." -> \nocite{...}'
1598 r = re.compile(r'^key "(.*)"')
1602 m = r.match(body[i])
1604 body[i:i+1] = ["\\backslash", "nocite{" + m.group(1) + "}"]
1605 j += 1 # because we added a line
1606 i += 2 # skip that line
1609 j -= 1 # because we deleted a line
1610 # no need to change i, since it now points to the next line
1614 def revert_nocite(document):
1615 "Revert LatexCommand nocite to ERT"
1618 i = find_token(document.body, "\\begin_inset CommandInset citation", i)
1621 if (document.body[i+1] != "LatexCommand nocite"):
1622 # note that we already incremented i
1625 insetEnd = find_end_of_inset(document.body, i)
1627 #this should not happen
1628 document.warning("End of CommandInset citation not found in revert_nocite!")
1631 paramLocation = i + 2 #start of the inset's parameters
1633 document.body[i:i+2] = \
1634 ["\\begin_inset ERT", "status collapsed", "", "\\begin_layout Standard"]
1635 # that added two lines
1638 #print insetEnd, document.body[i: insetEnd + 1]
1639 insetEnd += revert_nocite_key(document.body, paramLocation, insetEnd)
1640 #print insetEnd, document.body[i: insetEnd + 1]
1641 document.body.insert(insetEnd, "\\end_layout")
1642 document.body.insert(insetEnd + 1, "")
1646 def revert_btprintall(document):
1647 "Revert (non-bibtopic) btPrintAll option to ERT \nocite{*}"
1648 i = find_token(document.header, '\\use_bibtopic', 0)
1650 document.warning("Malformed lyx document: Missing '\\use_bibtopic'.")
1652 if get_value(document.header, '\\use_bibtopic', 0) == "false":
1654 while i < len(document.body):
1655 i = find_token(document.body, "\\begin_inset CommandInset bibtex", i)
1658 j = find_end_of_inset(document.body, i + 1)
1660 #this should not happen
1661 document.warning("End of CommandInset bibtex not found in revert_btprintall!")
1662 j = len(document.body)
1663 # this range isn't really right, but it should be OK, since we shouldn't
1664 # see more than one matching line in each inset
1666 for k in range(i, j):
1667 if (document.body[k] == 'btprint "btPrintAll"'):
1668 del document.body[k]
1669 subst = ["\\begin_inset ERT",
1670 "status collapsed", "",
1671 "\\begin_layout Standard", "",
1676 document.body[i:i] = subst
1677 addlines = addedlines + len(subst) - 1
1681 def revert_bahasam(document):
1682 "Set language Bahasa Malaysia to Bahasa Indonesia"
1684 if document.language == "bahasam":
1685 document.language = "bahasa"
1686 i = find_token(document.header, "\\language", 0)
1688 document.header[i] = "\\language bahasa"
1691 j = find_token(document.body, "\\lang bahasam", j)
1694 document.body[j] = document.body[j].replace("\\lang bahasam", "\\lang bahasa")
1698 def revert_interlingua(document):
1699 "Set language Interlingua to English"
1701 if document.language == "interlingua":
1702 document.language = "english"
1703 i = find_token(document.header, "\\language", 0)
1705 document.header[i] = "\\language english"
1708 j = find_token(document.body, "\\lang interlingua", j)
1711 document.body[j] = document.body[j].replace("\\lang interlingua", "\\lang english")
1715 def revert_serbianlatin(document):
1716 "Set language Serbian-Latin to Croatian"
1718 if document.language == "serbian-latin":
1719 document.language = "croatian"
1720 i = find_token(document.header, "\\language", 0)
1722 document.header[i] = "\\language croatian"
1725 j = find_token(document.body, "\\lang serbian-latin", j)
1728 document.body[j] = document.body[j].replace("\\lang serbian-latin", "\\lang croatian")
1732 def revert_rotfloat(document):
1733 " Revert sideways custom floats. "
1736 # whitespace intended (exclude \\begin_inset FloatList)
1737 i = find_token(document.body, "\\begin_inset Float ", i)
1740 line = document.body[i]
1741 r = re.compile(r'\\begin_inset Float (.*)$')
1744 document.warning("Unable to match line " + str(i) + " of body!")
1747 floattype = m.group(1)
1748 if floattype == "figure" or floattype == "table":
1751 j = find_end_of_inset(document.body, i)
1753 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_rotfloat.")
1757 if get_value(document.body, 'sideways', i, j) == "false":
1760 l = find_default_layout(document, i + 1, j)
1762 document.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
1764 subst = ['\\begin_layout Standard',
1765 '\\begin_inset ERT',
1766 'status collapsed', '',
1767 '\\begin_layout Standard', '', '',
1769 'end{sideways' + floattype + '}',
1770 '\\end_layout', '', '\\end_inset']
1771 document.body[j : j+1] = subst
1772 addedLines = len(subst) - 1
1773 del document.body[i+1 : l]
1774 addedLines -= (l-1) - (i+1)
1775 subst = ['\\begin_inset ERT', 'status collapsed', '',
1776 '\\begin_layout Standard', '', '', '\\backslash',
1777 'begin{sideways' + floattype + '}',
1778 '\\end_layout', '', '\\end_inset', '',
1780 document.body[i : i+1] = subst
1781 addedLines += len(subst) - 1
1782 if floattype == "algorithm":
1783 add_to_preamble(document,
1784 ['% Commands inserted by lyx2lyx for sideways algorithm float',
1785 '\\usepackage{rotfloat}',
1786 '\\floatstyle{ruled}',
1787 '\\newfloat{algorithm}{tbp}{loa}',
1788 '\\floatname{algorithm}{Algorithm}'])
1790 document.warning("Cannot create preamble definition for custom float" + floattype + ".")
1794 def revert_widesideways(document):
1795 " Revert wide sideways floats. "
1798 # whitespace intended (exclude \\begin_inset FloatList)
1799 i = find_token(document.body, '\\begin_inset Float ', i)
1802 line = document.body[i]
1803 r = re.compile(r'\\begin_inset Float (.*)$')
1806 document.warning("Unable to match line " + str(i) + " of body!")
1809 floattype = m.group(1)
1810 if floattype != "figure" and floattype != "table":
1813 j = find_end_of_inset(document.body, i)
1815 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_widesideways.")
1818 if get_value(document.body, 'sideways', i, j) == "false" or \
1819 get_value(document.body, 'wide', i, j) == "false":
1822 l = find_default_layout(document, i + 1, j)
1824 document.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
1826 subst = ['\\begin_layout Standard', '\\begin_inset ERT',
1827 'status collapsed', '',
1828 '\\begin_layout Standard', '', '', '\\backslash',
1829 'end{sideways' + floattype + '*}',
1830 '\\end_layout', '', '\\end_inset']
1831 document.body[j : j+1] = subst
1832 addedLines = len(subst) - 1
1833 del document.body[i+1:l-1]
1834 addedLines -= (l-1) - (i+1)
1835 subst = ['\\begin_inset ERT', 'status collapsed', '',
1836 '\\begin_layout Standard', '', '', '\\backslash',
1837 'begin{sideways' + floattype + '*}', '\\end_layout', '',
1838 '\\end_inset', '', '\\end_layout', '']
1839 document.body[i : i+1] = subst
1840 addedLines += len(subst) - 1
1841 add_to_preamble(document, ['\\usepackage{rotfloat}\n'])
1845 def revert_inset_embedding(document, type):
1846 ' Remove embed tag from certain type of insets'
1849 i = find_token(document.body, "\\begin_inset %s" % type, i)
1852 j = find_end_of_inset(document.body, i)
1854 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_inset_embedding.")
1857 k = find_token(document.body, "\tembed", i, j)
1859 k = find_token(document.body, "embed", i, j)
1861 del document.body[k]
1865 def revert_external_embedding(document):
1866 ' Remove embed tag from external inset '
1867 revert_inset_embedding(document, 'External')
1870 def convert_subfig(document):
1871 " Convert subfigures to subfloats. "
1874 i = find_token(document.body, '\\begin_inset Graphics', i)
1877 endInset = find_end_of_inset(document.body, i)
1879 document.warning("Malformed lyx document: Missing '\\end_inset' in convert_subfig.")
1882 k = find_token(document.body, '\tsubcaption', i, endInset)
1886 l = find_token(document.body, '\tsubcaptionText', i, endInset)
1888 document.warning("Malformed lyx document: Can't find subcaptionText!")
1891 caption = document.body[l][16:].strip('"')
1892 del document.body[l]
1893 del document.body[k]
1895 subst = ['\\begin_inset Float figure', 'wide false', 'sideways false',
1896 'status open', '', '\\begin_layout Plain Layout', '\\begin_inset Caption',
1897 '', '\\begin_layout Plain Layout',
1898 caption, '\\end_layout', '', '\\end_inset', '',
1899 '\\end_layout', '', '\\begin_layout Plain Layout']
1900 document.body[i : i] = subst
1901 addedLines += len(subst)
1902 endInset += addedLines
1903 subst = ['', '\\end_inset', '', '\\end_layout']
1904 document.body[endInset : endInset] = subst
1905 addedLines += len(subst)
1909 def revert_subfig(document):
1910 " Revert subfloats. "
1913 # whitespace intended (exclude \\begin_inset FloatList)
1914 i = find_tokens(document.body, ['\\begin_inset Float ', '\\begin_inset Wrap'], i)
1920 j = find_end_of_inset(document.body, i)
1922 document.warning("Malformed lyx document: Missing '\\end_inset' (float) at line " + str(i + len(document.header)) + ".\n\t" + document.body[i])
1923 # document.warning(document.body[i-1] + "\n" + document.body[i+1])
1925 continue # this will get us back to the outer loop, since j == -1
1926 # look for embedded float (= subfloat)
1927 # whitespace intended (exclude \\begin_inset FloatList)
1928 k = find_token(document.body, '\\begin_inset Float ', i + 1, j)
1931 l = find_end_of_inset(document.body, k)
1933 document.warning("Malformed lyx document: Missing '\\end_inset' (embedded float).")
1936 continue # escape to the outer loop
1937 m = find_default_layout(document, k + 1, l)
1939 cap = find_token(document.body, '\\begin_inset Caption', k + 1, l)
1944 capend = find_end_of_inset(document.body, cap)
1946 document.warning("Malformed lyx document: Missing '\\end_inset' (caption).")
1950 lbl = find_token(document.body, '\\begin_inset CommandInset label', cap, capend)
1952 lblend = find_end_of_inset(document.body, lbl + 1)
1954 document.warning("Malformed lyx document: Missing '\\end_inset' (label).")
1956 for line in document.body[lbl:lblend + 1]:
1957 if line.startswith('name '):
1958 label = line.split()[1].strip('"')
1965 opt = find_token(document.body, '\\begin_inset OptArg', cap, capend)
1967 optend = find_end_of_inset(document.body, opt)
1969 document.warning("Malformed lyx document: Missing '\\end_inset' (OptArg).")
1971 optc = find_default_layout(document, opt, optend)
1973 document.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
1975 optcend = find_end_of(document.body, optc, "\\begin_layout", "\\end_layout")
1976 for line in document.body[optc:optcend]:
1977 if not line.startswith('\\'):
1978 shortcap += line.strip()
1982 for line in document.body[cap:capend]:
1983 if line in document.body[lbl:lblend]:
1985 elif line in document.body[opt:optend]:
1987 elif not line.startswith('\\'):
1988 caption += line.strip()
1990 caption += "\\backslash\nlabel{" + label + "}"
1991 subst = '\\begin_layout Plain Layout\n\\begin_inset ERT\nstatus collapsed\n\n' \
1992 '\\begin_layout Plain Layout\n\n}\n\\end_layout\n\n\\end_inset\n\n' \
1993 '\\end_layout\n\n\\begin_layout Plain Layout\n'
1994 subst = subst.split('\n')
1995 document.body[l : l+1] = subst
1996 addedLines = len(subst) - 1
1997 # this is before l and so is unchanged by the multiline insertion
1999 del document.body[cap:capend+1]
2000 addedLines -= (capend + 1 - cap)
2001 del document.body[k+1:m-1]
2002 addedLines -= (m - 1 - (k + 1))
2003 insertion = '\\begin_inset ERT\nstatus collapsed\n\n' \
2004 '\\begin_layout Plain Layout\n\n\\backslash\n' \
2006 if len(shortcap) > 0:
2007 insertion = insertion + "[" + shortcap + "]"
2008 if len(caption) > 0:
2009 insertion = insertion + "[" + caption + "]"
2010 insertion = insertion + '{%\n\\end_layout\n\n\\end_inset\n\n\\end_layout\n'
2011 insertion = insertion.split('\n')
2012 document.body[k : k + 1] = insertion
2013 addedLines += len(insertion) - 1
2014 add_to_preamble(document, ['\\usepackage{subfig}\n'])
2018 def revert_wrapplacement(document):
2019 " Revert placement options wrap floats (wrapfig). "
2022 i = find_token(document.body, "\\begin_inset Wrap figure", i)
2025 e = find_end_of_inset(document.body, i)
2026 j = find_token(document.body, "placement", i + 1, e)
2028 document.warning("Malformed LyX document: Couldn't find placement parameter of wrap float.")
2031 r = re.compile("placement (o|i|l|r)")
2032 m = r.match(document.body[j])
2034 document.warning("Malformed LyX document: Placement option isn't O|I|R|L!")
2035 document.body[j] = "placement " + m.group(1).lower()
2039 def remove_extra_embedded_files(document):
2040 " Remove \extra_embedded_files from buffer params "
2041 i = find_token(document.header, '\\extra_embedded_files', 0)
2044 document.header.pop(i)
2047 def convert_spaceinset(document):
2048 " Convert '\\InsetSpace foo' to '\\begin_inset Space foo\n\\end_inset' "
2050 while i < len(document.body):
2051 m = re.match(r'(.*)\\InsetSpace (.*)', document.body[i])
2055 subst = [before, "\\begin_inset Space " + after, "\\end_inset"]
2056 document.body[i: i+1] = subst
2062 def revert_spaceinset(document):
2063 " Revert '\\begin_inset Space foo\n\\end_inset' to '\\InsetSpace foo' "
2066 i = find_token(document.body, "\\begin_inset Space", i)
2069 j = find_end_of_inset(document.body, i)
2071 document.warning("Malformed LyX document: Could not find end of space inset.")
2073 document.body[i] = document.body[i].replace('\\begin_inset Space', '\\InsetSpace')
2074 del document.body[j]
2077 def convert_hfill(document):
2078 " Convert hfill to space inset "
2081 i = find_token(document.body, "\\hfill", i)
2084 subst = document.body[i].replace('\\hfill', \
2085 '\n\\begin_inset Space \\hfill{}\n\\end_inset')
2086 subst = subst.split('\n')
2087 document.body[i : i+1] = subst
2091 def revert_hfills(document):
2092 ' Revert \\hfill commands '
2093 hfill = re.compile(r'\\hfill')
2094 dotfill = re.compile(r'\\dotfill')
2095 hrulefill = re.compile(r'\\hrulefill')
2098 i = find_token(document.body, "\\InsetSpace", i)
2101 if hfill.search(document.body[i]):
2102 document.body[i] = \
2103 document.body[i].replace('\\InsetSpace \\hfill{}', '\\hfill')
2106 if dotfill.search(document.body[i]):
2107 subst = document.body[i].replace('\\InsetSpace \\dotfill{}', \
2108 '\\begin_inset ERT\nstatus collapsed\n\n' \
2109 '\\begin_layout Standard\n\n\n\\backslash\n' \
2110 'dotfill{}\n\\end_layout\n\n\\end_inset\n\n')
2111 subst = subst.split('\n')
2112 document.body[i : i+1] = subst
2115 if hrulefill.search(document.body[i]):
2116 subst = document.body[i].replace('\\InsetSpace \\hrulefill{}', \
2117 '\\begin_inset ERT\nstatus collapsed\n\n' \
2118 '\\begin_layout Standard\n\n\n\\backslash\n' \
2119 'hrulefill{}\n\\end_layout\n\n\\end_inset\n\n')
2120 subst = subst.split('\n')
2121 document.body[i : i+1] = subst
2126 def revert_hspace(document):
2127 ' Revert \\InsetSpace \\hspace{} to ERT '
2129 hspace = re.compile(r'\\hspace{}')
2130 hstar = re.compile(r'\\hspace\*{}')
2132 i = find_token(document.body, "\\InsetSpace \\hspace", i)
2135 length = get_value(document.body, '\\length', i+1)
2137 document.warning("Malformed lyx document: Missing '\\length' in Space inset.")
2139 del document.body[i+1]
2141 if hstar.search(document.body[i]):
2142 subst = document.body[i].replace('\\InsetSpace \\hspace*{}', \
2143 '\\begin_inset ERT\nstatus collapsed\n\n' \
2144 '\\begin_layout Standard\n\n\n\\backslash\n' \
2145 'hspace*{' + length + '}\n\\end_layout\n\n\\end_inset\n\n')
2146 subst = subst.split('\n')
2147 document.body[i : i+1] = subst
2148 addedLines += len(subst) - 1
2151 if hspace.search(document.body[i]):
2152 subst = document.body[i].replace('\\InsetSpace \\hspace{}', \
2153 '\\begin_inset ERT\nstatus collapsed\n\n' \
2154 '\\begin_layout Standard\n\n\n\\backslash\n' \
2155 'hspace{' + length + '}\n\\end_layout\n\n\\end_inset\n\n')
2156 subst = subst.split('\n')
2157 document.body[i : i+1] = subst
2158 addedLines += len(subst) - 1
2164 def revert_protected_hfill(document):
2165 ' Revert \\begin_inset Space \\hspace*{\\fill} to ERT '
2168 i = find_token(document.body, '\\begin_inset Space \\hspace*{\\fill}', i)
2171 j = find_end_of_inset(document.body, i)
2173 document.warning("Malformed LyX document: Could not find end of space inset.")
2175 del document.body[j]
2176 subst = document.body[i].replace('\\begin_inset Space \\hspace*{\\fill}', \
2177 '\\begin_inset ERT\nstatus collapsed\n\n' \
2178 '\\begin_layout Standard\n\n\n\\backslash\n' \
2179 'hspace*{\n\\backslash\nfill}\n\\end_layout\n\n\\end_inset\n\n')
2180 subst = subst.split('\n')
2181 document.body[i : i+1] = subst
2185 def revert_leftarrowfill(document):
2186 ' Revert \\begin_inset Space \\leftarrowfill{} to ERT '
2189 i = find_token(document.body, '\\begin_inset Space \\leftarrowfill{}', i)
2192 j = find_end_of_inset(document.body, i)
2194 document.warning("Malformed LyX document: Could not find end of space inset.")
2196 del document.body[j]
2197 subst = document.body[i].replace('\\begin_inset Space \\leftarrowfill{}', \
2198 '\\begin_inset ERT\nstatus collapsed\n\n' \
2199 '\\begin_layout Standard\n\n\n\\backslash\n' \
2200 'leftarrowfill{}\n\\end_layout\n\n\\end_inset\n\n')
2201 subst = subst.split('\n')
2202 document.body[i : i+1] = subst
2206 def revert_rightarrowfill(document):
2207 ' Revert \\begin_inset Space \\rightarrowfill{} to ERT '
2210 i = find_token(document.body, '\\begin_inset Space \\rightarrowfill{}', i)
2213 j = find_end_of_inset(document.body, i)
2215 document.warning("Malformed LyX document: Could not find end of space inset.")
2217 del document.body[j]
2218 subst = document.body[i].replace('\\begin_inset Space \\rightarrowfill{}', \
2219 '\\begin_inset ERT\nstatus collapsed\n\n' \
2220 '\\begin_layout Standard\n\n\n\\backslash\n' \
2221 'rightarrowfill{}\n\\end_layout\n\n\\end_inset\n\n')
2222 subst = subst.split('\n')
2223 document.body[i : i+1] = subst
2227 def revert_upbracefill(document):
2228 ' Revert \\begin_inset Space \\upbracefill{} to ERT '
2231 i = find_token(document.body, '\\begin_inset Space \\upbracefill{}', i)
2234 j = find_end_of_inset(document.body, i)
2236 document.warning("Malformed LyX document: Could not find end of space inset.")
2238 del document.body[j]
2239 subst = document.body[i].replace('\\begin_inset Space \\upbracefill{}', \
2240 '\\begin_inset ERT\nstatus collapsed\n\n' \
2241 '\\begin_layout Standard\n\n\n\\backslash\n' \
2242 'upbracefill{}\n\\end_layout\n\n\\end_inset\n\n')
2243 subst = subst.split('\n')
2244 document.body[i : i+1] = subst
2248 def revert_downbracefill(document):
2249 ' Revert \\begin_inset Space \\downbracefill{} to ERT '
2252 i = find_token(document.body, '\\begin_inset Space \\downbracefill{}', i)
2255 j = find_end_of_inset(document.body, i)
2257 document.warning("Malformed LyX document: Could not find end of space inset.")
2259 del document.body[j]
2260 subst = document.body[i].replace('\\begin_inset Space \\downbracefill{}', \
2261 '\\begin_inset ERT\nstatus collapsed\n\n' \
2262 '\\begin_layout Standard\n\n\n\\backslash\n' \
2263 'downbracefill{}\n\\end_layout\n\n\\end_inset\n\n')
2264 subst = subst.split('\n')
2265 document.body[i : i+1] = subst
2269 def revert_local_layout(document):
2270 ' Revert local layout headers.'
2273 i = find_token(document.header, "\\begin_local_layout", i)
2276 j = find_end_of(document.header, i, "\\begin_local_layout", "\\end_local_layout")
2278 # this should not happen
2280 document.header[i : j + 1] = []
2283 def convert_pagebreaks(document):
2284 ' Convert inline Newpage insets to new format '
2287 i = find_token(document.body, '\\newpage', i)
2290 document.body[i:i+1] = ['\\begin_inset Newpage newpage',
2294 i = find_token(document.body, '\\pagebreak', i)
2297 document.body[i:i+1] = ['\\begin_inset Newpage pagebreak',
2301 i = find_token(document.body, '\\clearpage', i)
2304 document.body[i:i+1] = ['\\begin_inset Newpage clearpage',
2308 i = find_token(document.body, '\\cleardoublepage', i)
2311 document.body[i:i+1] = ['\\begin_inset Newpage cleardoublepage',
2315 def revert_pagebreaks(document):
2316 ' Revert \\begin_inset Newpage to previous inline format '
2319 i = find_token(document.body, '\\begin_inset Newpage', i)
2322 j = find_end_of_inset(document.body, i)
2324 document.warning("Malformed LyX document: Could not find end of Newpage inset.")
2326 del document.body[j]
2327 document.body[i] = document.body[i].replace('\\begin_inset Newpage newpage', '\\newpage')
2328 document.body[i] = document.body[i].replace('\\begin_inset Newpage pagebreak', '\\pagebreak')
2329 document.body[i] = document.body[i].replace('\\begin_inset Newpage clearpage', '\\clearpage')
2330 document.body[i] = document.body[i].replace('\\begin_inset Newpage cleardoublepage', '\\cleardoublepage')
2333 def convert_linebreaks(document):
2334 ' Convert inline Newline insets to new format '
2337 i = find_token(document.body, '\\newline', i)
2340 document.body[i:i+1] = ['\\begin_inset Newline newline',
2344 i = find_token(document.body, '\\linebreak', i)
2347 document.body[i:i+1] = ['\\begin_inset Newline linebreak',
2351 def revert_linebreaks(document):
2352 ' Revert \\begin_inset Newline to previous inline format '
2355 i = find_token(document.body, '\\begin_inset Newline', i)
2358 j = find_end_of_inset(document.body, i)
2360 document.warning("Malformed LyX document: Could not find end of Newline inset.")
2362 del document.body[j]
2363 document.body[i] = document.body[i].replace('\\begin_inset Newline newline', '\\newline')
2364 document.body[i] = document.body[i].replace('\\begin_inset Newline linebreak', '\\linebreak')
2367 def convert_japanese_plain(document):
2368 ' Set language japanese-plain to japanese '
2370 if document.language == "japanese-plain":
2371 document.language = "japanese"
2372 i = find_token(document.header, "\\language", 0)
2374 document.header[i] = "\\language japanese"
2377 j = find_token(document.body, "\\lang japanese-plain", j)
2380 document.body[j] = document.body[j].replace("\\lang japanese-plain", "\\lang japanese")
2384 def revert_pdfpages(document):
2385 ' Revert pdfpages external inset to ERT '
2388 i = find_token(document.body, "\\begin_inset External", i)
2391 j = find_end_of_inset(document.body, i)
2393 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_pdfpages.")
2396 if get_value(document.body, 'template', i, j) == "PDFPages":
2397 filename = get_value(document.body, 'filename', i, j)
2399 r = re.compile(r'\textra PDFLaTeX \"(.*)\"$')
2400 for k in range(i, j):
2401 m = r.match(document.body[k])
2404 angle = get_value(document.body, 'rotateAngle', i, j)
2405 width = get_value(document.body, 'width', i, j)
2406 height = get_value(document.body, 'height', i, j)
2407 scale = get_value(document.body, 'scale', i, j)
2408 keepAspectRatio = find_token(document.body, "\tkeepAspectRatio", i, j)
2412 options += ",angle=" + angle
2414 options += "angle=" + angle
2417 options += ",width=" + convert_len(width)
2419 options += "width=" + convert_len(width)
2422 options += ",height=" + convert_len(height)
2424 options += "height=" + convert_len(height)
2427 options += ",scale=" + scale
2429 options += "scale=" + scale
2430 if keepAspectRatio != '':
2432 options += ",keepaspectratio"
2434 options += "keepaspectratio"
2436 options = '[' + options + ']'
2437 del document.body[i+1:j+1]
2438 document.body[i:i+1] = ['\\begin_inset ERT',
2441 '\\begin_layout Standard',
2444 'includepdf' + options + '{' + filename + '}',
2448 add_to_preamble(document, ['\\usepackage{pdfpages}\n'])
2454 def revert_mexican(document):
2455 ' Set language Spanish(Mexico) to Spanish '
2457 if document.language == "spanish-mexico":
2458 document.language = "spanish"
2459 i = find_token(document.header, "\\language", 0)
2461 document.header[i] = "\\language spanish"
2464 j = find_token(document.body, "\\lang spanish-mexico", j)
2467 document.body[j] = document.body[j].replace("\\lang spanish-mexico", "\\lang spanish")
2471 def remove_embedding(document):
2472 ' Remove embed tag from all insets '
2473 revert_inset_embedding(document, 'Graphics')
2474 revert_inset_embedding(document, 'External')
2475 revert_inset_embedding(document, 'CommandInset include')
2476 revert_inset_embedding(document, 'CommandInset bibtex')
2479 def revert_master(document):
2480 ' Remove master param '
2481 i = find_token(document.header, "\\master", 0)
2483 del document.header[i]
2486 def revert_graphics_group(document):
2487 ' Revert group information from graphics insets '
2490 i = find_token(document.body, "\\begin_inset Graphics", i)
2493 j = find_end_of_inset(document.body, i)
2495 document.warning("Malformed lyx document: Missing '\\end_inset' in revert_graphics_group.")
2498 k = find_token(document.body, " groupId", i, j)
2502 del document.body[k]
2506 def update_apa_styles(document):
2507 ' Replace obsolete styles '
2509 if document.textclass != "apa":
2512 obsoletedby = { "Acknowledgments": "Acknowledgements",
2513 "Section*": "Section",
2514 "Subsection*": "Subsection",
2515 "Subsubsection*": "Subsubsection",
2516 "Paragraph*": "Paragraph",
2517 "Subparagraph*": "Subparagraph"}
2520 i = find_token(document.body, "\\begin_layout", i)
2524 layout = document.body[i][14:]
2525 if layout in obsoletedby:
2526 document.body[i] = "\\begin_layout " + obsoletedby[layout]
2531 def convert_paper_sizes(document):
2532 ' exchange size options legalpaper and executivepaper to correct order '
2533 # routine is needed to fix http://bugzilla.lyx.org/show_bug.cgi?id=4868
2536 i = find_token(document.header, "\\papersize executivepaper", 0)
2538 document.header[i] = "\\papersize legalpaper"
2540 j = find_token(document.header, "\\papersize legalpaper", 0)
2542 document.header[j] = "\\papersize executivepaper"
2545 def revert_paper_sizes(document):
2546 ' exchange size options legalpaper and executivepaper to correct order '
2549 i = find_token(document.header, "\\papersize executivepaper", 0)
2551 document.header[i] = "\\papersize legalpaper"
2553 j = find_token(document.header, "\\papersize legalpaper", 0)
2555 document.header[j] = "\\papersize executivepaper"
2558 def convert_InsetSpace(document):
2559 " Convert '\\begin_inset Space foo' to '\\begin_inset space foo'"
2562 i = find_token(document.body, "\\begin_inset Space", i)
2565 document.body[i] = document.body[i].replace('\\begin_inset Space', '\\begin_inset space')
2568 def revert_InsetSpace(document):
2569 " Revert '\\begin_inset space foo' to '\\begin_inset Space foo'"
2572 i = find_token(document.body, "\\begin_inset space", i)
2575 document.body[i] = document.body[i].replace('\\begin_inset space', '\\begin_inset Space')
2578 def convert_display_enum(document):
2579 " Convert 'display foo' to 'display false/true'"
2582 i = find_token(document.body, "\tdisplay", i)
2585 val = get_value(document.body, 'display', i)
2587 document.body[i] = document.body[i].replace('none', 'false')
2588 if val == "default":
2589 document.body[i] = document.body[i].replace('default', 'true')
2590 if val == "monochrome":
2591 document.body[i] = document.body[i].replace('monochrome', 'true')
2592 if val == "grayscale":
2593 document.body[i] = document.body[i].replace('grayscale', 'true')
2595 document.body[i] = document.body[i].replace('color', 'true')
2596 if val == "preview":
2597 document.body[i] = document.body[i].replace('preview', 'true')
2601 def revert_display_enum(document):
2602 " Revert 'display false/true' to 'display none/color'"
2605 i = find_token(document.body, "\tdisplay", i)
2608 val = get_value(document.body, 'display', i)
2610 document.body[i] = document.body[i].replace('false', 'none')
2612 document.body[i] = document.body[i].replace('true', 'default')
2616 def remove_fontsCJK(document):
2617 ' Remove font_cjk param '
2618 i = find_token(document.header, "\\font_cjk", 0)
2620 del document.header[i]
2623 def convert_plain_layout(document):
2624 " Convert 'PlainLayout' to 'Plain Layout'"
2627 i = find_token(document.body, '\\begin_layout PlainLayout', i)
2630 document.body[i] = document.body[i].replace('\\begin_layout PlainLayout', \
2631 '\\begin_layout Plain Layout')
2635 def revert_plain_layout(document):
2636 " Convert 'PlainLayout' to 'Plain Layout'"
2639 i = find_token(document.body, '\\begin_layout Plain Layout', i)
2642 document.body[i] = document.body[i].replace('\\begin_layout Plain Layout', \
2643 '\\begin_layout PlainLayout')
2647 def revert_plainlayout(document):
2648 " Convert 'PlainLayout' to 'Plain Layout'"
2651 i = find_token(document.body, '\\begin_layout PlainLayout', i)
2654 # This will be incorrect for some document classes, since Standard is not always
2655 # the default. But (a) it is probably the best we can do and (b) it will actually
2656 # work, in fact, since an unknown layout will be converted to default.
2657 document.body[i] = document.body[i].replace('\\begin_layout PlainLayout', \
2658 '\\begin_layout Standard')
2662 def revert_polytonicgreek(document):
2663 "Set language polytonic Greek to Greek"
2665 if document.language == "polutonikogreek":
2666 document.language = "greek"
2667 i = find_token(document.header, "\\language", 0)
2669 document.header[i] = "\\language greek"
2672 j = find_token(document.body, "\\lang polutonikogreek", j)
2675 document.body[j] = document.body[j].replace("\\lang polutonikogreek", "\\lang greek")
2683 supported_versions = ["1.6.0","1.6"]
2684 convert = [[277, [fix_wrong_tables]],
2685 [278, [close_begin_deeper]],
2686 [279, [long_charstyle_names]],
2687 [280, [axe_show_label]],
2690 [283, [convert_flex]],
2694 [287, [convert_wrapfig_options]],
2695 [288, [convert_inset_command]],
2696 [289, [convert_latexcommand_index]],
2701 [294, [convert_pdf_options]],
2702 [295, [convert_htmlurl, convert_url]],
2703 [296, [convert_include]],
2704 [297, [convert_usorbian]],
2710 [303, [convert_serbocroatian]],
2711 [304, [convert_framed_notes]],
2718 [311, [convert_ams_classes]],
2720 [313, [convert_module_names]],
2723 [316, [convert_subfig]],
2726 [319, [convert_spaceinset, convert_hfill]],
2728 [321, [convert_tablines]],
2729 [322, [convert_plain_layout]],
2730 [323, [convert_pagebreaks]],
2731 [324, [convert_linebreaks]],
2732 [325, [convert_japanese_plain]],
2735 [328, [remove_embedding, remove_extra_embedded_files, remove_inzip_options]],
2738 [331, [convert_ltcaption]],
2740 [333, [update_apa_styles]],
2741 [334, [convert_paper_sizes]],
2742 [335, [convert_InsetSpace]],
2744 [337, [convert_display_enum]],
2748 revert = [[337, [revert_polytonicgreek]],
2749 [336, [revert_display_enum]],
2750 [335, [remove_fontsCJK]],
2751 [334, [revert_InsetSpace]],
2752 [333, [revert_paper_sizes]],
2754 [331, [revert_graphics_group]],
2755 [330, [revert_ltcaption]],
2756 [329, [revert_leftarrowfill, revert_rightarrowfill, revert_upbracefill, revert_downbracefill]],
2757 [328, [revert_master]],
2759 [326, [revert_mexican]],
2760 [325, [revert_pdfpages]],
2762 [323, [revert_linebreaks]],
2763 [322, [revert_pagebreaks]],
2764 [321, [revert_local_layout, revert_plain_layout]],
2765 [320, [revert_tablines]],
2766 [319, [revert_protected_hfill]],
2767 [318, [revert_spaceinset, revert_hfills, revert_hspace]],
2768 [317, [remove_extra_embedded_files]],
2769 [316, [revert_wrapplacement]],
2770 [315, [revert_subfig]],
2771 [314, [revert_colsep, revert_plainlayout]],
2773 [312, [revert_module_names]],
2774 [311, [revert_rotfloat, revert_widesideways]],
2775 [310, [revert_external_embedding]],
2776 [309, [revert_btprintall]],
2777 [308, [revert_nocite]],
2778 [307, [revert_serbianlatin]],
2779 [306, [revert_slash, revert_nobreakdash]],
2780 [305, [revert_interlingua]],
2781 [304, [revert_bahasam]],
2782 [303, [revert_framed_notes]],
2784 [301, [revert_latin, revert_samin]],
2785 [300, [revert_linebreak]],
2786 [299, [revert_pagebreak]],
2787 [298, [revert_hyperlinktype]],
2788 [297, [revert_macro_optional_params]],
2789 [296, [revert_albanian, revert_lowersorbian, revert_uppersorbian]],
2790 [295, [revert_include]],
2791 [294, [revert_href, revert_url]],
2792 [293, [revert_pdf_options_2]],
2793 [292, [revert_inset_info]],
2794 [291, [revert_japanese, revert_japanese_encoding]],
2795 [290, [revert_vietnamese]],
2796 [289, [revert_wraptable]],
2797 [288, [revert_latexcommand_index]],
2798 [287, [revert_inset_command]],
2799 [286, [revert_wrapfig_options]],
2800 [285, [revert_pdf_options]],
2801 [284, [remove_inzip_options]],
2803 [282, [revert_flex]],
2805 [280, [revert_begin_modules]],
2806 [279, [revert_show_label]],
2807 [278, [revert_long_charstyle_names]],
2813 if __name__ == "__main__":