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")
34 def wrap_into_ert(string, src, dst):
35 " Wrap a something into an ERT"
36 return string.replace(src, '\n\\begin_inset ERT\nstatus collapsed\n\\begin_layout Standard\n'
37 + dst + '\n\\end_layout\n\\end_inset\n')
39 def add_to_preamble(document, text):
40 """ Add text to the preamble if it is not already there.
41 Only the first line is checked!"""
43 if find_token(document.preamble, text[0], 0) != -1:
46 document.preamble.extend(text)
48 # Convert a LyX length into a LaTeX length
50 units = {"text%":"\\backslash\ntextwidth", "col%":"\\backslash\ncolumnwidth",
51 "page%":"\\backslash\npagewidth", "line%":"\\backslash\nlinewidth",
52 "theight%":"\\backslash\ntextheight", "pheight%":"\\backslash\npageheight"}
54 # Convert LyX units to LaTeX units
55 for unit in units.keys():
56 if len.find(unit) != -1:
57 len = '%f' % (len2value(len) / 100)
58 len = len.strip('0') + units[unit]
63 # Return the value of len without the unit in numerical form.
65 result = re.search('([+-]?[0-9.]+)', len)
67 return float(result.group(1))
71 # Unfortunately, this doesn't really work, since Standard isn't always default.
72 # But it's as good as we can do right now.
73 def find_default_layout(document, start, end):
74 l = find_token(document.body, "\\begin_layout Standard", start, end)
76 l = find_token(document.body, "\\begin_layout PlainLayout", start, end)
78 l = find_token(document.body, "\\begin_layout Plain Layout", start, end)
81 ####################################################################
83 def get_option(document, m, option, default):
84 l = document.body[m].find(option)
87 val = document.body[m][l:].split('"')[1]
90 def remove_option(document, m, option):
91 l = document.body[m].find(option)
93 val = document.body[m][l:].split('"')[1]
94 document.body[m] = document.body[m][:l-1] + document.body[m][l+len(option + '="' + val + '"'):]
97 def set_option(document, m, option, value):
98 l = document.body[m].find(option)
100 oldval = document.body[m][l:].split('"')[1]
101 l = l + len(option + '="')
102 document.body[m] = document.body[m][:l] + value + document.body[m][l+len(oldval):]
104 document.body[m] = document.body[m][:-1] + ' ' + option + '="' + value + '">'
107 def convert_tablines(document):
110 i = find_token(document.body, "\\begin_inset Tabular", i)
112 # LyX 1.3 inserted an extra space between \begin_inset
113 # and Tabular so let us try if this is the case and fix it.
114 i = find_token(document.body, "\\begin_inset Tabular", i)
118 document.body[i] = "\\begin_inset Tabular"
119 j = find_end_of_inset(document.body, i + 1)
121 document.warning("Malformed LyX document: Could not find end of tabular.")
125 nrows = int(document.body[i+1].split('"')[3])
126 ncols = int(document.body[i+1].split('"')[5])
129 for k in range(ncols):
130 m = find_token(document.body, "<column", m)
131 left = get_option(document, m, 'leftline', 'false')
132 right = get_option(document, m, 'rightline', 'false')
133 col_info.append([left, right])
134 remove_option(document, m, 'leftline')
135 remove_option(document, m, 'rightline')
139 for k in range(nrows):
140 m = find_token(document.body, "<row", m)
141 top = get_option(document, m, 'topline', 'false')
142 bottom = get_option(document, m, 'bottomline', 'false')
143 row_info.append([top, bottom])
144 remove_option(document, m, 'topline')
145 remove_option(document, m, 'bottomline')
150 for k in range(nrows*ncols):
151 m = find_token(document.body, "<cell", m)
152 mc_info.append(get_option(document, m, 'multicolumn', '0'))
155 for l in range(nrows):
156 for k in range(ncols):
157 m = find_token(document.body, '<cell', m)
158 if mc_info[l*ncols + k] == '0':
159 r = set_option(document, m, 'topline', row_info[l][0])
160 r = set_option(document, m, 'bottomline', row_info[l][1])
161 r = set_option(document, m, 'leftline', col_info[k][0])
162 r = set_option(document, m, 'rightline', col_info[k][1])
163 elif mc_info[l*ncols + k] == '1':
165 while s < ncols and mc_info[l*ncols + s] == '2':
167 if s < ncols and mc_info[l*ncols + s] != '1':
168 r = set_option(document, m, 'rightline', col_info[k][1])
169 if k > 0 and mc_info[l*ncols + k - 1] == '0':
170 r = set_option(document, m, 'leftline', col_info[k][0])
175 def revert_tablines(document):
178 i = find_token(document.body, "\\begin_inset Tabular", i)
181 j = find_end_of_inset(document.body, i + 1)
183 document.warning("Malformed LyX document: Could not find end of tabular.")
187 nrows = int(document.body[i+1].split('"')[3])
188 ncols = int(document.body[i+1].split('"')[5])
191 for k in range(nrows*ncols):
192 m = find_token(document.body, "<cell", m)
193 top = get_option(document, m, 'topline', 'false')
194 bottom = get_option(document, m, 'bottomline', 'false')
195 left = get_option(document, m, 'leftline', 'false')
196 right = get_option(document, m, 'rightline', 'false')
197 lines.append([top, bottom, left, right])
202 for k in range(ncols):
203 m = find_token(document.body, "<column", m)
205 for l in range(nrows):
206 left = lines[l*ncols + k][2]
209 set_option(document, m, 'leftline', left)
211 for l in range(nrows):
212 right = lines[l*ncols + k][3]
215 set_option(document, m, 'rightline', right)
219 for k in range(nrows):
220 m = find_token(document.body, "<row", m)
222 for l in range(ncols):
223 top = lines[k*ncols + l][0]
226 set_option(document, m, 'topline', top)
228 for l in range(ncols):
229 bottom = lines[k*ncols + l][1]
230 if bottom == 'false':
232 set_option(document, m, 'bottomline', bottom)
238 def fix_wrong_tables(document):
241 i = find_token(document.body, "\\begin_inset Tabular", i)
244 j = find_end_of_inset(document.body, i + 1)
246 document.warning("Malformed LyX document: Could not find end of tabular.")
250 nrows = int(document.body[i+1].split('"')[3])
251 ncols = int(document.body[i+1].split('"')[5])
253 for l in range(nrows):
255 for k in range(ncols):
256 m = find_token(document.body, '<cell', m)
258 if document.body[m].find('multicolumn') != -1:
259 multicol_cont = int(document.body[m].split('"')[1])
261 if multicol_cont == 2 and (k == 0 or prev_multicolumn == 0):
262 document.body[m] = document.body[m][:5] + document.body[m][21:]
265 prev_multicolumn = multicol_cont
272 def close_begin_deeper(document):
276 i = find_tokens(document.body, ["\\begin_deeper", "\\end_deeper"], i)
281 if document.body[i][:13] == "\\begin_deeper":
288 document.body[-2:-2] = ['\\end_deeper' for i in range(depth)]
291 def long_charstyle_names(document):
294 i = find_token(document.body, "\\begin_inset CharStyle", i)
297 document.body[i] = document.body[i].replace("CharStyle ", "CharStyle CharStyle:")
300 def revert_long_charstyle_names(document):
303 i = find_token(document.body, "\\begin_inset CharStyle", i)
306 document.body[i] = document.body[i].replace("CharStyle CharStyle:", "CharStyle")
310 def axe_show_label(document):
313 i = find_token(document.body, "\\begin_inset CharStyle", i)
316 if document.body[i + 1].find("show_label") != -1:
317 if document.body[i + 1].find("true") != -1:
318 document.body[i + 1] = "status open"
319 del document.body[ i + 2]
321 if document.body[i + 1].find("false") != -1:
322 document.body[i + 1] = "status collapsed"
323 del document.body[ i + 2]
325 document.warning("Malformed LyX document: show_label neither false nor true.")
327 document.warning("Malformed LyX document: show_label missing in CharStyle.")
332 def revert_show_label(document):
335 i = find_token(document.body, "\\begin_inset CharStyle", i)
338 if document.body[i + 1].find("status open") != -1:
339 document.body.insert(i + 1, "show_label true")
341 if document.body[i + 1].find("status collapsed") != -1:
342 document.body.insert(i + 1, "show_label false")
344 document.warning("Malformed LyX document: no legal status line in CharStyle.")
347 def revert_begin_modules(document):
350 i = find_token(document.header, "\\begin_modules", i)
353 j = find_end_of(document.header, i, "\\begin_modules", "\\end_modules")
355 # this should not happen
357 document.header[i : j + 1] = []
359 def convert_flex(document):
360 "Convert CharStyle to Flex"
363 i = find_token(document.body, "\\begin_inset CharStyle", i)
366 document.body[i] = document.body[i].replace('\\begin_inset CharStyle', '\\begin_inset Flex')
368 def revert_flex(document):
369 "Convert Flex to CharStyle"
372 i = find_token(document.body, "\\begin_inset Flex", i)
375 document.body[i] = document.body[i].replace('\\begin_inset Flex', '\\begin_inset CharStyle')
378 # Discard PDF options for hyperref
379 def revert_pdf_options(document):
380 "Revert PDF options for hyperref."
381 # store the PDF options and delete the entries from the Lyx file
389 bookmarksnumbered = ""
391 bookmarksopenlevel = ""
399 i = find_token(document.header, "\\use_hyperref", i)
401 hyperref = get_value(document.header, "\\use_hyperref", i) == 'true'
402 del document.header[i]
403 i = find_token(document.header, "\\pdf_store_options", i)
405 del document.header[i]
406 i = find_token(document.header, "\\pdf_title", 0)
408 title = get_value_string(document.header, '\\pdf_title', 0, 0, True)
409 title = ' pdftitle={' + title + '}'
410 del document.header[i]
411 i = find_token(document.header, "\\pdf_author", 0)
413 author = get_value_string(document.header, '\\pdf_author', 0, 0, True)
415 author = ' pdfauthor={' + author + '}'
417 author = ',\n pdfauthor={' + author + '}'
418 del document.header[i]
419 i = find_token(document.header, "\\pdf_subject", 0)
421 subject = get_value_string(document.header, '\\pdf_subject', 0, 0, True)
422 if title == "" and author == "":
423 subject = ' pdfsubject={' + subject + '}'
425 subject = ',\n pdfsubject={' + subject + '}'
426 del document.header[i]
427 i = find_token(document.header, "\\pdf_keywords", 0)
429 keywords = get_value_string(document.header, '\\pdf_keywords', 0, 0, True)
430 if title == "" and author == "" and subject == "":
431 keywords = ' pdfkeywords={' + keywords + '}'
433 keywords = ',\n pdfkeywords={' + keywords + '}'
434 del document.header[i]
435 i = find_token(document.header, "\\pdf_bookmarks", 0)
437 bookmarks = get_value_string(document.header, '\\pdf_bookmarks', 0)
438 bookmarks = ',\n bookmarks=' + bookmarks
439 del document.header[i]
440 i = find_token(document.header, "\\pdf_bookmarksnumbered", i)
442 bookmarksnumbered = get_value_string(document.header, '\\pdf_bookmarksnumbered', 0)
443 bookmarksnumbered = ',\n bookmarksnumbered=' + bookmarksnumbered
444 del document.header[i]
445 i = find_token(document.header, "\\pdf_bookmarksopen", i)
447 bookmarksopen = get_value_string(document.header, '\\pdf_bookmarksopen', 0)
448 bookmarksopen = ',\n bookmarksopen=' + bookmarksopen
449 del document.header[i]
450 i = find_token(document.header, "\\pdf_bookmarksopenlevel", i)
452 bookmarksopenlevel = get_value_string(document.header, '\\pdf_bookmarksopenlevel', 0, 0, True)
453 bookmarksopenlevel = ',\n bookmarksopenlevel=' + bookmarksopenlevel
454 del document.header[i]
455 i = find_token(document.header, "\\pdf_breaklinks", i)
457 breaklinks = get_value_string(document.header, '\\pdf_breaklinks', 0)
458 breaklinks = ',\n breaklinks=' + breaklinks
459 del document.header[i]
460 i = find_token(document.header, "\\pdf_pdfborder", i)
462 pdfborder = get_value_string(document.header, '\\pdf_pdfborder', 0)
463 if pdfborder == 'true':
464 pdfborder = ',\n pdfborder={0 0 0}'
466 pdfborder = ',\n pdfborder={0 0 1}'
467 del document.header[i]
468 i = find_token(document.header, "\\pdf_colorlinks", i)
470 colorlinks = get_value_string(document.header, '\\pdf_colorlinks', 0)
471 colorlinks = ',\n colorlinks=' + colorlinks
472 del document.header[i]
473 i = find_token(document.header, "\\pdf_backref", i)
475 backref = get_value_string(document.header, '\\pdf_backref', 0)
476 backref = ',\n backref=' + backref
477 del document.header[i]
478 i = find_token(document.header, "\\pdf_pagebackref", i)
480 pagebackref = get_value_string(document.header, '\\pdf_pagebackref', 0)
481 pagebackref = ',\n pagebackref=' + pagebackref
482 del document.header[i]
483 i = find_token(document.header, "\\pdf_pagemode", 0)
485 pagemode = get_value_string(document.header, '\\pdf_pagemode', 0)
486 pagemode = ',\n pdfpagemode=' + pagemode
487 del document.header[i]
488 i = find_token(document.header, "\\pdf_quoted_options", 0)
490 otheroptions = get_value_string(document.header, '\\pdf_quoted_options', 0, 0, True)
491 if title == "" and author == "" and subject == "" and keywords == "":
492 otheroptions = ' ' + otheroptions
494 otheroptions = ',\n ' + otheroptions
495 del document.header[i]
497 # write to the preamble when hyperref was used
499 # preamble write preparations
500 # bookmark numbers are only output when they are turned on
501 if bookmarksopen == ',\n bookmarksopen=true':
502 bookmarksopen = bookmarksopen + bookmarksopenlevel
503 if bookmarks == ',\n bookmarks=true':
504 bookmarks = bookmarks + bookmarksnumbered + bookmarksopen
506 bookmarks = bookmarks
507 # hypersetup is only output when there are things to be set up
508 setupstart = '\\hypersetup{%\n'
510 if otheroptions == "" and title == "" and author == ""\
511 and subject == "" and keywords == "":
515 add_to_preamble(document,
516 ['% Commands inserted by lyx2lyx for PDF properties',
517 '\\usepackage[unicode=true'
536 def remove_inzip_options(document):
537 "Remove inzipName and embed options from the Graphics inset"
540 i = find_token(document.body, "\\begin_inset Graphics", i)
543 j = find_end_of_inset(document.body, i + 1)
546 document.warning("Malformed LyX document: Could not find end of graphics inset.")
547 # If there's a inzip param, just remove that
548 k = find_token(document.body, "\tinzipName", i + 1, j)
551 # embed option must follow the inzipName option
552 del document.body[k+1]
556 def convert_inset_command(document):
559 \begin_inset LatexCommand cmd
561 \begin_inset CommandInset InsetType
566 i = find_token(document.body, "\\begin_inset LatexCommand", i)
569 line = document.body[i]
570 r = re.compile(r'\\begin_inset LatexCommand (.*)$')
574 #this is adapted from factory.cpp
575 if cmdName[0:4].lower() == "cite":
576 insetName = "citation"
577 elif cmdName == "url" or cmdName == "htmlurl":
579 elif cmdName[-3:] == "ref":
581 elif cmdName == "tableofcontents":
583 elif cmdName == "printnomenclature":
584 insetName = "nomencl_print"
585 elif cmdName == "printindex":
586 insetName = "index_print"
589 insertion = ["\\begin_inset CommandInset " + insetName, "LatexCommand " + cmdName]
590 document.body[i : i+1] = insertion
593 def revert_inset_command(document):
596 \begin_inset CommandInset InsetType
599 \begin_inset LatexCommand cmd
600 Some insets may end up being converted to insets earlier versions of LyX
601 will not be able to recognize. Not sure what to do about that.
605 i = find_token(document.body, "\\begin_inset CommandInset", i)
608 nextline = document.body[i+1]
609 r = re.compile(r'LatexCommand\s+(.*)$')
610 m = r.match(nextline)
612 document.warning("Malformed LyX document: Missing LatexCommand in " + document.body[i] + ".")
615 insertion = ["\\begin_inset LatexCommand " + cmdName]
616 document.body[i : i+2] = insertion
619 def convert_wrapfig_options(document):
620 "Convert optional options for wrap floats (wrapfig)."
621 # adds the tokens "lines", "placement", and "overhang"
624 i = find_token(document.body, "\\begin_inset Wrap figure", i)
627 document.body.insert(i + 1, "lines 0")
628 j = find_token(document.body, "placement", i)
629 # placement can be already set or not; if not, set it
631 document.body.insert(i + 3, "overhang 0col%")
633 document.body.insert(i + 2, "placement o")
634 document.body.insert(i + 3, "overhang 0col%")
638 def revert_wrapfig_options(document):
639 "Revert optional options for wrap floats (wrapfig)."
642 i = find_token(document.body, "lines", i)
645 j = find_token(document.body, "overhang", i+1)
646 if j != i + 2 and j != -1:
647 document.warning("Malformed LyX document: Couldn't find overhang parameter of wrap float.")
651 del document.body[j-1]
655 def convert_latexcommand_index(document):
656 "Convert from LatexCommand form to collapsable form."
659 i = find_token(document.body, "\\begin_inset CommandInset index", i)
662 if document.body[i + 1] != "LatexCommand index": # Might also be index_print
664 fullcontent = document.body[i + 2][6:].strip('"')
665 document.body[i:i + 2] = ["\\begin_inset Index",
667 "\\begin_layout Standard"]
668 # Put here the conversions needed from LaTeX string to LyXText.
669 # Here we do a minimal conversion to prevent crashes and data loss.
670 # Manual patch-up may be needed.
671 # Umlauted characters (most common ones, can be extended):
672 fullcontent = fullcontent.replace(r'\\\"a', u'ä').replace(r'\\\"o', u'ö').replace(r'\\\"u', u'ü')
674 fullcontent = wrap_into_ert(fullcontent, r'\"', '"')
675 #fullcontent = fullcontent.replace(r'\"', '\n\\begin_inset ERT\nstatus collapsed\n\\begin_layout standard\n"\n\\end_layout\n\\end_inset\n')
677 r = re.compile('^(.*?)(\$.*?\$)(.*)')
682 f = m.group(2).replace('\\\\', '\\')
686 s = wrap_into_ert(s, r'\\', '\\backslash')
687 s = wrap_into_ert(s, '{', '{')
688 s = wrap_into_ert(s, '}', '}')
689 document.body.insert(i + 3, s)
691 document.body.insert(i + 3, "\\begin_inset Formula " + f)
692 document.body.insert(i + 4, "\\end_inset")
694 # Generic, \\ -> \backslash:
695 g = wrap_into_ert(g, r'\\', '\\backslash{}')
696 g = wrap_into_ert(g, '{', '{')
697 g = wrap_into_ert(g, '}', '}')
698 document.body.insert(i + 3, g)
699 document.body[i + 4] = "\\end_layout"
703 def revert_latexcommand_index(document):
704 "Revert from collapsable form to LatexCommand form."
707 i = find_token(document.body, "\\begin_inset Index", i)
710 j = find_end_of_inset(document.body, i + 1)
713 del document.body[j - 1]
714 del document.body[j - 2] # \end_layout
715 document.body[i] = "\\begin_inset CommandInset index"
716 document.body[i + 1] = "LatexCommand index"
717 # clean up multiline stuff
719 for k in range(i + 3, j - 2):
720 line = document.body[k]
721 if line.startswith("\\begin_inset ERT"):
723 if line.startswith("\\begin_inset Formula"):
725 if line.startswith("\\begin_layout Standard"):
727 if line.startswith("\\begin_layout Plain"):
729 if line.startswith("\\end_layout"):
731 if line.startswith("\\end_inset"):
733 if line.startswith("status collapsed"):
735 line = line.replace(u'ä', r'\\\"a').replace(u'ö', r'\\\"o').replace(u'ü', r'\\\"u')
736 content = content + line;
737 document.body[i + 3] = "name " + '"' + content + '"'
738 for k in range(i + 4, j - 2):
739 del document.body[i + 4]
740 document.body.insert(i + 4, "")
741 del document.body[i + 2] # \begin_layout standard
745 def revert_wraptable(document):
746 "Revert wrap table to wrap figure."
749 i = find_token(document.body, "\\begin_inset Wrap table", i)
752 document.body[i] = document.body[i].replace('\\begin_inset Wrap table', '\\begin_inset Wrap figure')
756 def revert_vietnamese(document):
757 "Set language Vietnamese to English"
758 # Set document language from Vietnamese to English
760 if document.language == "vietnamese":
761 document.language = "english"
762 i = find_token(document.header, "\\language", 0)
764 document.header[i] = "\\language english"
767 j = find_token(document.body, "\\lang vietnamese", j)
770 document.body[j] = document.body[j].replace("\\lang vietnamese", "\\lang english")
774 def revert_japanese(document):
775 "Set language japanese-plain to japanese"
776 # Set document language from japanese-plain to japanese
778 if document.language == "japanese-plain":
779 document.language = "japanese"
780 i = find_token(document.header, "\\language", 0)
782 document.header[i] = "\\language japanese"
785 j = find_token(document.body, "\\lang japanese-plain", j)
788 document.body[j] = document.body[j].replace("\\lang japanese-plain", "\\lang japanese")
792 def revert_japanese_encoding(document):
793 "Set input encoding form EUC-JP-plain to EUC-JP etc."
794 # Set input encoding form EUC-JP-plain to EUC-JP etc.
796 i = find_token(document.header, "\\inputencoding EUC-JP-plain", 0)
798 document.header[i] = "\\inputencoding EUC-JP"
800 j = find_token(document.header, "\\inputencoding JIS-plain", 0)
802 document.header[j] = "\\inputencoding JIS"
804 k = find_token(document.header, "\\inputencoding SJIS-plain", 0)
805 if k != -1: # convert to UTF8 since there is currently no SJIS encoding
806 document.header[k] = "\\inputencoding UTF8"
809 def revert_inset_info(document):
810 'Replace info inset with its content'
813 i = find_token(document.body, '\\begin_inset Info', i)
816 j = find_end_of_inset(document.body, i + 1)
819 document.warning("Malformed LyX document: Could not find end of Info inset.")
822 for k in range(i, j+1):
823 if document.body[k].startswith("arg"):
824 arg = document.body[k][3:].strip().strip('"')
825 if document.body[k].startswith("type"):
826 type = document.body[k][4:].strip().strip('"')
827 # I think there is a newline after \\end_inset, which should be removed.
828 if document.body[j + 1].strip() == "":
829 document.body[i : (j + 2)] = [type + ':' + arg]
831 document.body[i : (j + 1)] = [type + ':' + arg]
834 def convert_pdf_options(document):
835 # Set the pdfusetitle tag, delete the pdf_store_options,
836 # set quotes for bookmarksopenlevel"
837 has_hr = get_value(document.header, "\\use_hyperref", 0, default = "0")
839 k = find_token(document.header, "\\use_hyperref", 0)
840 document.header.insert(k + 1, "\\pdf_pdfusetitle true")
841 k = find_token(document.header, "\\pdf_store_options", 0)
843 del document.header[k]
844 i = find_token(document.header, "\\pdf_bookmarksopenlevel", k)
846 document.header[i] = document.header[i].replace('"', '')
849 def revert_pdf_options_2(document):
850 # reset the pdfusetitle tag, set quotes for bookmarksopenlevel"
851 k = find_token(document.header, "\\use_hyperref", 0)
852 i = find_token(document.header, "\\pdf_pdfusetitle", k)
854 del document.header[i]
855 i = find_token(document.header, "\\pdf_bookmarksopenlevel", k)
857 values = document.header[i].split()
858 values[1] = ' "' + values[1] + '"'
859 document.header[i] = ''.join(values)
862 def convert_htmlurl(document):
863 'Convert "htmlurl" to "href" insets for docbook'
864 if document.backend != "docbook":
868 i = find_token(document.body, "\\begin_inset CommandInset url", i)
871 document.body[i] = "\\begin_inset CommandInset href"
872 document.body[i + 1] = "LatexCommand href"
876 def convert_url(document):
877 'Convert url insets to url charstyles'
878 if document.backend == "docbook":
882 i = find_token(document.body, "\\begin_inset CommandInset url", i)
885 n = find_token(document.body, "name", i)
887 # place the URL name in typewriter before the new URL insert
888 # grab the name 'bla' from the e.g. the line 'name "bla"',
889 # therefore start with the 6th character
890 name = document.body[n][6:-1]
891 newname = [name + " "]
892 document.body[i:i] = newname
894 j = find_token(document.body, "target", i)
896 document.warning("Malformed LyX document: Can't find target for url inset")
899 target = document.body[j][8:-1]
900 k = find_token(document.body, "\\end_inset", j)
902 document.warning("Malformed LyX document: Can't find end of url inset")
905 newstuff = ["\\begin_inset Flex URL",
906 "status collapsed", "",
907 "\\begin_layout Standard",
912 document.body[i:k] = newstuff
915 def convert_ams_classes(document):
916 tc = document.textclass
917 if (tc != "amsart" and tc != "amsart-plain" and
918 tc != "amsart-seq" and tc != "amsbook"):
920 if tc == "amsart-plain":
921 document.textclass = "amsart"
922 document.set_textclass()
923 document.add_module("Theorems (Starred)")
925 if tc == "amsart-seq":
926 document.textclass = "amsart"
927 document.set_textclass()
928 document.add_module("Theorems (AMS)")
930 #Now we want to see if any of the environments in the extended theorems
931 #module were used in this document. If so, we'll add that module, too.
932 layouts = ["Criterion", "Algorithm", "Axiom", "Condition", "Note", \
933 "Notation", "Summary", "Acknowledgement", "Conclusion", "Fact", \
936 r = re.compile(r'^\\begin_layout (.*?)\*?\s*$')
939 i = find_token(document.body, "\\begin_layout", i)
942 m = r.match(document.body[i])
944 document.warning("Weirdly formed \\begin_layout at line %d of body!" % i)
948 if layouts.count(m) != 0:
949 document.add_module("Theorems (AMS-Extended)")
953 def revert_href(document):
954 'Reverts hyperlink insets (href) to url insets (url)'
957 i = find_token(document.body, "\\begin_inset CommandInset href", i)
960 document.body[i : i + 2] = \
961 ["\\begin_inset CommandInset url", "LatexCommand url"]
965 def convert_include(document):
966 'Converts include insets to new format.'
968 r = re.compile(r'\\begin_inset Include\s+\\([^{]+){([^}]*)}(?:\[(.*)\])?')
970 i = find_token(document.body, "\\begin_inset Include", i)
973 line = document.body[i]
974 previewline = document.body[i + 1]
977 document.warning("Unable to match line " + str(i) + " of body!")
983 insertion = ["\\begin_inset CommandInset include",
984 "LatexCommand " + cmd, previewline,
985 "filename \"" + fn + "\""]
988 insertion.append("lstparams " + '"' + opt + '"')
990 document.body[i : i + 2] = insertion
994 def revert_include(document):
995 'Reverts include insets to old format.'
997 r1 = re.compile('LatexCommand (.+)')
998 r2 = re.compile('filename (.+)')
999 r3 = re.compile('options (.*)')
1001 i = find_token(document.body, "\\begin_inset CommandInset include", i)
1004 previewline = document.body[i + 1]
1005 m = r1.match(document.body[i + 2])
1007 document.warning("Malformed LyX document: No LatexCommand line for `" +
1008 document.body[i] + "' on line " + str(i) + ".")
1012 m = r2.match(document.body[i + 3])
1014 document.warning("Malformed LyX document: No filename line for `" + \
1015 document.body[i] + "' on line " + str(i) + ".")
1021 if (cmd == "lstinputlisting"):
1022 m = r3.match(document.body[i + 4])
1024 options = m.group(1)
1026 newline = "\\begin_inset Include \\" + cmd + "{" + fn + "}"
1028 newline += ("[" + options + "]")
1029 insertion = [newline, previewline]
1030 document.body[i : i + numlines] = insertion
1034 def revert_albanian(document):
1035 "Set language Albanian to English"
1037 if document.language == "albanian":
1038 document.language = "english"
1039 i = find_token(document.header, "\\language", 0)
1041 document.header[i] = "\\language english"
1044 j = find_token(document.body, "\\lang albanian", j)
1047 document.body[j] = document.body[j].replace("\\lang albanian", "\\lang english")
1051 def revert_lowersorbian(document):
1052 "Set language lower Sorbian to English"
1054 if document.language == "lowersorbian":
1055 document.language = "english"
1056 i = find_token(document.header, "\\language", 0)
1058 document.header[i] = "\\language english"
1061 j = find_token(document.body, "\\lang lowersorbian", j)
1064 document.body[j] = document.body[j].replace("\\lang lowersorbian", "\\lang english")
1068 def revert_uppersorbian(document):
1069 "Set language uppersorbian to usorbian as this was used in LyX 1.5"
1071 if document.language == "uppersorbian":
1072 document.language = "usorbian"
1073 i = find_token(document.header, "\\language", 0)
1075 document.header[i] = "\\language usorbian"
1078 j = find_token(document.body, "\\lang uppersorbian", j)
1081 document.body[j] = document.body[j].replace("\\lang uppersorbian", "\\lang usorbian")
1085 def convert_usorbian(document):
1086 "Set language usorbian to uppersorbian"
1088 if document.language == "usorbian":
1089 document.language = "uppersorbian"
1090 i = find_token(document.header, "\\language", 0)
1092 document.header[i] = "\\language uppersorbian"
1095 j = find_token(document.body, "\\lang usorbian", j)
1098 document.body[j] = document.body[j].replace("\\lang usorbian", "\\lang uppersorbian")
1102 def revert_macro_optional_params(document):
1103 "Convert macro definitions with optional parameters into ERTs"
1104 # Stub to convert macro definitions with one or more optional parameters
1105 # into uninterpreted ERT insets
1108 def revert_hyperlinktype(document):
1109 'Reverts hyperlink type'
1113 i = find_token(document.body, "target", i)
1116 j = find_token(document.body, "type", i)
1120 del document.body[j]
1124 def revert_pagebreak(document):
1125 'Reverts pagebreak to ERT'
1128 i = find_token(document.body, "\\pagebreak", i)
1131 document.body[i] = '\\begin_inset ERT\nstatus collapsed\n\n' \
1132 '\\begin_layout Standard\n\n\n\\backslash\n' \
1133 'pagebreak{}\n\\end_layout\n\n\\end_inset\n\n'
1137 def revert_linebreak(document):
1138 'Reverts linebreak to ERT'
1141 i = find_token(document.body, "\\linebreak", i)
1144 document.body[i] = '\\begin_inset ERT\nstatus collapsed\n\n' \
1145 '\\begin_layout Standard\n\n\n\\backslash\n' \
1146 'linebreak{}\n\\end_layout\n\n\\end_inset\n\n'
1150 def revert_latin(document):
1151 "Set language Latin to English"
1153 if document.language == "latin":
1154 document.language = "english"
1155 i = find_token(document.header, "\\language", 0)
1157 document.header[i] = "\\language english"
1160 j = find_token(document.body, "\\lang latin", j)
1163 document.body[j] = document.body[j].replace("\\lang latin", "\\lang english")
1167 def revert_samin(document):
1168 "Set language North Sami to English"
1170 if document.language == "samin":
1171 document.language = "english"
1172 i = find_token(document.header, "\\language", 0)
1174 document.header[i] = "\\language english"
1177 j = find_token(document.body, "\\lang samin", j)
1180 document.body[j] = document.body[j].replace("\\lang samin", "\\lang english")
1184 def convert_serbocroatian(document):
1185 "Set language Serbocroatian to Croatian as this was really Croatian in LyX 1.5"
1187 if document.language == "serbocroatian":
1188 document.language = "croatian"
1189 i = find_token(document.header, "\\language", 0)
1191 document.header[i] = "\\language croatian"
1194 j = find_token(document.body, "\\lang serbocroatian", j)
1197 document.body[j] = document.body[j].replace("\\lang serbocroatian", "\\lang croatian")
1201 def convert_framed_notes(document):
1202 "Convert framed notes to boxes. "
1205 i = find_tokens(document.body, ["\\begin_inset Note Framed", "\\begin_inset Note Shaded"], i)
1209 document.body[i] = document.body[i].replace("\\begin_inset Note", "\\begin_inset Box")
1210 document.body.insert(i + 1, 'position "t"\nhor_pos "c"\nhas_inner_box 0\ninner_pos "t"\n' \
1211 'use_parbox 0\nwidth "100col%"\nspecial "none"\nheight "1in"\n' \
1212 'height_special "totalheight"')
1216 def convert_module_names(document):
1217 modulemap = { 'Braille' : 'braille', 'Endnote' : 'endnotes', 'Foot to End' : 'foottoend',\
1218 'Hanging' : 'hanging', 'Linguistics' : 'linguistics', 'Logical Markup' : 'logicalmkup', \
1219 'Theorems (AMS-Extended)' : 'theorems-ams-extended', 'Theorems (AMS)' : 'theorems-ams', \
1220 'Theorems (Order By Chapter)' : 'theorems-chap', 'Theorems (Order By Section)' : 'theorems-sec', \
1221 'Theorems (Starred)' : 'theorems-starred', 'Theorems' : 'theorems-std' }
1222 modlist = document.get_module_list()
1223 if len(modlist) == 0:
1227 if modulemap.has_key(mod):
1228 newmodlist.append(modulemap[mod])
1230 document.warning("Can't find module %s in the module map!" % mod)
1231 newmodlist.append(mod)
1232 document.set_module_list(newmodlist)
1235 def revert_module_names(document):
1236 modulemap = { 'braille' : 'Braille', 'endnotes' : 'Endnote', 'foottoend' : 'Foot to End',\
1237 'hanging' : 'Hanging', 'linguistics' : 'Linguistics', 'logicalmkup' : 'Logical Markup', \
1238 'theorems-ams-extended' : 'Theorems (AMS-Extended)', 'theorems-ams' : 'Theorems (AMS)', \
1239 'theorems-chap' : 'Theorems (Order By Chapter)', 'theorems-sec' : 'Theorems (Order By Section)', \
1240 'theorems-starred' : 'Theorems (Starred)', 'theorems-std' : 'Theorems'}
1241 modlist = document.get_module_list()
1242 if len(modlist) == 0:
1246 if modulemap.has_key(mod):
1247 newmodlist.append(modulemap[mod])
1249 document.warning("Can't find module %s in the module map!" % mod)
1250 newmodlist.append(mod)
1251 document.set_module_list(newmodlist)
1254 def revert_colsep(document):
1255 i = find_token(document.header, "\\columnsep", 0)
1258 colsepline = document.header[i]
1259 r = re.compile(r'\\columnsep (.*)')
1260 m = r.match(colsepline)
1262 document.warning("Malformed column separation line!")
1265 del document.header[i]
1266 #it seems to be safe to add the package even if it is already used
1267 pretext = ["\\usepackage{geometry}", "\\geometry{columnsep=" + colsep + "}"]
1269 add_to_preamble(document, pretext)
1272 def revert_framed_notes(document):
1273 "Revert framed boxes to notes. "
1276 i = find_tokens(document.body, ["\\begin_inset Box Framed", "\\begin_inset Box Shaded"], i)
1280 j = find_end_of_inset(document.body, i + 1)
1283 document.warning("Malformed LyX document: Could not find end of Box inset.")
1284 k = find_token(document.body, "status", i + 1, j)
1286 document.warning("Malformed LyX document: Missing `status' tag in Box inset.")
1288 status = document.body[k]
1289 l = find_default_layout(document, i + 1, j)
1291 document.warning("Malformed LyX document: Missing `\\begin_layout' in Box inset.")
1293 m = find_token(document.body, "\\end_layout", i + 1, j)
1295 document.warning("Malformed LyX document: Missing `\\end_layout' in Box inset.")
1297 ibox = find_token(document.body, "has_inner_box 1", i + 1, k)
1298 pbox = find_token(document.body, "use_parbox 1", i + 1, k)
1299 if ibox == -1 and pbox == -1:
1300 document.body[i] = document.body[i].replace("\\begin_inset Box", "\\begin_inset Note")
1301 del document.body[i+1:k]
1303 document.body[i] = document.body[i].replace("\\begin_inset Box Shaded", "\\begin_inset Box Frameless")
1304 document.body.insert(l + 1, "\\begin_inset Note Shaded\n" + status + "\n\\begin_layout Standard\n")
1305 document.body.insert(m + 1, "\\end_layout\n\\end_inset")
1309 def revert_slash(document):
1310 'Revert \\SpecialChar \\slash{} to ERT'
1311 for i in range(len(document.body)):
1312 document.body[i] = document.body[i].replace('\\SpecialChar \\slash{}', \
1313 '\\begin_inset ERT\nstatus collapsed\n\n' \
1314 '\\begin_layout Standard\n\n\n\\backslash\n' \
1315 'slash{}\n\\end_layout\n\n\\end_inset\n\n')
1318 def revert_nobreakdash(document):
1319 'Revert \\SpecialChar \\nobreakdash- to ERT'
1321 for i in range(len(document.body)):
1322 line = document.body[i]
1323 r = re.compile(r'\\SpecialChar \\nobreakdash-')
1327 document.body[i] = document.body[i].replace('\\SpecialChar \\nobreakdash-', \
1328 '\\begin_inset ERT\nstatus collapsed\n\n' \
1329 '\\begin_layout Standard\n\n\n\\backslash\n' \
1330 'nobreakdash-\n\\end_layout\n\n\\end_inset\n\n')
1333 j = find_token(document.header, "\\use_amsmath", 0)
1335 document.warning("Malformed LyX document: Missing '\\use_amsmath'.")
1337 document.header[j] = "\\use_amsmath 2"
1340 def revert_nocite_key(body, start, end):
1341 'key "..." -> \nocite{...}'
1342 for i in range(start, end):
1343 if (body[i][0:5] == 'key "'):
1344 body[i] = body[i].replace('key "', "\\backslash\nnocite{")
1345 body[i] = body[i].replace('"', "}")
1350 def revert_nocite(document):
1351 "Revert LatexCommand nocite to ERT"
1354 i = find_token(document.body, "\\begin_inset CommandInset citation", i)
1358 if (document.body[i] == "LatexCommand nocite"):
1359 j = find_end_of_inset(document.body, i + 1)
1361 #this should not happen
1362 document.warning("End of CommandInset citation not found in revert_nocite!")
1363 revert_nocite_key(document.body, i + 1, len(document.body))
1365 revert_nocite_key(document.body, i + 1, j)
1366 document.body[i-1] = "\\begin_inset ERT"
1367 document.body[i] = "status collapsed\n\n" \
1368 "\\begin_layout Standard"
1369 document.body.insert(j, "\\end_layout\n");
1373 def revert_btprintall(document):
1374 "Revert (non-bibtopic) btPrintAll option to ERT \nocite{*}"
1375 i = find_token(document.header, '\\use_bibtopic', 0)
1377 document.warning("Malformed lyx document: Missing '\\use_bibtopic'.")
1379 if get_value(document.header, '\\use_bibtopic', 0) == "false":
1381 while i < len(document.body):
1382 i = find_token(document.body, "\\begin_inset CommandInset bibtex", i)
1385 j = find_end_of_inset(document.body, i + 1)
1387 #this should not happen
1388 document.warning("End of CommandInset bibtex not found in revert_btprintall!")
1389 j = len(document.body)
1390 for k in range(i, j):
1391 if (document.body[k] == 'btprint "btPrintAll"'):
1392 del document.body[k]
1393 document.body.insert(i, "\\begin_inset ERT\n" \
1394 "status collapsed\n\n\\begin_layout Standard\n\n" \
1395 "\\backslash\nnocite{*}\n" \
1396 "\\end_layout\n\\end_inset\n")
1400 def revert_bahasam(document):
1401 "Set language Bahasa Malaysia to Bahasa Indonesia"
1403 if document.language == "bahasam":
1404 document.language = "bahasa"
1405 i = find_token(document.header, "\\language", 0)
1407 document.header[i] = "\\language bahasa"
1410 j = find_token(document.body, "\\lang bahasam", j)
1413 document.body[j] = document.body[j].replace("\\lang bahasam", "\\lang bahasa")
1417 def revert_interlingua(document):
1418 "Set language Interlingua to English"
1420 if document.language == "interlingua":
1421 document.language = "english"
1422 i = find_token(document.header, "\\language", 0)
1424 document.header[i] = "\\language english"
1427 j = find_token(document.body, "\\lang interlingua", j)
1430 document.body[j] = document.body[j].replace("\\lang interlingua", "\\lang english")
1434 def revert_serbianlatin(document):
1435 "Set language Serbian-Latin to Croatian"
1437 if document.language == "serbian-latin":
1438 document.language = "croatian"
1439 i = find_token(document.header, "\\language", 0)
1441 document.header[i] = "\\language croatian"
1444 j = find_token(document.body, "\\lang serbian-latin", j)
1447 document.body[j] = document.body[j].replace("\\lang serbian-latin", "\\lang croatian")
1451 def revert_rotfloat(document):
1452 " Revert sideways custom floats. "
1455 i = find_token(document.body, "\\begin_inset Float", i)
1458 line = document.body[i]
1459 r = re.compile(r'\\begin_inset Float (.*)$')
1461 floattype = m.group(1)
1462 if floattype == "figure" or floattype == "table":
1465 j = find_end_of_inset(document.body, i)
1467 document.warning("Malformed lyx document: Missing '\\end_inset'.")
1470 if get_value(document.body, 'sideways', i, j) != "false":
1471 l = find_default_layout(document, i + 1, j)
1473 document.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
1475 document.body[j] = '\\begin_layout Standard\n\\begin_inset ERT\nstatus collapsed\n\n' \
1476 '\\begin_layout Standard\n\n\n\\backslash\n' \
1477 'end{sideways' + floattype + '}\n\\end_layout\n\n\\end_inset\n'
1478 del document.body[i+1:l-1]
1479 document.body[i] = '\\begin_inset ERT\nstatus collapsed\n\n' \
1480 '\\begin_layout Standard\n\n\n\\backslash\n' \
1481 'begin{sideways' + floattype + '}\n\\end_layout\n\n\\end_inset\n\n\\end_layout\n\n'
1482 if floattype == "algorithm":
1483 add_to_preamble(document,
1484 ['% Commands inserted by lyx2lyx for sideways algorithm float',
1485 '\\usepackage{rotfloat}\n'
1486 '\\floatstyle{ruled}\n'
1487 '\\newfloat{algorithm}{tbp}{loa}\n'
1488 '\\floatname{algorithm}{Algorithm}\n'])
1490 document.warning("Cannot create preamble definition for custom float" + floattype + ".")
1496 def revert_widesideways(document):
1497 " Revert wide sideways floats. "
1500 i = find_token(document.body, '\\begin_inset Float', i)
1503 line = document.body[i]
1504 r = re.compile(r'\\begin_inset Float (.*)$')
1506 floattype = m.group(1)
1507 if floattype != "figure" and floattype != "table":
1510 j = find_end_of_inset(document.body, i)
1512 document.warning("Malformed lyx document: Missing '\\end_inset'.")
1515 if get_value(document.body, 'sideways', i, j) != "false":
1516 if get_value(document.body, 'wide', i, j) != "false":
1517 l = find_default_layout(document, i + 1, j)
1519 document.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
1521 document.body[j] = '\\begin_layout Standard\n\\begin_inset ERT\nstatus collapsed\n\n' \
1522 '\\begin_layout Standard\n\n\n\\backslash\n' \
1523 'end{sideways' + floattype + '*}\n\\end_layout\n\n\\end_inset\n'
1524 del document.body[i+1:l-1]
1525 document.body[i] = '\\begin_inset ERT\nstatus collapsed\n\n' \
1526 '\\begin_layout Standard\n\n\n\\backslash\n' \
1527 'begin{sideways' + floattype + '*}\n\\end_layout\n\n\\end_inset\n\n\\end_layout\n\n'
1528 add_to_preamble(document,
1529 ['\\usepackage{rotfloat}\n'])
1535 def revert_inset_embedding(document, type):
1536 ' Remove embed tag from certain type of insets'
1539 i = find_token(document.body, "\\begin_inset %s" % type, i)
1542 j = find_end_of_inset(document.body, i)
1544 document.warning("Malformed lyx document: Missing '\\end_inset'.")
1547 k = find_token(document.body, "\tembed", i, j)
1549 k = find_token(document.body, "embed", i, j)
1551 del document.body[k]
1555 def revert_external_embedding(document):
1556 ' Remove embed tag from external inset '
1557 revert_inset_embedding(document, 'External')
1560 def convert_subfig(document):
1561 " Convert subfigures to subfloats. "
1564 i = find_token(document.body, '\\begin_inset Graphics', i)
1567 j = find_end_of_inset(document.body, i)
1569 document.warning("Malformed lyx document: Missing '\\end_inset'.")
1572 k = find_token(document.body, '\tsubcaption', i, j)
1576 l = find_token(document.body, '\tsubcaptionText', i, j)
1577 caption = document.body[l][16:].strip('"')
1578 savestr = document.body[i]
1579 del document.body[l]
1580 del document.body[k]
1581 document.body[i] = '\\begin_inset Float figure\nwide false\nsideways false\n' \
1582 'status open\n\n\\begin_layout Plain Layout\n\\begin_inset Caption\n\n\\begin_layout Plain Layout\n' \
1583 + caption + '\n\\end_layout\n\n\\end_inset\n\n\\end_layout\n\n\\begin_layout Plain Layout\n' + savestr
1584 savestr = document.body[j]
1585 document.body[j] = '\n\\end_layout\n\n\\end_inset\n' + savestr
1588 def revert_subfig(document):
1589 " Revert subfloats. "
1592 i = find_token(document.body, '\\begin_inset Float', i)
1596 j = find_end_of_inset(document.body, i)
1598 document.warning("Malformed lyx document: Missing '\\end_inset' (float).")
1601 # look for embedded float (= subfloat)
1602 k = find_token(document.body, '\\begin_inset Float', i + 1, j)
1605 l = find_end_of_inset(document.body, k)
1607 document.warning("Malformed lyx document: Missing '\\end_inset' (embedded float).")
1610 m = find_default_layout(document, k + 1, l)
1612 cap = find_token(document.body, '\\begin_inset Caption', k + 1, l)
1616 capend = find_end_of_inset(document.body, cap)
1618 document.warning("Malformed lyx document: Missing '\\end_inset' (caption).")
1622 lbl = find_token(document.body, '\\begin_inset CommandInset label', cap, capend)
1624 lblend = find_end_of_inset(document.body, lbl + 1)
1626 document.warning("Malformed lyx document: Missing '\\end_inset' (label).")
1628 for line in document.body[lbl:lblend + 1]:
1629 if line.startswith('name '):
1630 label = line.split()[1].strip('"')
1637 opt = find_token(document.body, '\\begin_inset OptArg', cap, capend)
1639 optend = find_end_of_inset(document.body, opt)
1641 document.warning("Malformed lyx document: Missing '\\end_inset' (OptArg).")
1643 optc = find_default_layout(document, opt, optend)
1645 document.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
1647 optcend = find_end_of(document.body, optc, "\\begin_layout", "\\end_layout")
1648 for line in document.body[optc:optcend]:
1649 if not line.startswith('\\'):
1650 shortcap += line.strip()
1654 for line in document.body[cap:capend]:
1655 if line in document.body[lbl:lblend]:
1657 elif line in document.body[opt:optend]:
1659 elif not line.startswith('\\'):
1660 caption += line.strip()
1662 caption += "\\backslash\nlabel{" + label + "}"
1663 document.body[l] = '\\begin_layout Plain Layout\n\\begin_inset ERT\nstatus collapsed\n\n' \
1664 '\\begin_layout Plain Layout\n\n}\n\\end_layout\n\n\\end_inset\n\n\\end_layout\n\n\\begin_layout Plain Layout\n'
1665 del document.body[cap:capend+1]
1666 del document.body[k+1:m-1]
1667 insertion = '\\begin_inset ERT\nstatus collapsed\n\n' \
1668 '\\begin_layout Plain Layout\n\n\\backslash\n' \
1670 if len(shortcap) > 0:
1671 insertion = insertion + "[" + shortcap + "]"
1672 if len(caption) > 0:
1673 insertion = insertion + "[" + caption + "]"
1674 insertion = insertion + '{%\n\\end_layout\n\n\\end_inset\n\n\\end_layout\n'
1675 document.body[k] = insertion
1676 add_to_preamble(document,
1677 ['\\usepackage{subfig}\n'])
1681 def revert_wrapplacement(document):
1682 " Revert placement options wrap floats (wrapfig). "
1685 i = find_token(document.body, "lines", i)
1688 j = find_token(document.body, "placement", i+1)
1690 document.warning("Malformed LyX document: Couldn't find placement parameter of wrap float.")
1692 document.body[j] = document.body[j].replace("placement O", "placement o")
1693 document.body[j] = document.body[j].replace("placement I", "placement i")
1694 document.body[j] = document.body[j].replace("placement L", "placement l")
1695 document.body[j] = document.body[j].replace("placement R", "placement r")
1699 def remove_extra_embedded_files(document):
1700 " Remove \extra_embedded_files from buffer params "
1701 i = find_token(document.header, '\\extra_embedded_files', 0)
1704 document.header.pop(i)
1707 def convert_spaceinset(document):
1708 " Convert '\\InsetSpace foo' to '\\begin_inset Space foo\n\\end_inset' "
1709 for i in range(len(document.body)):
1710 if re.search(r'\InsetSpace', document.body[i]):
1711 document.body[i] = document.body[i].replace('\\InsetSpace', '\n\\begin_inset Space')
1712 document.body[i] = document.body[i] + "\n\\end_inset"
1715 def revert_spaceinset(document):
1716 " Revert '\\begin_inset Space foo\n\\end_inset' to '\\InsetSpace foo' "
1719 i = find_token(document.body, "\\begin_inset Space", i)
1722 j = find_end_of_inset(document.body, i)
1724 document.warning("Malformed LyX document: Could not find end of space inset.")
1726 document.body[i] = document.body[i].replace('\\begin_inset Space', '\\InsetSpace')
1727 del document.body[j]
1730 def convert_hfill(document):
1731 " Convert hfill to space inset "
1734 i = find_token(document.body, "\\hfill", i)
1737 document.body[i] = document.body[i].replace('\\hfill', '\n\\begin_inset Space \\hfill{}\n\\end_inset')
1740 def revert_hfills(document):
1741 ' Revert \\hfill commands '
1742 for i in range(len(document.body)):
1743 document.body[i] = document.body[i].replace('\\InsetSpace \\hfill{}', '\\hfill')
1744 document.body[i] = document.body[i].replace('\\InsetSpace \\dotfill{}', \
1745 '\\begin_inset ERT\nstatus collapsed\n\n' \
1746 '\\begin_layout Standard\n\n\n\\backslash\n' \
1747 'dotfill{}\n\\end_layout\n\n\\end_inset\n\n')
1748 document.body[i] = document.body[i].replace('\\InsetSpace \\hrulefill{}', \
1749 '\\begin_inset ERT\nstatus collapsed\n\n' \
1750 '\\begin_layout Standard\n\n\n\\backslash\n' \
1751 'hrulefill{}\n\\end_layout\n\n\\end_inset\n\n')
1754 def revert_hspace(document):
1755 ' Revert \\InsetSpace \\hspace{} to ERT '
1758 i = find_token(document.body, "\\InsetSpace \\hspace", i)
1761 length = get_value(document.body, '\\length', i+1)
1763 document.warning("Malformed lyx document: Missing '\\length' in Space inset.")
1765 del document.body[i+1]
1766 document.body[i] = document.body[i].replace('\\InsetSpace \\hspace*{}', \
1767 '\\begin_inset ERT\nstatus collapsed\n\n' \
1768 '\\begin_layout Standard\n\n\n\\backslash\n' \
1769 'hspace*{' + length + '}\n\\end_layout\n\n\\end_inset\n\n')
1770 document.body[i] = document.body[i].replace('\\InsetSpace \\hspace{}', \
1771 '\\begin_inset ERT\nstatus collapsed\n\n' \
1772 '\\begin_layout Standard\n\n\n\\backslash\n' \
1773 'hspace{' + length + '}\n\\end_layout\n\n\\end_inset\n\n')
1776 def revert_protected_hfill(document):
1777 ' Revert \\begin_inset Space \\hspace*{\\fill} to ERT '
1780 i = find_token(document.body, '\\begin_inset Space \\hspace*{\\fill}', i)
1783 j = find_end_of_inset(document.body, i)
1785 document.warning("Malformed LyX document: Could not find end of space inset.")
1787 del document.body[j]
1788 document.body[i] = document.body[i].replace('\\begin_inset Space \\hspace*{\\fill}', \
1789 '\\begin_inset ERT\nstatus collapsed\n\n' \
1790 '\\begin_layout Standard\n\n\n\\backslash\n' \
1791 'hspace*{\n\\backslash\nfill}\n\\end_layout\n\n\\end_inset\n\n')
1794 def revert_local_layout(document):
1795 ' Revert local layout headers.'
1798 i = find_token(document.header, "\\begin_local_layout", i)
1801 j = find_end_of(document.header, i, "\\begin_local_layout", "\\end_local_layout")
1803 # this should not happen
1805 document.header[i : j + 1] = []
1808 def convert_pagebreaks(document):
1809 ' Convert inline Newpage insets to new format '
1812 i = find_token(document.body, '\\newpage', i)
1815 document.body[i:i+1] = ['\\begin_inset Newpage newpage',
1819 i = find_token(document.body, '\\pagebreak', i)
1822 document.body[i:i+1] = ['\\begin_inset Newpage pagebreak',
1826 i = find_token(document.body, '\\clearpage', i)
1829 document.body[i:i+1] = ['\\begin_inset Newpage clearpage',
1833 i = find_token(document.body, '\\cleardoublepage', i)
1836 document.body[i:i+1] = ['\\begin_inset Newpage cleardoublepage',
1840 def revert_pagebreaks(document):
1841 ' Revert \\begin_inset Newpage to previous inline format '
1844 i = find_token(document.body, '\\begin_inset Newpage', i)
1847 j = find_end_of_inset(document.body, i)
1849 document.warning("Malformed LyX document: Could not find end of Newpage inset.")
1851 del document.body[j]
1852 document.body[i] = document.body[i].replace('\\begin_inset Newpage newpage', '\\newpage')
1853 document.body[i] = document.body[i].replace('\\begin_inset Newpage pagebreak', '\\pagebreak')
1854 document.body[i] = document.body[i].replace('\\begin_inset Newpage clearpage', '\\clearpage')
1855 document.body[i] = document.body[i].replace('\\begin_inset Newpage cleardoublepage', '\\cleardoublepage')
1858 def convert_linebreaks(document):
1859 ' Convert inline Newline insets to new format '
1862 i = find_token(document.body, '\\newline', i)
1865 document.body[i:i+1] = ['\\begin_inset Newline newline',
1869 i = find_token(document.body, '\\linebreak', i)
1872 document.body[i:i+1] = ['\\begin_inset Newline linebreak',
1876 def revert_linebreaks(document):
1877 ' Revert \\begin_inset Newline to previous inline format '
1880 i = find_token(document.body, '\\begin_inset Newline', i)
1883 j = find_end_of_inset(document.body, i)
1885 document.warning("Malformed LyX document: Could not find end of Newline inset.")
1887 del document.body[j]
1888 document.body[i] = document.body[i].replace('\\begin_inset Newline newline', '\\newline')
1889 document.body[i] = document.body[i].replace('\\begin_inset Newline linebreak', '\\linebreak')
1892 def convert_japanese_plain(document):
1893 ' Set language japanese-plain to japanese '
1895 if document.language == "japanese-plain":
1896 document.language = "japanese"
1897 i = find_token(document.header, "\\language", 0)
1899 document.header[i] = "\\language japanese"
1902 j = find_token(document.body, "\\lang japanese-plain", j)
1905 document.body[j] = document.body[j].replace("\\lang japanese-plain", "\\lang japanese")
1909 def revert_pdfpages(document):
1910 ' Revert pdfpages external inset to ERT '
1913 i = find_token(document.body, "\\begin_inset External", i)
1916 j = find_end_of_inset(document.body, i)
1918 document.warning("Malformed lyx document: Missing '\\end_inset'.")
1921 if get_value(document.body, 'template', i, j) == "PDFPages":
1922 filename = get_value(document.body, 'filename', i, j)
1924 r = re.compile(r'\textra PDFLaTeX \"(.*)\"$')
1925 for k in range(i, j):
1926 m = r.match(document.body[k])
1929 angle = get_value(document.body, 'rotateAngle', i, j)
1930 width = get_value(document.body, 'width', i, j)
1931 height = get_value(document.body, 'height', i, j)
1932 scale = get_value(document.body, 'scale', i, j)
1933 keepAspectRatio = find_token(document.body, "\tkeepAspectRatio", i, j)
1937 options += ",angle=" + angle
1939 options += "angle=" + angle
1942 options += ",width=" + convert_len(width)
1944 options += "width=" + convert_len(width)
1947 options += ",height=" + convert_len(height)
1949 options += "height=" + convert_len(height)
1952 options += ",scale=" + scale
1954 options += "scale=" + scale
1955 if keepAspectRatio != '':
1957 options += ",keepaspectratio"
1959 options += "keepaspectratio"
1961 options = '[' + options + ']'
1962 del document.body[i+1:j+1]
1963 document.body[i:i+1] = ['\\begin_inset ERT',
1966 '\\begin_layout Standard',
1969 'includepdf' + options + '{' + filename + '}',
1973 add_to_preamble(document, ['\\usepackage{pdfpages}\n'])
1979 def revert_mexican(document):
1980 "Set language Spanish(Mexico) to Spanish"
1982 if document.language == "spanish-mexico":
1983 document.language = "spanish"
1984 i = find_token(document.header, "\\language", 0)
1986 document.header[i] = "\\language spanish"
1989 j = find_token(document.body, "\\lang spanish-mexico", j)
1992 document.body[j] = document.body[j].replace("\\lang spanish-mexico", "\\lang spanish")
1996 def remove_embedding(document):
1997 ' Remove embed tag from all insets'
1998 revert_inset_embedding(document, 'Graphics')
1999 revert_inset_embedding(document, 'External')
2000 revert_inset_embedding(document, 'CommandInset include')
2001 revert_inset_embedding(document, 'CommandInset bibtex')
2008 supported_versions = ["1.6.0","1.6"]
2009 convert = [[277, [fix_wrong_tables]],
2010 [278, [close_begin_deeper]],
2011 [279, [long_charstyle_names]],
2012 [280, [axe_show_label]],
2015 [283, [convert_flex]],
2019 [287, [convert_wrapfig_options]],
2020 [288, [convert_inset_command]],
2021 [289, [convert_latexcommand_index]],
2026 [294, [convert_pdf_options]],
2027 [295, [convert_htmlurl, convert_url]],
2028 [296, [convert_include]],
2029 [297, [convert_usorbian]],
2035 [303, [convert_serbocroatian]],
2036 [304, [convert_framed_notes]],
2043 [311, [convert_ams_classes]],
2045 [313, [convert_module_names]],
2048 [316, [convert_subfig]],
2051 [319, [convert_spaceinset, convert_hfill]],
2053 [321, [convert_tablines]],
2055 [323, [convert_pagebreaks]],
2056 [324, [convert_linebreaks]],
2057 [325, [convert_japanese_plain]],
2060 [328, [remove_embedding, remove_extra_embedded_files, remove_inzip_options]],
2063 revert = [[327, []],
2064 [326, [revert_mexican]],
2065 [325, [revert_pdfpages]],
2067 [323, [revert_linebreaks]],
2068 [322, [revert_pagebreaks]],
2069 [321, [revert_local_layout]],
2070 [320, [revert_tablines]],
2071 [319, [revert_protected_hfill]],
2072 [318, [revert_spaceinset, revert_hfills, revert_hspace]],
2073 [317, [remove_extra_embedded_files]],
2074 [316, [revert_wrapplacement]],
2075 [315, [revert_subfig]],
2076 [314, [revert_colsep]],
2078 [312, [revert_module_names]],
2079 [311, [revert_rotfloat, revert_widesideways]],
2080 [310, [revert_external_embedding]],
2081 [309, [revert_btprintall]],
2082 [308, [revert_nocite]],
2083 [307, [revert_serbianlatin]],
2084 [306, [revert_slash, revert_nobreakdash]],
2085 [305, [revert_interlingua]],
2086 [304, [revert_bahasam]],
2087 [303, [revert_framed_notes]],
2089 [301, [revert_latin, revert_samin]],
2090 [300, [revert_linebreak]],
2091 [299, [revert_pagebreak]],
2092 [298, [revert_hyperlinktype]],
2093 [297, [revert_macro_optional_params]],
2094 [296, [revert_albanian, revert_lowersorbian, revert_uppersorbian]],
2095 [295, [revert_include]],
2096 [294, [revert_href]],
2097 [293, [revert_pdf_options_2]],
2098 [292, [revert_inset_info]],
2099 [291, [revert_japanese, revert_japanese_encoding]],
2100 [290, [revert_vietnamese]],
2101 [289, [revert_wraptable]],
2102 [288, [revert_latexcommand_index]],
2103 [287, [revert_inset_command]],
2104 [286, [revert_wrapfig_options]],
2105 [285, [revert_pdf_options]],
2106 [284, [remove_inzip_options]],
2108 [282, [revert_flex]],
2110 [280, [revert_begin_modules]],
2111 [279, [revert_show_label]],
2112 [278, [revert_long_charstyle_names]],
2118 if __name__ == "__main__":