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 ####################################################################
73 def get_option(document, m, option, default):
74 l = document.body[m].find(option)
77 val = document.body[m][l:].split('"')[1]
80 def remove_option(document, m, option):
81 l = document.body[m].find(option)
83 val = document.body[m][l:].split('"')[1]
84 document.body[m] = document.body[m][:l-1] + document.body[m][l+len(option + '="' + val + '"'):]
87 def set_option(document, m, option, value):
88 l = document.body[m].find(option)
90 oldval = document.body[m][l:].split('"')[1]
91 l = l + len(option + '="')
92 document.body[m] = document.body[m][:l] + value + document.body[m][l+len(oldval):]
94 document.body[m] = document.body[m][:-1] + ' ' + option + '="' + value + '">'
97 def convert_tablines(document):
100 i = find_token(document.body, "\\begin_inset Tabular", i)
102 # LyX 1.3 inserted an extra space between \begin_inset
103 # and Tabular so let us try if this is the case and fix it.
104 i = find_token(document.body, "\\begin_inset Tabular", i)
108 document.body[i] = "\\begin_inset Tabular"
109 j = find_end_of_inset(document.body, i + 1)
111 document.warning("Malformed LyX document: Could not find end of tabular.")
115 nrows = int(document.body[i+1].split('"')[3])
116 ncols = int(document.body[i+1].split('"')[5])
119 for k in range(ncols):
120 m = find_token(document.body, "<column", m)
121 left = get_option(document, m, 'leftline', 'false')
122 right = get_option(document, m, 'rightline', 'false')
123 col_info.append([left, right])
124 remove_option(document, m, 'leftline')
125 remove_option(document, m, 'rightline')
129 for k in range(nrows):
130 m = find_token(document.body, "<row", m)
131 top = get_option(document, m, 'topline', 'false')
132 bottom = get_option(document, m, 'bottomline', 'false')
133 row_info.append([top, bottom])
134 remove_option(document, m, 'topline')
135 remove_option(document, m, 'bottomline')
140 for k in range(nrows*ncols):
141 m = find_token(document.body, "<cell", m)
142 mc_info.append(get_option(document, m, 'multicolumn', '0'))
145 for l in range(nrows):
146 for k in range(ncols):
147 m = find_token(document.body, '<cell', m)
148 if mc_info[l*ncols + k] == '0':
149 r = set_option(document, m, 'topline', row_info[l][0])
150 r = set_option(document, m, 'bottomline', row_info[l][1])
151 r = set_option(document, m, 'leftline', col_info[k][0])
152 r = set_option(document, m, 'rightline', col_info[k][1])
153 elif mc_info[l*ncols + k] == '1':
155 while s < ncols and mc_info[l*ncols + s] == '2':
157 if s < ncols and mc_info[l*ncols + s] != '1':
158 r = set_option(document, m, 'rightline', col_info[k][1])
159 if k > 0 and mc_info[l*ncols + k - 1] == '0':
160 r = set_option(document, m, 'leftline', col_info[k][0])
165 def revert_tablines(document):
168 i = find_token(document.body, "\\begin_inset Tabular", i)
171 j = find_end_of_inset(document.body, i + 1)
173 document.warning("Malformed LyX document: Could not find end of tabular.")
177 nrows = int(document.body[i+1].split('"')[3])
178 ncols = int(document.body[i+1].split('"')[5])
181 for k in range(nrows*ncols):
182 m = find_token(document.body, "<cell", m)
183 top = get_option(document, m, 'topline', 'false')
184 bottom = get_option(document, m, 'bottomline', 'false')
185 left = get_option(document, m, 'leftline', 'false')
186 right = get_option(document, m, 'rightline', 'false')
187 lines.append([top, bottom, left, right])
192 for k in range(ncols):
193 m = find_token(document.body, "<column", m)
195 for l in range(nrows):
196 left = lines[k*ncols + k][2]
199 set_option(document, m, 'leftline', left)
201 for l in range(nrows):
202 right = lines[k*ncols + k][3]
205 set_option(document, m, 'rightline', right)
209 for k in range(nrows):
210 m = find_token(document.body, "<row", m)
212 for l in range(ncols):
213 top = lines[k*ncols + l][0]
216 set_option(document, m, 'topline', top)
218 for l in range(ncols):
219 bottom = lines[k*ncols + l][1]
220 if bottom == 'false':
222 set_option(document, m, 'bottomline', bottom)
228 def fix_wrong_tables(document):
231 i = find_token(document.body, "\\begin_inset Tabular", i)
234 j = find_end_of_inset(document.body, i + 1)
236 document.warning("Malformed LyX document: Could not find end of tabular.")
240 nrows = int(document.body[i+1].split('"')[3])
241 ncols = int(document.body[i+1].split('"')[5])
243 for l in range(nrows):
245 for k in range(ncols):
246 m = find_token(document.body, '<cell', m)
248 if document.body[m].find('multicolumn') != -1:
249 multicol_cont = int(document.body[m].split('"')[1])
251 if multicol_cont == 2 and (k == 0 or prev_multicolumn == 0):
252 document.body[m] = document.body[m][:5] + document.body[m][21:]
255 prev_multicolumn = multicol_cont
262 def close_begin_deeper(document):
266 i = find_tokens(document.body, ["\\begin_deeper", "\\end_deeper"], i)
271 if document.body[i][:13] == "\\begin_deeper":
278 document.body[-2:-2] = ['\\end_deeper' for i in range(depth)]
281 def long_charstyle_names(document):
284 i = find_token(document.body, "\\begin_inset CharStyle", i)
287 document.body[i] = document.body[i].replace("CharStyle ", "CharStyle CharStyle:")
290 def revert_long_charstyle_names(document):
293 i = find_token(document.body, "\\begin_inset CharStyle", i)
296 document.body[i] = document.body[i].replace("CharStyle CharStyle:", "CharStyle")
300 def axe_show_label(document):
303 i = find_token(document.body, "\\begin_inset CharStyle", i)
306 if document.body[i + 1].find("show_label") != -1:
307 if document.body[i + 1].find("true") != -1:
308 document.body[i + 1] = "status open"
309 del document.body[ i + 2]
311 if document.body[i + 1].find("false") != -1:
312 document.body[i + 1] = "status collapsed"
313 del document.body[ i + 2]
315 document.warning("Malformed LyX document: show_label neither false nor true.")
317 document.warning("Malformed LyX document: show_label missing in CharStyle.")
322 def revert_show_label(document):
325 i = find_token(document.body, "\\begin_inset CharStyle", i)
328 if document.body[i + 1].find("status open") != -1:
329 document.body.insert(i + 1, "show_label true")
331 if document.body[i + 1].find("status collapsed") != -1:
332 document.body.insert(i + 1, "show_label false")
334 document.warning("Malformed LyX document: no legal status line in CharStyle.")
337 def revert_begin_modules(document):
340 i = find_token(document.header, "\\begin_modules", i)
343 j = find_end_of(document.header, i, "\\begin_modules", "\\end_modules")
345 # this should not happen
347 document.header[i : j + 1] = []
349 def convert_flex(document):
350 "Convert CharStyle to Flex"
353 i = find_token(document.body, "\\begin_inset CharStyle", i)
356 document.body[i] = document.body[i].replace('\\begin_inset CharStyle', '\\begin_inset Flex')
358 def revert_flex(document):
359 "Convert Flex to CharStyle"
362 i = find_token(document.body, "\\begin_inset Flex", i)
365 document.body[i] = document.body[i].replace('\\begin_inset Flex', '\\begin_inset CharStyle')
368 # Discard PDF options for hyperref
369 def revert_pdf_options(document):
370 "Revert PDF options for hyperref."
371 # store the PDF options and delete the entries from the Lyx file
379 bookmarksnumbered = ""
381 bookmarksopenlevel = ""
389 i = find_token(document.header, "\\use_hyperref", i)
391 hyperref = get_value(document.header, "\\use_hyperref", i) == 'true'
392 del document.header[i]
393 i = find_token(document.header, "\\pdf_store_options", i)
395 del document.header[i]
396 i = find_token(document.header, "\\pdf_title", 0)
398 title = get_value_string(document.header, '\\pdf_title', 0, 0, True)
399 title = ' pdftitle={' + title + '}'
400 del document.header[i]
401 i = find_token(document.header, "\\pdf_author", 0)
403 author = get_value_string(document.header, '\\pdf_author', 0, 0, True)
405 author = ' pdfauthor={' + author + '}'
407 author = ',\n pdfauthor={' + author + '}'
408 del document.header[i]
409 i = find_token(document.header, "\\pdf_subject", 0)
411 subject = get_value_string(document.header, '\\pdf_subject', 0, 0, True)
412 if title == "" and author == "":
413 subject = ' pdfsubject={' + subject + '}'
415 subject = ',\n pdfsubject={' + subject + '}'
416 del document.header[i]
417 i = find_token(document.header, "\\pdf_keywords", 0)
419 keywords = get_value_string(document.header, '\\pdf_keywords', 0, 0, True)
420 if title == "" and author == "" and subject == "":
421 keywords = ' pdfkeywords={' + keywords + '}'
423 keywords = ',\n pdfkeywords={' + keywords + '}'
424 del document.header[i]
425 i = find_token(document.header, "\\pdf_bookmarks", 0)
427 bookmarks = get_value_string(document.header, '\\pdf_bookmarks', 0)
428 bookmarks = ',\n bookmarks=' + bookmarks
429 del document.header[i]
430 i = find_token(document.header, "\\pdf_bookmarksnumbered", i)
432 bookmarksnumbered = get_value_string(document.header, '\\pdf_bookmarksnumbered', 0)
433 bookmarksnumbered = ',\n bookmarksnumbered=' + bookmarksnumbered
434 del document.header[i]
435 i = find_token(document.header, "\\pdf_bookmarksopen", i)
437 bookmarksopen = get_value_string(document.header, '\\pdf_bookmarksopen', 0)
438 bookmarksopen = ',\n bookmarksopen=' + bookmarksopen
439 del document.header[i]
440 i = find_token(document.header, "\\pdf_bookmarksopenlevel", i)
442 bookmarksopenlevel = get_value_string(document.header, '\\pdf_bookmarksopenlevel', 0, 0, True)
443 bookmarksopenlevel = ',\n bookmarksopenlevel=' + bookmarksopenlevel
444 del document.header[i]
445 i = find_token(document.header, "\\pdf_breaklinks", i)
447 breaklinks = get_value_string(document.header, '\\pdf_breaklinks', 0)
448 breaklinks = ',\n breaklinks=' + breaklinks
449 del document.header[i]
450 i = find_token(document.header, "\\pdf_pdfborder", i)
452 pdfborder = get_value_string(document.header, '\\pdf_pdfborder', 0)
453 if pdfborder == 'true':
454 pdfborder = ',\n pdfborder={0 0 0}'
456 pdfborder = ',\n pdfborder={0 0 1}'
457 del document.header[i]
458 i = find_token(document.header, "\\pdf_colorlinks", i)
460 colorlinks = get_value_string(document.header, '\\pdf_colorlinks', 0)
461 colorlinks = ',\n colorlinks=' + colorlinks
462 del document.header[i]
463 i = find_token(document.header, "\\pdf_backref", i)
465 backref = get_value_string(document.header, '\\pdf_backref', 0)
466 backref = ',\n backref=' + backref
467 del document.header[i]
468 i = find_token(document.header, "\\pdf_pagebackref", i)
470 pagebackref = get_value_string(document.header, '\\pdf_pagebackref', 0)
471 pagebackref = ',\n pagebackref=' + pagebackref
472 del document.header[i]
473 i = find_token(document.header, "\\pdf_pagemode", 0)
475 pagemode = get_value_string(document.header, '\\pdf_pagemode', 0)
476 pagemode = ',\n pdfpagemode=' + pagemode
477 del document.header[i]
478 i = find_token(document.header, "\\pdf_quoted_options", 0)
480 otheroptions = get_value_string(document.header, '\\pdf_quoted_options', 0, 0, True)
481 if title == "" and author == "" and subject == "" and keywords == "":
482 otheroptions = ' ' + otheroptions
484 otheroptions = ',\n ' + otheroptions
485 del document.header[i]
487 # write to the preamble when hyperref was used
489 # preamble write preparations
490 # bookmark numbers are only output when they are turned on
491 if bookmarksopen == ',\n bookmarksopen=true':
492 bookmarksopen = bookmarksopen + bookmarksopenlevel
493 if bookmarks == ',\n bookmarks=true':
494 bookmarks = bookmarks + bookmarksnumbered + bookmarksopen
496 bookmarks = bookmarks
497 # hypersetup is only output when there are things to be set up
498 setupstart = '\\hypersetup{%\n'
500 if otheroptions == "" and title == "" and author == ""\
501 and subject == "" and keywords == "":
505 add_to_preamble(document,
506 ['% Commands inserted by lyx2lyx for PDF properties',
507 '\\usepackage[unicode=true'
526 def remove_inzip_options(document):
527 "Remove inzipName and embed options from the Graphics inset"
530 i = find_token(document.body, "\\begin_inset Graphics", i)
533 j = find_end_of_inset(document.body, i + 1)
536 document.warning("Malformed LyX document: Could not find end of graphics inset.")
537 # If there's a inzip param, just remove that
538 k = find_token(document.body, "\tinzipName", i + 1, j)
541 # embed option must follow the inzipName option
542 del document.body[k+1]
546 def convert_inset_command(document):
549 \begin_inset LatexCommand cmd
551 \begin_inset CommandInset InsetType
556 i = find_token(document.body, "\\begin_inset LatexCommand", i)
559 line = document.body[i]
560 r = re.compile(r'\\begin_inset LatexCommand (.*)$')
564 #this is adapted from factory.cpp
565 if cmdName[0:4].lower() == "cite":
566 insetName = "citation"
567 elif cmdName == "url" or cmdName == "htmlurl":
569 elif cmdName[-3:] == "ref":
571 elif cmdName == "tableofcontents":
573 elif cmdName == "printnomenclature":
574 insetName = "nomencl_print"
575 elif cmdName == "printindex":
576 insetName = "index_print"
579 insertion = ["\\begin_inset CommandInset " + insetName, "LatexCommand " + cmdName]
580 document.body[i : i+1] = insertion
583 def revert_inset_command(document):
586 \begin_inset CommandInset InsetType
589 \begin_inset LatexCommand cmd
590 Some insets may end up being converted to insets earlier versions of LyX
591 will not be able to recognize. Not sure what to do about that.
595 i = find_token(document.body, "\\begin_inset CommandInset", i)
598 nextline = document.body[i+1]
599 r = re.compile(r'LatexCommand\s+(.*)$')
600 m = r.match(nextline)
602 document.warning("Malformed LyX document: Missing LatexCommand in " + document.body[i] + ".")
605 insertion = ["\\begin_inset LatexCommand " + cmdName]
606 document.body[i : i+2] = insertion
609 def convert_wrapfig_options(document):
610 "Convert optional options for wrap floats (wrapfig)."
611 # adds the tokens "lines", "placement", and "overhang"
614 i = find_token(document.body, "\\begin_inset Wrap figure", i)
617 document.body.insert(i + 1, "lines 0")
618 j = find_token(document.body, "placement", i)
619 # placement can be already set or not; if not, set it
621 document.body.insert(i + 3, "overhang 0col%")
623 document.body.insert(i + 2, "placement o")
624 document.body.insert(i + 3, "overhang 0col%")
628 def revert_wrapfig_options(document):
629 "Revert optional options for wrap floats (wrapfig)."
632 i = find_token(document.body, "lines", i)
635 j = find_token(document.body, "overhang", i+1)
636 if j != i + 2 and j != -1:
637 document.warning("Malformed LyX document: Couldn't find overhang parameter of wrap float.")
641 del document.body[j-1]
645 def convert_latexcommand_index(document):
646 "Convert from LatexCommand form to collapsable form."
649 i = find_token(document.body, "\\begin_inset CommandInset index", i)
652 if document.body[i + 1] != "LatexCommand index": # Might also be index_print
654 fullcontent = document.body[i + 2][6:].strip('"')
655 document.body[i:i + 2] = ["\\begin_inset Index",
657 "\\begin_layout Standard"]
658 # Put here the conversions needed from LaTeX string to LyXText.
659 # Here we do a minimal conversion to prevent crashes and data loss.
660 # Manual patch-up may be needed.
661 # Umlauted characters (most common ones, can be extended):
662 fullcontent = fullcontent.replace(r'\\\"a', u'ä').replace(r'\\\"o', u'ö').replace(r'\\\"u', u'ü')
664 fullcontent = wrap_into_ert(fullcontent, r'\"', '"')
665 #fullcontent = fullcontent.replace(r'\"', '\n\\begin_inset ERT\nstatus collapsed\n\\begin_layout standard\n"\n\\end_layout\n\\end_inset\n')
667 r = re.compile('^(.*?)(\$.*?\$)(.*)')
672 f = m.group(2).replace('\\\\', '\\')
676 s = wrap_into_ert(s, r'\\', '\\backslash')
677 s = wrap_into_ert(s, '{', '{')
678 s = wrap_into_ert(s, '}', '}')
679 document.body.insert(i + 3, s)
681 document.body.insert(i + 3, "\\begin_inset Formula " + f)
682 document.body.insert(i + 4, "\\end_inset")
684 # Generic, \\ -> \backslash:
685 g = wrap_into_ert(g, r'\\', '\\backslash{}')
686 g = wrap_into_ert(g, '{', '{')
687 g = wrap_into_ert(g, '}', '}')
688 document.body.insert(i + 3, g)
689 document.body[i + 4] = "\\end_layout"
693 def revert_latexcommand_index(document):
694 "Revert from collapsable form to LatexCommand form."
697 i = find_token(document.body, "\\begin_inset Index", i)
700 j = find_end_of_inset(document.body, i + 1)
703 del document.body[j - 1]
704 del document.body[j - 2] # \end_layout
705 document.body[i] = "\\begin_inset CommandInset index"
706 document.body[i + 1] = "LatexCommand index"
707 # clean up multiline stuff
709 for k in range(i + 3, j - 2):
710 line = document.body[k]
711 if line.startswith("\\begin_inset ERT"):
713 if line.startswith("\\begin_inset Formula"):
715 if line.startswith("\\begin_layout Standard"):
717 if line.startswith("\\end_layout"):
719 if line.startswith("\\end_inset"):
721 if line.startswith("status collapsed"):
723 line = line.replace(u'ä', r'\\\"a').replace(u'ö', r'\\\"o').replace(u'ü', r'\\\"u')
724 content = content + line;
725 document.body[i + 3] = "name " + '"' + content + '"'
726 for k in range(i + 4, j - 2):
727 del document.body[i + 4]
728 document.body.insert(i + 4, "")
729 del document.body[i + 2] # \begin_layout standard
733 def revert_wraptable(document):
734 "Revert wrap table to wrap figure."
737 i = find_token(document.body, "\\begin_inset Wrap table", i)
740 document.body[i] = document.body[i].replace('\\begin_inset Wrap table', '\\begin_inset Wrap figure')
744 def revert_vietnamese(document):
745 "Set language Vietnamese to English"
746 # Set document language from Vietnamese to English
748 if document.language == "vietnamese":
749 document.language = "english"
750 i = find_token(document.header, "\\language", 0)
752 document.header[i] = "\\language english"
755 j = find_token(document.body, "\\lang vietnamese", j)
758 document.body[j] = document.body[j].replace("\\lang vietnamese", "\\lang english")
762 def revert_japanese(document):
763 "Set language japanese-plain to japanese"
764 # Set document language from japanese-plain to japanese
766 if document.language == "japanese-plain":
767 document.language = "japanese"
768 i = find_token(document.header, "\\language", 0)
770 document.header[i] = "\\language japanese"
773 j = find_token(document.body, "\\lang japanese-plain", j)
776 document.body[j] = document.body[j].replace("\\lang japanese-plain", "\\lang japanese")
780 def revert_japanese_encoding(document):
781 "Set input encoding form EUC-JP-plain to EUC-JP etc."
782 # Set input encoding form EUC-JP-plain to EUC-JP etc.
784 i = find_token(document.header, "\\inputencoding EUC-JP-plain", 0)
786 document.header[i] = "\\inputencoding EUC-JP"
788 j = find_token(document.header, "\\inputencoding JIS-plain", 0)
790 document.header[j] = "\\inputencoding JIS"
792 k = find_token(document.header, "\\inputencoding SJIS-plain", 0)
793 if k != -1: # convert to UTF8 since there is currently no SJIS encoding
794 document.header[k] = "\\inputencoding UTF8"
797 def revert_inset_info(document):
798 'Replace info inset with its content'
801 i = find_token(document.body, '\\begin_inset Info', i)
804 j = find_end_of_inset(document.body, i + 1)
807 document.warning("Malformed LyX document: Could not find end of Info inset.")
810 for k in range(i, j+1):
811 if document.body[k].startswith("arg"):
812 arg = document.body[k][3:].strip().strip('"')
813 if document.body[k].startswith("type"):
814 type = document.body[k][4:].strip().strip('"')
815 # I think there is a newline after \\end_inset, which should be removed.
816 if document.body[j + 1].strip() == "":
817 document.body[i : (j + 2)] = [type + ':' + arg]
819 document.body[i : (j + 1)] = [type + ':' + arg]
822 def convert_pdf_options(document):
823 # Set the pdfusetitle tag, delete the pdf_store_options,
824 # set quotes for bookmarksopenlevel"
825 has_hr = get_value(document.header, "\\use_hyperref", 0, default = "0")
827 k = find_token(document.header, "\\use_hyperref", 0)
828 document.header.insert(k + 1, "\\pdf_pdfusetitle true")
829 k = find_token(document.header, "\\pdf_store_options", 0)
831 del document.header[k]
832 i = find_token(document.header, "\\pdf_bookmarksopenlevel", k)
834 document.header[i] = document.header[i].replace('"', '')
837 def revert_pdf_options_2(document):
838 # reset the pdfusetitle tag, set quotes for bookmarksopenlevel"
839 k = find_token(document.header, "\\use_hyperref", 0)
840 i = find_token(document.header, "\\pdf_pdfusetitle", k)
842 del document.header[i]
843 i = find_token(document.header, "\\pdf_bookmarksopenlevel", k)
845 values = document.header[i].split()
846 values[1] = ' "' + values[1] + '"'
847 document.header[i] = ''.join(values)
850 def convert_htmlurl(document):
851 'Convert "htmlurl" to "href" insets for docbook'
852 if document.backend != "docbook":
856 i = find_token(document.body, "\\begin_inset CommandInset url", i)
859 document.body[i] = "\\begin_inset CommandInset href"
860 document.body[i + 1] = "LatexCommand href"
864 def convert_url(document):
865 'Convert url insets to url charstyles'
866 if document.backend == "docbook":
870 i = find_token(document.body, "\\begin_inset CommandInset url", i)
873 n = find_token(document.body, "name", i)
875 # place the URL name in typewriter before the new URL insert
876 # grab the name 'bla' from the e.g. the line 'name "bla"',
877 # therefore start with the 6th character
878 name = document.body[n][6:-1]
879 newname = [name + " "]
880 document.body[i:i] = newname
882 j = find_token(document.body, "target", i)
884 document.warning("Malformed LyX document: Can't find target for url inset")
887 target = document.body[j][8:-1]
888 k = find_token(document.body, "\\end_inset", j)
890 document.warning("Malformed LyX document: Can't find end of url inset")
893 newstuff = ["\\begin_inset Flex URL",
894 "status collapsed", "",
895 "\\begin_layout Standard",
900 document.body[i:k] = newstuff
903 def convert_ams_classes(document):
904 tc = document.textclass
905 if (tc != "amsart" and tc != "amsart-plain" and
906 tc != "amsart-seq" and tc != "amsbook"):
908 if tc == "amsart-plain":
909 document.textclass = "amsart"
910 document.set_textclass()
911 document.add_module("Theorems (Starred)")
913 if tc == "amsart-seq":
914 document.textclass = "amsart"
915 document.set_textclass()
916 document.add_module("Theorems (AMS)")
918 #Now we want to see if any of the environments in the extended theorems
919 #module were used in this document. If so, we'll add that module, too.
920 layouts = ["Criterion", "Algorithm", "Axiom", "Condition", "Note", \
921 "Notation", "Summary", "Acknowledgement", "Conclusion", "Fact", \
924 r = re.compile(r'^\\begin_layout (.*?)\*?\s*$')
927 i = find_token(document.body, "\\begin_layout", i)
930 m = r.match(document.body[i])
932 document.warning("Weirdly formed \\begin_layout at line %d of body!" % i)
936 if layouts.count(m) != 0:
937 document.add_module("Theorems (AMS-Extended)")
941 def revert_href(document):
942 'Reverts hyperlink insets (href) to url insets (url)'
945 i = find_token(document.body, "\\begin_inset CommandInset href", i)
948 document.body[i : i + 2] = \
949 ["\\begin_inset CommandInset url", "LatexCommand url"]
953 def convert_include(document):
954 'Converts include insets to new format.'
956 r = re.compile(r'\\begin_inset Include\s+\\([^{]+){([^}]*)}(?:\[(.*)\])?')
958 i = find_token(document.body, "\\begin_inset Include", i)
961 line = document.body[i]
962 previewline = document.body[i + 1]
965 document.warning("Unable to match line " + str(i) + " of body!")
971 insertion = ["\\begin_inset CommandInset include",
972 "LatexCommand " + cmd, previewline,
973 "filename \"" + fn + "\""]
976 insertion.append("lstparams " + '"' + opt + '"')
978 document.body[i : i + 2] = insertion
982 def revert_include(document):
983 'Reverts include insets to old format.'
985 r1 = re.compile('LatexCommand (.+)')
986 r2 = re.compile('filename (.+)')
987 r3 = re.compile('options (.*)')
989 i = find_token(document.body, "\\begin_inset CommandInset include", i)
992 previewline = document.body[i + 1]
993 m = r1.match(document.body[i + 2])
995 document.warning("Malformed LyX document: No LatexCommand line for `" +
996 document.body[i] + "' on line " + str(i) + ".")
1000 m = r2.match(document.body[i + 3])
1002 document.warning("Malformed LyX document: No filename line for `" + \
1003 document.body[i] + "' on line " + str(i) + ".")
1009 if (cmd == "lstinputlisting"):
1010 m = r3.match(document.body[i + 4])
1012 options = m.group(1)
1014 newline = "\\begin_inset Include \\" + cmd + "{" + fn + "}"
1016 newline += ("[" + options + "]")
1017 insertion = [newline, previewline]
1018 document.body[i : i + numlines] = insertion
1022 def revert_albanian(document):
1023 "Set language Albanian to English"
1025 if document.language == "albanian":
1026 document.language = "english"
1027 i = find_token(document.header, "\\language", 0)
1029 document.header[i] = "\\language english"
1032 j = find_token(document.body, "\\lang albanian", j)
1035 document.body[j] = document.body[j].replace("\\lang albanian", "\\lang english")
1039 def revert_lowersorbian(document):
1040 "Set language lower Sorbian to English"
1042 if document.language == "lowersorbian":
1043 document.language = "english"
1044 i = find_token(document.header, "\\language", 0)
1046 document.header[i] = "\\language english"
1049 j = find_token(document.body, "\\lang lowersorbian", j)
1052 document.body[j] = document.body[j].replace("\\lang lowersorbian", "\\lang english")
1056 def revert_uppersorbian(document):
1057 "Set language uppersorbian to usorbian as this was used in LyX 1.5"
1059 if document.language == "uppersorbian":
1060 document.language = "usorbian"
1061 i = find_token(document.header, "\\language", 0)
1063 document.header[i] = "\\language usorbian"
1066 j = find_token(document.body, "\\lang uppersorbian", j)
1069 document.body[j] = document.body[j].replace("\\lang uppersorbian", "\\lang usorbian")
1073 def convert_usorbian(document):
1074 "Set language usorbian to uppersorbian"
1076 if document.language == "usorbian":
1077 document.language = "uppersorbian"
1078 i = find_token(document.header, "\\language", 0)
1080 document.header[i] = "\\language uppersorbian"
1083 j = find_token(document.body, "\\lang usorbian", j)
1086 document.body[j] = document.body[j].replace("\\lang usorbian", "\\lang uppersorbian")
1090 def revert_macro_optional_params(document):
1091 "Convert macro definitions with optional parameters into ERTs"
1092 # Stub to convert macro definitions with one or more optional parameters
1093 # into uninterpreted ERT insets
1096 def revert_hyperlinktype(document):
1097 'Reverts hyperlink type'
1101 i = find_token(document.body, "target", i)
1104 j = find_token(document.body, "type", i)
1108 del document.body[j]
1112 def revert_pagebreak(document):
1113 'Reverts pagebreak to ERT'
1116 i = find_token(document.body, "\\pagebreak", i)
1119 document.body[i] = '\\begin_inset ERT\nstatus collapsed\n\n' \
1120 '\\begin_layout Standard\n\n\n\\backslash\n' \
1121 'pagebreak{}\n\\end_layout\n\n\\end_inset\n\n'
1125 def revert_linebreak(document):
1126 'Reverts linebreak to ERT'
1129 i = find_token(document.body, "\\linebreak", i)
1132 document.body[i] = '\\begin_inset ERT\nstatus collapsed\n\n' \
1133 '\\begin_layout Standard\n\n\n\\backslash\n' \
1134 'linebreak{}\n\\end_layout\n\n\\end_inset\n\n'
1138 def revert_latin(document):
1139 "Set language Latin to English"
1141 if document.language == "latin":
1142 document.language = "english"
1143 i = find_token(document.header, "\\language", 0)
1145 document.header[i] = "\\language english"
1148 j = find_token(document.body, "\\lang latin", j)
1151 document.body[j] = document.body[j].replace("\\lang latin", "\\lang english")
1155 def revert_samin(document):
1156 "Set language North Sami to English"
1158 if document.language == "samin":
1159 document.language = "english"
1160 i = find_token(document.header, "\\language", 0)
1162 document.header[i] = "\\language english"
1165 j = find_token(document.body, "\\lang samin", j)
1168 document.body[j] = document.body[j].replace("\\lang samin", "\\lang english")
1172 def convert_serbocroatian(document):
1173 "Set language Serbocroatian to Croatian as this was really Croatian in LyX 1.5"
1175 if document.language == "serbocroatian":
1176 document.language = "croatian"
1177 i = find_token(document.header, "\\language", 0)
1179 document.header[i] = "\\language croatian"
1182 j = find_token(document.body, "\\lang serbocroatian", j)
1185 document.body[j] = document.body[j].replace("\\lang serbocroatian", "\\lang croatian")
1189 def convert_framed_notes(document):
1190 "Convert framed notes to boxes. "
1193 i = find_tokens(document.body, ["\\begin_inset Note Framed", "\\begin_inset Note Shaded"], i)
1197 document.body[i] = document.body[i].replace("\\begin_inset Note", "\\begin_inset Box")
1198 document.body.insert(i + 1, 'position "t"\nhor_pos "c"\nhas_inner_box 0\ninner_pos "t"\n' \
1199 'use_parbox 0\nwidth "100col%"\nspecial "none"\nheight "1in"\n' \
1200 'height_special "totalheight"')
1204 def convert_module_names(document):
1205 modulemap = { 'Braille' : 'braille', 'Endnote' : 'endnotes', 'Foot to End' : 'foottoend',\
1206 'Hanging' : 'hanging', 'Linguistics' : 'linguistics', 'Logical Markup' : 'logicalmkup', \
1207 'Theorems (AMS-Extended)' : 'theorems-ams-extended', 'Theorems (AMS)' : 'theorems-ams', \
1208 'Theorems (Order By Chapter)' : 'theorems-chap', 'Theorems (Order By Section)' : 'theorems-sec', \
1209 'Theorems (Starred)' : 'theorems-starred', 'Theorems' : 'theorems-std' }
1210 modlist = document.get_module_list()
1211 if len(modlist) == 0:
1215 if modulemap.has_key(mod):
1216 newmodlist.append(modulemap[mod])
1218 document.warning("Can't find module %s in the module map!" % mod)
1219 newmodlist.append(mod)
1220 document.set_module_list(newmodlist)
1223 def revert_module_names(document):
1224 modulemap = { 'braille' : 'Braille', 'endnotes' : 'Endnote', 'foottoend' : 'Foot to End',\
1225 'hanging' : 'Hanging', 'linguistics' : 'Linguistics', 'logicalmkup' : 'Logical Markup', \
1226 'theorems-ams-extended' : 'Theorems (AMS-Extended)', 'theorems-ams' : 'Theorems (AMS)', \
1227 'theorems-chap' : 'Theorems (Order By Chapter)', 'theorems-sec' : 'Theorems (Order By Section)', \
1228 'theorems-starred' : 'Theorems (Starred)', 'theorems-std' : 'Theorems'}
1229 modlist = document.get_module_list()
1230 if len(modlist) == 0:
1234 if modulemap.has_key(mod):
1235 newmodlist.append(modulemap[mod])
1237 document.warning("Can't find module %s in the module map!" % mod)
1238 newmodlist.append(mod)
1239 document.set_module_list(newmodlist)
1242 def revert_colsep(document):
1243 i = find_token(document.header, "\\columnsep", 0)
1246 colsepline = document.header[i]
1247 r = re.compile(r'\\columnsep (.*)')
1248 m = r.match(colsepline)
1250 document.warning("Malformed column separation line!")
1253 del document.header[i]
1254 #it seems to be safe to add the package even if it is already used
1255 pretext = ["\\usepackage{geometry}", "\\geometry{columnsep=" + colsep + "}"]
1257 add_to_preamble(document, pretext)
1260 def revert_framed_notes(document):
1261 "Revert framed boxes to notes. "
1264 i = find_tokens(document.body, ["\\begin_inset Box Framed", "\\begin_inset Box Shaded"], i)
1268 j = find_end_of_inset(document.body, i + 1)
1271 document.warning("Malformed LyX document: Could not find end of Box inset.")
1272 k = find_token(document.body, "status", i + 1, j)
1274 document.warning("Malformed LyX document: Missing `status' tag in Box inset.")
1276 status = document.body[k]
1277 l = find_token(document.body, "\\begin_layout Standard", i + 1, j)
1279 document.warning("Malformed LyX document: Missing `\\begin_layout Standard' in Box inset.")
1281 m = find_token(document.body, "\\end_layout", i + 1, j)
1283 document.warning("Malformed LyX document: Missing `\\end_layout' in Box inset.")
1285 ibox = find_token(document.body, "has_inner_box 1", i + 1, k)
1286 pbox = find_token(document.body, "use_parbox 1", i + 1, k)
1287 if ibox == -1 and pbox == -1:
1288 document.body[i] = document.body[i].replace("\\begin_inset Box", "\\begin_inset Note")
1289 del document.body[i+1:k]
1291 document.body[i] = document.body[i].replace("\\begin_inset Box Shaded", "\\begin_inset Box Frameless")
1292 document.body.insert(l + 1, "\\begin_inset Note Shaded\n" + status + "\n\\begin_layout Standard\n")
1293 document.body.insert(m + 1, "\\end_layout\n\\end_inset")
1297 def revert_slash(document):
1298 'Revert \\SpecialChar \\slash{} to ERT'
1299 for i in range(len(document.body)):
1300 document.body[i] = document.body[i].replace('\\SpecialChar \\slash{}', \
1301 '\\begin_inset ERT\nstatus collapsed\n\n' \
1302 '\\begin_layout Standard\n\n\n\\backslash\n' \
1303 'slash{}\n\\end_layout\n\n\\end_inset\n\n')
1306 def revert_nobreakdash(document):
1307 'Revert \\SpecialChar \\nobreakdash- to ERT'
1309 for i in range(len(document.body)):
1310 line = document.body[i]
1311 r = re.compile(r'\\SpecialChar \\nobreakdash-')
1315 document.body[i] = document.body[i].replace('\\SpecialChar \\nobreakdash-', \
1316 '\\begin_inset ERT\nstatus collapsed\n\n' \
1317 '\\begin_layout Standard\n\n\n\\backslash\n' \
1318 'nobreakdash-\n\\end_layout\n\n\\end_inset\n\n')
1321 j = find_token(document.header, "\\use_amsmath", 0)
1323 document.warning("Malformed LyX document: Missing '\\use_amsmath'.")
1325 document.header[j] = "\\use_amsmath 2"
1328 def revert_nocite_key(body, start, end):
1329 'key "..." -> \nocite{...}'
1330 for i in range(start, end):
1331 if (body[i][0:5] == 'key "'):
1332 body[i] = body[i].replace('key "', "\\backslash\nnocite{")
1333 body[i] = body[i].replace('"', "}")
1338 def revert_nocite(document):
1339 "Revert LatexCommand nocite to ERT"
1342 i = find_token(document.body, "\\begin_inset CommandInset citation", i)
1346 if (document.body[i] == "LatexCommand nocite"):
1347 j = find_end_of_inset(document.body, i + 1)
1349 #this should not happen
1350 document.warning("End of CommandInset citation not found in revert_nocite!")
1351 revert_nocite_key(document.body, i + 1, len(document.body))
1353 revert_nocite_key(document.body, i + 1, j)
1354 document.body[i-1] = "\\begin_inset ERT"
1355 document.body[i] = "status collapsed\n\n" \
1356 "\\begin_layout Standard"
1357 document.body.insert(j, "\\end_layout\n");
1361 def revert_btprintall(document):
1362 "Revert (non-bibtopic) btPrintAll option to ERT \nocite{*}"
1363 i = find_token(document.header, '\\use_bibtopic', 0)
1365 document.warning("Malformed lyx document: Missing '\\use_bibtopic'.")
1367 if get_value(document.header, '\\use_bibtopic', 0) == "false":
1369 while i < len(document.body):
1370 i = find_token(document.body, "\\begin_inset CommandInset bibtex", i)
1373 j = find_end_of_inset(document.body, i + 1)
1375 #this should not happen
1376 document.warning("End of CommandInset bibtex not found in revert_btprintall!")
1377 j = len(document.body)
1378 for k in range(i, j):
1379 if (document.body[k] == 'btprint "btPrintAll"'):
1380 del document.body[k]
1381 document.body.insert(i, "\\begin_inset ERT\n" \
1382 "status collapsed\n\n\\begin_layout Standard\n\n" \
1383 "\\backslash\nnocite{*}\n" \
1384 "\\end_layout\n\\end_inset\n")
1388 def revert_bahasam(document):
1389 "Set language Bahasa Malaysia to Bahasa Indonesia"
1391 if document.language == "bahasam":
1392 document.language = "bahasa"
1393 i = find_token(document.header, "\\language", 0)
1395 document.header[i] = "\\language bahasa"
1398 j = find_token(document.body, "\\lang bahasam", j)
1401 document.body[j] = document.body[j].replace("\\lang bahasam", "\\lang bahasa")
1405 def revert_interlingua(document):
1406 "Set language Interlingua to English"
1408 if document.language == "interlingua":
1409 document.language = "english"
1410 i = find_token(document.header, "\\language", 0)
1412 document.header[i] = "\\language english"
1415 j = find_token(document.body, "\\lang interlingua", j)
1418 document.body[j] = document.body[j].replace("\\lang interlingua", "\\lang english")
1422 def revert_serbianlatin(document):
1423 "Set language Serbian-Latin to Croatian"
1425 if document.language == "serbian-latin":
1426 document.language = "croatian"
1427 i = find_token(document.header, "\\language", 0)
1429 document.header[i] = "\\language croatian"
1432 j = find_token(document.body, "\\lang serbian-latin", j)
1435 document.body[j] = document.body[j].replace("\\lang serbian-latin", "\\lang croatian")
1439 def revert_rotfloat(document):
1440 " Revert sideways custom floats. "
1443 i = find_token(document.body, "\\begin_inset Float", i)
1446 line = document.body[i]
1447 r = re.compile(r'\\begin_inset Float (.*)$')
1449 floattype = m.group(1)
1450 if floattype == "figure" or floattype == "table":
1453 j = find_end_of_inset(document.body, i)
1455 document.warning("Malformed lyx document: Missing '\\end_inset'.")
1458 if get_value(document.body, 'sideways', i, j) != "false":
1459 l = find_token(document.body, "\\begin_layout Standard", i + 1, j)
1461 document.warning("Malformed LyX document: Missing `\\begin_layout Standard' in Float inset.")
1463 document.body[j] = '\\begin_layout Standard\n\\begin_inset ERT\nstatus collapsed\n\n' \
1464 '\\begin_layout Standard\n\n\n\\backslash\n' \
1465 'end{sideways' + floattype + '}\n\\end_layout\n\n\\end_inset\n'
1466 del document.body[i+1:l-1]
1467 document.body[i] = '\\begin_inset ERT\nstatus collapsed\n\n' \
1468 '\\begin_layout Standard\n\n\n\\backslash\n' \
1469 'begin{sideways' + floattype + '}\n\\end_layout\n\n\\end_inset\n\n\\end_layout\n\n'
1470 if floattype == "algorithm":
1471 add_to_preamble(document,
1472 ['% Commands inserted by lyx2lyx for sideways algorithm float',
1473 '\\usepackage{rotfloat}\n'
1474 '\\floatstyle{ruled}\n'
1475 '\\newfloat{algorithm}{tbp}{loa}\n'
1476 '\\floatname{algorithm}{Algorithm}\n'])
1478 document.warning("Cannot create preamble definition for custom float" + floattype + ".")
1484 def revert_widesideways(document):
1485 " Revert wide sideways floats. "
1488 i = find_token(document.body, '\\begin_inset Float', i)
1491 line = document.body[i]
1492 r = re.compile(r'\\begin_inset Float (.*)$')
1494 floattype = m.group(1)
1495 if floattype != "figure" and floattype != "table":
1498 j = find_end_of_inset(document.body, i)
1500 document.warning("Malformed lyx document: Missing '\\end_inset'.")
1503 if get_value(document.body, 'sideways', i, j) != "false":
1504 if get_value(document.body, 'wide', i, j) != "false":
1505 l = find_token(document.body, "\\begin_layout Standard", i + 1, j)
1507 document.warning("Malformed LyX document: Missing `\\begin_layout Standard' in Float inset.")
1509 document.body[j] = '\\begin_layout Standard\n\\begin_inset ERT\nstatus collapsed\n\n' \
1510 '\\begin_layout Standard\n\n\n\\backslash\n' \
1511 'end{sideways' + floattype + '*}\n\\end_layout\n\n\\end_inset\n'
1512 del document.body[i+1:l-1]
1513 document.body[i] = '\\begin_inset ERT\nstatus collapsed\n\n' \
1514 '\\begin_layout Standard\n\n\n\\backslash\n' \
1515 'begin{sideways' + floattype + '*}\n\\end_layout\n\n\\end_inset\n\n\\end_layout\n\n'
1516 add_to_preamble(document,
1517 ['\\usepackage{rotfloat}\n'])
1523 def revert_external_embedding(document):
1524 ' Remove embed tag from external inset '
1527 i = find_token(document.body, "\\begin_inset External", i)
1530 j = find_end_of_inset(document.body, i)
1532 document.warning("Malformed lyx document: Missing '\\end_inset'.")
1535 k = find_token(document.body, "\tembed", i, j)
1537 del document.body[k]
1541 def convert_subfig(document):
1542 " Convert subfigures to subfloats. "
1545 i = find_token(document.body, '\\begin_inset Graphics', i)
1548 j = find_end_of_inset(document.body, i)
1550 document.warning("Malformed lyx document: Missing '\\end_inset'.")
1553 k = find_token(document.body, '\tsubcaption', i, j)
1557 l = find_token(document.body, '\tsubcaptionText', i, j)
1558 caption = document.body[l][16:].strip('"')
1559 savestr = document.body[i]
1560 del document.body[l]
1561 del document.body[k]
1562 document.body[i] = '\\begin_inset Float figure\nwide false\nsideways false\n' \
1563 'status open\n\n\\begin_layout PlainLayout\n\\begin_inset Caption\n\n\\begin_layout PlainLayout\n' \
1564 + caption + '\n\\end_layout\n\n\\end_inset\n\n\\end_layout\n\n\\begin_layout PlainLayout\n' + savestr
1565 savestr = document.body[j]
1566 document.body[j] = '\n\\end_layout\n\n\\end_inset\n' + savestr
1569 def revert_subfig(document):
1570 " Revert subfloats. "
1573 i = find_token(document.body, '\\begin_inset Float', i)
1577 j = find_end_of_inset(document.body, i)
1579 document.warning("Malformed lyx document: Missing '\\end_inset' (float).")
1582 # look for embedded float (= subfloat)
1583 k = find_token(document.body, '\\begin_inset Float', i + 1, j)
1586 l = find_end_of_inset(document.body, k)
1588 document.warning("Malformed lyx document: Missing '\\end_inset' (embedded float).")
1591 m = find_token(document.body, "\\begin_layout PlainLayout", k + 1, l)
1593 cap = find_token(document.body, '\\begin_inset Caption', k + 1, l)
1597 capend = find_end_of_inset(document.body, cap)
1599 document.warning("Malformed lyx document: Missing '\\end_inset' (caption).")
1603 lbl = find_token(document.body, '\\begin_inset CommandInset label', cap, capend)
1605 lblend = find_end_of_inset(document.body, lbl + 1)
1607 document.warning("Malformed lyx document: Missing '\\end_inset' (label).")
1609 for line in document.body[lbl:lblend + 1]:
1610 if line.startswith('name '):
1611 label = line.split()[1].strip('"')
1618 opt = find_token(document.body, '\\begin_inset OptArg', cap, capend)
1620 optend = find_end_of_inset(document.body, opt)
1622 document.warning("Malformed lyx document: Missing '\\end_inset' (OptArg).")
1624 optc = find_token(document.body, "\\begin_layout PlainLayout", opt, optend)
1626 document.warning("Malformed LyX document: Missing `\\begin_layout PlainLayout' in Float inset.")
1628 optcend = find_end_of(document.body, optc, "\\begin_layout", "\\end_layout")
1629 for line in document.body[optc:optcend]:
1630 if not line.startswith('\\'):
1631 shortcap += line.strip()
1635 for line in document.body[cap:capend]:
1636 if line in document.body[lbl:lblend]:
1638 elif line in document.body[opt:optend]:
1640 elif not line.startswith('\\'):
1641 caption += line.strip()
1643 caption += "\\backslash\nlabel{" + label + "}"
1644 document.body[l] = '\\begin_layout PlainLayout\n\\begin_inset ERT\nstatus collapsed\n\n' \
1645 '\\begin_layout PlainLayout\n\n}\n\\end_layout\n\n\\end_inset\n\n\\end_layout\n\n\\begin_layout PlainLayout\n'
1646 del document.body[cap:capend+1]
1647 del document.body[k+1:m-1]
1648 insertion = '\\begin_inset ERT\nstatus collapsed\n\n' \
1649 '\\begin_layout PlainLayout\n\n\\backslash\n' \
1651 if len(shortcap) > 0:
1652 insertion = insertion + "[" + shortcap + "]"
1653 if len(caption) > 0:
1654 insertion = insertion + "[" + caption + "]"
1655 insertion = insertion + '{%\n\\end_layout\n\n\\end_inset\n\n\\end_layout\n'
1656 document.body[k] = insertion
1657 add_to_preamble(document,
1658 ['\\usepackage{subfig}\n'])
1662 def revert_wrapplacement(document):
1663 " Revert placement options wrap floats (wrapfig). "
1666 i = find_token(document.body, "lines", i)
1669 j = find_token(document.body, "placement", i+1)
1671 document.warning("Malformed LyX document: Couldn't find placement parameter of wrap float.")
1673 document.body[j] = document.body[j].replace("placement O", "placement o")
1674 document.body[j] = document.body[j].replace("placement I", "placement i")
1675 document.body[j] = document.body[j].replace("placement L", "placement l")
1676 document.body[j] = document.body[j].replace("placement R", "placement r")
1680 def remove_extra_embedded_files(document):
1681 " Remove \extra_embedded_files from buffer params "
1682 i = find_token(document.header, '\\extra_embedded_files', 0)
1684 document.warning("Malformed lyx document: Missing '\\extra_embedded_files'.")
1686 document.header.pop(i)
1689 def convert_spaceinset(document):
1690 " Convert '\\InsetSpace foo' to '\\begin_inset Space foo\n\\end_inset' "
1691 for i in range(len(document.body)):
1692 if re.search(r'\InsetSpace', document.body[i]):
1693 document.body[i] = document.body[i].replace('\\InsetSpace', '\n\\begin_inset Space')
1694 document.body[i] = document.body[i] + "\n\\end_inset"
1697 def revert_spaceinset(document):
1698 " Revert '\\begin_inset Space foo\n\\end_inset' to '\\InsetSpace foo' "
1701 i = find_token(document.body, "\\begin_inset Space", i)
1704 j = find_end_of_inset(document.body, i)
1706 document.warning("Malformed LyX document: Could not find end of space inset.")
1708 document.body[i] = document.body[i].replace('\\begin_inset Space', '\\InsetSpace')
1709 del document.body[j]
1712 def convert_hfill(document):
1713 " Convert hfill to space inset "
1716 i = find_token(document.body, "\\hfill", i)
1719 document.body[i] = document.body[i].replace('\\hfill', '\n\\begin_inset Space \\hfill{}\n\\end_inset')
1722 def revert_hfills(document):
1723 ' Revert \\hfill commands '
1724 for i in range(len(document.body)):
1725 document.body[i] = document.body[i].replace('\\InsetSpace \\hfill{}', '\\hfill')
1726 document.body[i] = document.body[i].replace('\\InsetSpace \\dotfill{}', \
1727 '\\begin_inset ERT\nstatus collapsed\n\n' \
1728 '\\begin_layout Standard\n\n\n\\backslash\n' \
1729 'dotfill{}\n\\end_layout\n\n\\end_inset\n\n')
1730 document.body[i] = document.body[i].replace('\\InsetSpace \\hrulefill{}', \
1731 '\\begin_inset ERT\nstatus collapsed\n\n' \
1732 '\\begin_layout Standard\n\n\n\\backslash\n' \
1733 'hrulefill{}\n\\end_layout\n\n\\end_inset\n\n')
1736 def revert_hspace(document):
1737 ' Revert \\InsetSpace \\hspace{} to ERT '
1740 i = find_token(document.body, "\\InsetSpace \\hspace", i)
1743 length = get_value(document.body, '\\length', i+1)
1745 document.warning("Malformed lyx document: Missing '\\length' in Space inset.")
1747 del document.body[i+1]
1748 document.body[i] = document.body[i].replace('\\InsetSpace \\hspace*{}', \
1749 '\\begin_inset ERT\nstatus collapsed\n\n' \
1750 '\\begin_layout Standard\n\n\n\\backslash\n' \
1751 'hspace*{' + length + '}\n\\end_layout\n\n\\end_inset\n\n')
1752 document.body[i] = document.body[i].replace('\\InsetSpace \\hspace{}', \
1753 '\\begin_inset ERT\nstatus collapsed\n\n' \
1754 '\\begin_layout Standard\n\n\n\\backslash\n' \
1755 'hspace{' + length + '}\n\\end_layout\n\n\\end_inset\n\n')
1758 def revert_protected_hfill(document):
1759 ' Revert \\begin_inset Space \\hspace*{\\fill} to ERT '
1762 i = find_token(document.body, '\\begin_inset Space \\hspace*{\\fill}', i)
1765 j = find_end_of_inset(document.body, i)
1767 document.warning("Malformed LyX document: Could not find end of space inset.")
1769 del document.body[j]
1770 document.body[i] = document.body[i].replace('\\begin_inset Space \\hspace*{\\fill}', \
1771 '\\begin_inset ERT\nstatus collapsed\n\n' \
1772 '\\begin_layout Standard\n\n\n\\backslash\n' \
1773 'hspace*{\n\\backslash\nfill}\n\\end_layout\n\n\\end_inset\n\n')
1776 def revert_local_layout(document):
1777 ' Revert local layout headers.'
1780 i = find_token(document.header, "\\begin_local_layout", i)
1783 j = find_end_of(document.header, i, "\\begin_local_layout", "\\end_local_layout")
1785 # this should not happen
1787 document.header[i : j + 1] = []
1790 def convert_pagebreaks(document):
1791 ' Convert inline Newpage insets to new format '
1794 i = find_token(document.body, '\\newpage', i)
1797 document.body[i:i+1] = ['\\begin_inset Newpage newpage',
1801 i = find_token(document.body, '\\pagebreak', i)
1804 document.body[i:i+1] = ['\\begin_inset Newpage pagebreak',
1808 i = find_token(document.body, '\\clearpage', i)
1811 document.body[i:i+1] = ['\\begin_inset Newpage clearpage',
1815 i = find_token(document.body, '\\cleardoublepage', i)
1818 document.body[i:i+1] = ['\\begin_inset Newpage cleardoublepage',
1822 def revert_pagebreaks(document):
1823 ' Revert \\begin_inset Newpage to previous inline format '
1826 i = find_token(document.body, '\\begin_inset Newpage', i)
1829 j = find_end_of_inset(document.body, i)
1831 document.warning("Malformed LyX document: Could not find end of Newpage inset.")
1833 del document.body[j]
1834 document.body[i] = document.body[i].replace('\\begin_inset Newpage newpage', '\\newpage')
1835 document.body[i] = document.body[i].replace('\\begin_inset Newpage pagebreak', '\\pagebreak')
1836 document.body[i] = document.body[i].replace('\\begin_inset Newpage clearpage', '\\clearpage')
1837 document.body[i] = document.body[i].replace('\\begin_inset Newpage cleardoublepage', '\\cleardoublepage')
1840 def convert_linebreaks(document):
1841 ' Convert inline Newline insets to new format '
1844 i = find_token(document.body, '\\newline', i)
1847 document.body[i:i+1] = ['\\begin_inset Newline newline',
1851 i = find_token(document.body, '\\linebreak', i)
1854 document.body[i:i+1] = ['\\begin_inset Newline linebreak',
1858 def revert_linebreaks(document):
1859 ' Revert \\begin_inset Newline to previous inline format '
1862 i = find_token(document.body, '\\begin_inset Newline', i)
1865 j = find_end_of_inset(document.body, i)
1867 document.warning("Malformed LyX document: Could not find end of Newline inset.")
1869 del document.body[j]
1870 document.body[i] = document.body[i].replace('\\begin_inset Newline newline', '\\newline')
1871 document.body[i] = document.body[i].replace('\\begin_inset Newline linebreak', '\\linebreak')
1874 def convert_japanese_plain(document):
1875 ' Set language japanese-plain to japanese '
1877 if document.language == "japanese-plain":
1878 document.language = "japanese"
1879 i = find_token(document.header, "\\language", 0)
1881 document.header[i] = "\\language japanese"
1884 j = find_token(document.body, "\\lang japanese-plain", j)
1887 document.body[j] = document.body[j].replace("\\lang japanese-plain", "\\lang japanese")
1891 def revert_pdfpages(document):
1892 ' Revert pdfpages external inset to ERT '
1895 i = find_token(document.body, "\\begin_inset External", i)
1898 j = find_end_of_inset(document.body, i)
1900 document.warning("Malformed lyx document: Missing '\\end_inset'.")
1903 if get_value(document.body, 'template', i, j) == "PDFPages":
1904 filename = get_value(document.body, 'filename', i, j)
1906 r = re.compile(r'\textra PDFLaTeX \"(.*)\"$')
1907 for k in range(i, j):
1908 m = r.match(document.body[k])
1911 angle = get_value(document.body, 'rotateAngle', i, j)
1912 width = get_value(document.body, 'width', i, j)
1913 height = get_value(document.body, 'height', i, j)
1914 scale = get_value(document.body, 'scale', i, j)
1915 keepAspectRatio = find_token(document.body, "\tkeepAspectRatio", i, j)
1919 options += ",angle=" + angle
1921 options += "angle=" + angle
1924 options += ",width=" + convert_len(width)
1926 options += "width=" + convert_len(width)
1929 options += ",height=" + convert_len(height)
1931 options += "height=" + convert_len(height)
1934 options += ",scale=" + scale
1936 options += "scale=" + scale
1937 if keepAspectRatio != '':
1939 options += ",keepaspectratio"
1941 options += "keepaspectratio"
1943 options = '[' + options + ']'
1944 del document.body[i+1:j+1]
1945 document.body[i:i+1] = ['\\begin_inset ERT',
1948 '\\begin_layout Standard',
1951 'includepdf' + options + '{' + filename + '}',
1955 add_to_preamble(document, ['\\usepackage{pdfpages}\n'])
1965 supported_versions = ["1.6.0","1.6"]
1966 convert = [[277, [fix_wrong_tables]],
1967 [278, [close_begin_deeper]],
1968 [279, [long_charstyle_names]],
1969 [280, [axe_show_label]],
1972 [283, [convert_flex]],
1976 [287, [convert_wrapfig_options]],
1977 [288, [convert_inset_command]],
1978 [289, [convert_latexcommand_index]],
1983 [294, [convert_pdf_options]],
1984 [295, [convert_htmlurl, convert_url]],
1985 [296, [convert_include]],
1986 [297, [convert_usorbian]],
1992 [303, [convert_serbocroatian]],
1993 [304, [convert_framed_notes]],
2000 [311, [convert_ams_classes]],
2002 [313, [convert_module_names]],
2005 [316, [convert_subfig]],
2008 [319, [convert_spaceinset, convert_hfill]],
2010 [321, [convert_tablines]],
2012 [323, [convert_pagebreaks]],
2013 [324, [convert_linebreaks]],
2014 [325, [convert_japanese_plain]],
2018 revert = [[325, [revert_pdfpages]],
2020 [323, [revert_linebreaks]],
2021 [322, [revert_pagebreaks]],
2022 [321, [revert_local_layout]],
2023 [320, [revert_tablines]],
2024 [319, [revert_protected_hfill]],
2025 [318, [revert_spaceinset, revert_hfills, revert_hspace]],
2026 [317, [remove_extra_embedded_files]],
2027 [316, [revert_wrapplacement]],
2028 [315, [revert_subfig]],
2029 [314, [revert_colsep]],
2031 [312, [revert_module_names]],
2032 [311, [revert_rotfloat, revert_widesideways]],
2033 [310, [revert_external_embedding]],
2034 [309, [revert_btprintall]],
2035 [308, [revert_nocite]],
2036 [307, [revert_serbianlatin]],
2037 [306, [revert_slash, revert_nobreakdash]],
2038 [305, [revert_interlingua]],
2039 [304, [revert_bahasam]],
2040 [303, [revert_framed_notes]],
2042 [301, [revert_latin, revert_samin]],
2043 [300, [revert_linebreak]],
2044 [299, [revert_pagebreak]],
2045 [298, [revert_hyperlinktype]],
2046 [297, [revert_macro_optional_params]],
2047 [296, [revert_albanian, revert_lowersorbian, revert_uppersorbian]],
2048 [295, [revert_include]],
2049 [294, [revert_href]],
2050 [293, [revert_pdf_options_2]],
2051 [292, [revert_inset_info]],
2052 [291, [revert_japanese, revert_japanese_encoding]],
2053 [290, [revert_vietnamese]],
2054 [289, [revert_wraptable]],
2055 [288, [revert_latexcommand_index]],
2056 [287, [revert_inset_command]],
2057 [286, [revert_wrapfig_options]],
2058 [285, [revert_pdf_options]],
2059 [284, [remove_inzip_options]],
2061 [282, [revert_flex]],
2063 [280, [revert_begin_modules]],
2064 [279, [revert_show_label]],
2065 [278, [revert_long_charstyle_names]],
2071 if __name__ == "__main__":