1 # -*- coding: utf-8 -*-
2 # This file is part of lyx2lyx
3 # -*- coding: utf-8 -*-
4 # Copyright (C) 2011 The LyX team
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 2
9 # of the License, or (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 """ Convert files to the file format generated by lyx 2.1"""
26 # Uncomment only what you need to import, please.
28 from parser_tools import count_pars_in_inset, del_token, find_token, find_token_exact, \
29 find_token_backwards, find_end_of, find_end_of_inset, find_end_of_layout, \
30 find_end_of_sequence, find_re, get_option_value, get_containing_layout, \
31 get_value, get_quoted_value, set_option_value
33 #from parser_tools import find_token, find_end_of, find_tokens, \
34 #find_end_of_inset, find_end_of_layout, \
35 #is_in_inset, del_token, check_token
37 from lyx2lyx_tools import add_to_preamble, put_cmd_in_ert, get_ert
39 #from lyx2lyx_tools import insert_to_preamble, \
40 # lyx2latex, latex_length, revert_flex_inset, \
41 # revert_font_attrs, hex2ratio, str2bool
43 ####################################################################
44 # Private helper functions
46 #def remove_option(lines, m, option):
47 #''' removes option from line m. returns whether we did anything '''
48 #l = lines[m].find(option)
51 #val = lines[m][l:].split('"')[1]
52 #lines[m] = lines[m][:l - 1] + lines[m][l+len(option + '="' + val + '"'):]
56 ###############################################################################
58 ### Conversion and reversion routines
60 ###############################################################################
62 def revert_visible_space(document):
63 "Revert InsetSpace visible into its ERT counterpart"
66 i = find_token(document.body, "\\begin_inset space \\textvisiblespace{}", i)
69 end = find_end_of_inset(document.body, i)
70 subst = put_cmd_in_ert("\\textvisiblespace{}")
71 document.body[i:end + 1] = subst
74 def convert_undertilde(document):
75 " Load undertilde automatically "
76 i = find_token(document.header, "\\use_mathdots" , 0)
78 i = find_token(document.header, "\\use_mhchem" , 0)
80 i = find_token(document.header, "\\use_esint" , 0)
82 document.warning("Malformed LyX document: Can't find \\use_mathdots.")
84 j = find_token(document.preamble, "\\usepackage{undertilde}", 0)
86 document.header.insert(i + 1, "\\use_undertilde 0")
88 document.header.insert(i + 1, "\\use_undertilde 2")
89 del document.preamble[j]
92 def revert_undertilde(document):
93 " Load undertilde if used in the document "
94 undertilde = find_token(document.header, "\\use_undertilde" , 0)
96 document.warning("No \\use_undertilde line. Assuming auto.")
98 val = get_value(document.header, "\\use_undertilde", undertilde)
99 del document.header[undertilde]
103 document.warning("Invalid \\use_undertilde value: " + val + ". Assuming auto.")
104 # probably usedots has not been changed, but be safe.
112 add_to_preamble(document, ["\\usepackage{undertilde}"])
115 # so we are in the auto case. we want to load undertilde if \utilde is used.
118 i = find_token(document.body, '\\begin_inset Formula', i)
121 j = find_end_of_inset(document.body, i)
123 document.warning("Malformed LyX document: Can't find end of Formula inset at line " + str(i))
126 code = "\n".join(document.body[i:j])
127 if code.find("\\utilde") != -1:
128 add_to_preamble(document, ["\\@ifundefined{utilde}{\\usepackage{undertilde}}"])
133 def revert_negative_space(document):
134 "Revert InsetSpace negmedspace and negthickspace into its TeX-code counterpart"
139 i = find_token(document.body, "\\begin_inset space \\negmedspace{}", i)
141 j = find_token(document.body, "\\begin_inset space \\negthickspace{}", j)
143 # load amsmath in the preamble if not already loaded if we are at the end of checking
145 i = find_token(document.header, "\\use_amsmath 2", 0)
147 add_to_preamble(document, ["\\@ifundefined{negthickspace}{\\usepackage{amsmath}}"])
151 end = find_end_of_inset(document.body, i)
152 subst = put_cmd_in_ert("\\negmedspace{}")
153 document.body[i:end + 1] = subst
154 j = find_token(document.body, "\\begin_inset space \\negthickspace{}", j)
157 end = find_end_of_inset(document.body, j)
158 subst = put_cmd_in_ert("\\negthickspace{}")
159 document.body[j:end + 1] = subst
163 def revert_math_spaces(document):
164 "Revert formulas with protected custom space and protected hfills to TeX-code"
167 i = find_token(document.body, "\\begin_inset Formula", i)
170 j = document.body[i].find("\\hspace*")
172 end = find_end_of_inset(document.body, i)
173 subst = put_cmd_in_ert(document.body[i][21:])
174 document.body[i:end + 1] = subst
178 def convert_japanese_encodings(document):
179 " Rename the japanese encodings to names understood by platex "
181 "EUC-JP-pLaTeX": "euc",
183 "SJIS-pLaTeX": "sjis"
185 i = find_token(document.header, "\\inputencoding" , 0)
188 val = get_value(document.header, "\\inputencoding", i)
189 if val in jap_enc_dict.keys():
190 document.header[i] = "\\inputencoding %s" % jap_enc_dict[val]
193 def revert_japanese_encodings(document):
194 " Revert the japanese encodings name changes "
196 "euc": "EUC-JP-pLaTeX",
198 "sjis": "SJIS-pLaTeX"
200 i = find_token(document.header, "\\inputencoding" , 0)
203 val = get_value(document.header, "\\inputencoding", i)
204 if val in jap_enc_dict.keys():
205 document.header[i] = "\\inputencoding %s" % jap_enc_dict[val]
208 def revert_justification(document):
209 " Revert the \\justification buffer param"
210 if not del_token(document.header, '\\justification', 0):
211 document.warning("Malformed LyX document: Missing \\justification.")
214 def revert_australian(document):
215 "Set English language variants Australian and Newzealand to English"
217 if document.language == "australian" or document.language == "newzealand":
218 document.language = "english"
219 i = find_token(document.header, "\\language", 0)
221 document.header[i] = "\\language english"
224 j = find_token(document.body, "\\lang australian", j)
226 j = find_token(document.body, "\\lang newzealand", 0)
230 document.body[j] = document.body[j].replace("\\lang newzealand", "\\lang english")
232 document.body[j] = document.body[j].replace("\\lang australian", "\\lang english")
236 def convert_biblio_style(document):
237 "Add a sensible default for \\biblio_style based on the citation engine."
238 i = find_token(document.header, "\\cite_engine", 0)
240 engine = get_value(document.header, "\\cite_engine", i).split("_")[0]
241 style = {"basic": "plain", "natbib": "plainnat", "jurabib": "jurabib"}
242 document.header.insert(i + 1, "\\biblio_style " + style[engine])
245 def revert_biblio_style(document):
246 "BibTeX insets with default option use the style defined by \\biblio_style."
247 i = find_token(document.header, "\\biblio_style" , 0)
249 document.warning("No \\biblio_style line. Nothing to do.")
252 default_style = get_value(document.header, "\\biblio_style", i)
253 del document.header[i]
255 # We are looking for bibtex insets having the default option
258 i = find_token(document.body, "\\begin_inset CommandInset bibtex", i)
261 j = find_end_of_inset(document.body, i)
263 document.warning("Malformed LyX document: Can't find end of bibtex inset at line " + str(i))
266 k = find_token(document.body, "options", i, j)
268 options = get_quoted_value(document.body, "options", k)
269 if "default" in options.split(","):
270 document.body[k] = 'options "%s"' \
271 % options.replace("default", default_style)
275 def handle_longtable_captions(document, forward):
278 begin_table = find_token(document.body, '<lyxtabular version=', begin_table)
279 if begin_table == -1:
281 end_table = find_end_of(document.body, begin_table, '<lyxtabular', '</lyxtabular>')
283 document.warning("Malformed LyX document: Could not find end of table.")
286 fline = find_token(document.body, "<features", begin_table, end_table)
288 document.warning("Can't find features for inset at line " + str(begin_table))
291 p = document.body[fline].find("islongtable")
296 numrows = get_option_value(document.body[begin_table], "rows")
298 numrows = int(numrows)
300 document.warning(document.body[begin_table])
301 document.warning("Unable to determine rows!")
302 begin_table = end_table
304 begin_row = begin_table
305 for row in range(numrows):
306 begin_row = find_token(document.body, '<row', begin_row, end_table)
308 document.warning("Can't find row " + str(row + 1))
310 end_row = find_end_of(document.body, begin_row, '<row', '</row>')
312 document.warning("Can't find end of row " + str(row + 1))
315 if (get_option_value(document.body[begin_row], 'caption') == 'true' and
316 get_option_value(document.body[begin_row], 'endfirsthead') != 'true' and
317 get_option_value(document.body[begin_row], 'endhead') != 'true' and
318 get_option_value(document.body[begin_row], 'endfoot') != 'true' and
319 get_option_value(document.body[begin_row], 'endlastfoot') != 'true'):
320 document.body[begin_row] = set_option_value(document.body[begin_row], 'caption', 'true", endfirsthead="true')
321 elif get_option_value(document.body[begin_row], 'caption') == 'true':
322 if get_option_value(document.body[begin_row], 'endfirsthead') == 'true':
323 document.body[begin_row] = set_option_value(document.body[begin_row], 'endfirsthead', 'false')
324 if get_option_value(document.body[begin_row], 'endhead') == 'true':
325 document.body[begin_row] = set_option_value(document.body[begin_row], 'endhead', 'false')
326 if get_option_value(document.body[begin_row], 'endfoot') == 'true':
327 document.body[begin_row] = set_option_value(document.body[begin_row], 'endfoot', 'false')
328 if get_option_value(document.body[begin_row], 'endlastfoot') == 'true':
329 document.body[begin_row] = set_option_value(document.body[begin_row], 'endlastfoot', 'false')
331 # since there could be a tabular inside this one, we
332 # cannot jump to end.
336 def convert_longtable_captions(document):
337 "Add a firsthead flag to caption rows"
338 handle_longtable_captions(document, True)
341 def revert_longtable_captions(document):
342 "remove head/foot flag from caption rows"
343 handle_longtable_captions(document, False)
346 def convert_use_packages(document):
347 "use_xxx yyy => use_package xxx yyy"
348 packages = ["amsmath", "esint", "mathdots", "mhchem", "undertilde"]
350 i = find_token(document.header, "\\use_%s" % p, 0)
352 value = get_value(document.header, "\\use_%s" % p, i)
353 document.header[i] = "\\use_package %s %s" % (p, value)
356 def revert_use_packages(document):
357 "use_package xxx yyy => use_xxx yyy"
358 packages = ["amsmath", "esint", "mathdots", "mhchem", "undertilde"]
359 # the order is arbitrary for the use_package version, and not all packages need to be given.
360 # Ensure a complete list and correct order (important for older LyX versions and especially lyx2lyx)
363 regexp = re.compile(r'(\\use_package\s+%s)' % p)
364 i = find_re(document.header, regexp, j)
366 value = get_value(document.header, "\\use_package %s" % p, i).split()[1]
367 del document.header[i]
369 document.header.insert(j, "\\use_%s %s" % (p, value))
373 def convert_use_package(document, pkg):
374 i = find_token(document.header, "\\use_package", 0)
376 document.warning("Malformed LyX document: Can't find \\use_package.")
378 j = find_token(document.preamble, "\\usepackage{" + pkg + "}", 0)
380 document.header.insert(i + 1, "\\use_package " + pkg + " 0")
382 document.header.insert(i + 1, "\\use_package " + pkg + " 2")
383 del document.preamble[j]
386 def revert_use_package(document, pkg, commands, oldauto):
387 # oldauto defines how the version we are reverting to behaves:
388 # if it is true, the old version uses the package automatically.
389 # if it is false, the old version never uses the package.
390 regexp = re.compile(r'(\\use_package\s+%s)' % pkg)
391 i = find_re(document.header, regexp, 0)
392 value = "1" # default is auto
394 value = get_value(document.header, "\\use_package" , i).split()[1]
395 del document.header[i]
396 if value == "2": # on
397 add_to_preamble(document, ["\\usepackage{" + pkg + "}"])
398 elif value == "1" and not oldauto: # auto
401 i = find_token(document.body, '\\begin_inset Formula', i)
404 j = find_end_of_inset(document.body, i)
406 document.warning("Malformed LyX document: Can't find end of Formula inset at line " + str(i))
409 code = "\n".join(document.body[i:j])
411 if code.find("\\%s" % c) != -1:
412 add_to_preamble(document, ["\\usepackage{" + pkg + "}"])
417 def convert_use_mathtools(document):
418 "insert use_package mathtools"
419 convert_use_package(document, "mathtools")
422 def revert_use_mathtools(document):
423 "remove use_package mathtools"
424 commands = ["mathclap", "mathllap", "mathrlap", \
425 "lgathered", "rgathered", "vcentcolon", "dblcolon", \
426 "coloneqq", "Coloneqq", "coloneq", "Coloneq", "eqqcolon", \
427 "Eqqcolon", "eqcolon", "Eqcolon", "colonapprox", \
428 "Colonapprox", "colonsim", "Colonsim"]
429 revert_use_package(document, "mathtools", commands, False)
432 def convert_use_stmaryrd(document):
433 "insert use_package stmaryrd"
434 convert_use_package(document, "stmaryrd")
437 def revert_use_stmaryrd(document):
438 "remove use_package stmaryrd"
439 # commands provided by stmaryrd.sty but LyX uses other packages:
440 # boxdot lightning, bigtriangledown, bigtriangleup
441 commands = ["shortleftarrow", "shortrightarrow", "shortuparrow", \
442 "shortdownarrow", "Yup", "Ydown", "Yleft", "Yright", \
443 "varcurlyvee", "varcurlywedge", "minuso", "baro", \
444 "sslash", "bbslash", "moo", "varotimes", "varoast", \
445 "varobar", "varodot", "varoslash", "varobslash", \
446 "varocircle", "varoplus", "varominus", "boxast", \
447 "boxbar", "boxslash", "boxbslash", "boxcircle", \
448 "boxbox", "boxempty", "merge", "vartimes", \
449 "fatsemi", "sswarrow", "ssearrow", "curlywedgeuparrow", \
450 "curlywedgedownarrow", "fatslash", "fatbslash", "lbag", \
451 "rbag", "varbigcirc", "leftrightarroweq", \
452 "curlyveedownarrow", "curlyveeuparrow", "nnwarrow", \
453 "nnearrow", "leftslice", "rightslice", "varolessthan", \
454 "varogreaterthan", "varovee", "varowedge", "talloblong", \
455 "interleave", "obar", "obslash", "olessthan", \
456 "ogreaterthan", "ovee", "owedge", "oblong", "inplus", \
457 "niplus", "nplus", "subsetplus", "supsetplus", \
458 "subsetpluseq", "supsetpluseq", "Lbag", "Rbag", \
459 "llbracket", "rrbracket", "llparenthesis", \
460 "rrparenthesis", "binampersand", "bindnasrepma", \
461 "trianglelefteqslant", "trianglerighteqslant", \
462 "ntrianglelefteqslant", "ntrianglerighteqslant", \
463 "llfloor", "rrfloor", "llceil", "rrceil", "arrownot", \
464 "Arrownot", "Mapstochar", "mapsfromchar", "Mapsfromchar", \
465 "leftrightarrowtriangle", "leftarrowtriangle", \
466 "rightarrowtriangle", \
467 "bigcurlyvee", "bigcurlywedge", "bigsqcap", "bigbox", \
468 "bigparallel", "biginterleave", "bignplus", \
469 "varcopyright", "longarrownot", "Longarrownot", \
470 "Mapsto", "mapsfrom", "Mapsfrom" "Longmapsto", \
471 "longmapsfrom", "Longmapsfrom"]
472 revert_use_package(document, "stmaryrd", commands, False)
476 def convert_use_stackrel(document):
477 "insert use_package stackrel"
478 convert_use_package(document, "stackrel")
481 def revert_use_stackrel(document):
482 "remove use_package stackrel"
483 commands = ["stackrel"]
484 revert_use_package(document, "stackrel", commands, False)
487 def convert_cite_engine_type(document):
488 "Determine the \\cite_engine_type from the citation engine."
489 i = find_token(document.header, "\\cite_engine", 0)
492 engine = get_value(document.header, "\\cite_engine", i)
494 engine, type = engine.split("_")
496 type = {"basic": "numerical", "jurabib": "authoryear"}[engine]
497 document.header[i] = "\\cite_engine " + engine
498 document.header.insert(i + 1, "\\cite_engine_type " + type)
501 def revert_cite_engine_type(document):
502 "Natbib had the type appended with an underscore."
503 engine_type = "numerical"
504 i = find_token(document.header, "\\cite_engine_type" , 0)
506 document.warning("No \\cite_engine_type line. Assuming numerical.")
508 engine_type = get_value(document.header, "\\cite_engine_type", i)
509 del document.header[i]
511 # We are looking for the natbib citation engine
512 i = find_token(document.header, "\\cite_engine natbib", 0)
515 document.header[i] = "\\cite_engine natbib_" + engine_type
518 # this is the same, as revert_use_cancel() except for the default
519 def revert_cancel(document):
520 "add cancel to the preamble if necessary"
521 commands = ["cancelto", "cancel", "bcancel", "xcancel"]
522 revert_use_package(document, "cancel", commands, False)
525 def revert_verbatim(document):
526 " Revert verbatim einvironments completely to TeX-code. "
529 subst_end = ['\end_layout', '', '\\begin_layout Plain Layout',
531 '\\begin_layout Plain Layout', '', '',
534 '\\end_layout', '', '\\end_inset',
535 '', '', '\\end_layout']
536 subst_begin = ['\\begin_layout Standard', '\\noindent',
537 '\\begin_inset ERT', 'status collapsed', '',
538 '\\begin_layout Plain Layout', '', '', '\\backslash',
540 '\\end_layout', '', '\\begin_layout Plain Layout', '']
542 i = find_token(document.body, "\\begin_layout Verbatim", i)
545 j = find_end_of_layout(document.body, i)
547 document.warning("Malformed lyx document: Can't find end of Verbatim layout")
550 # delete all line breaks insets (there are no other insets)
553 n = find_token(document.body, "\\begin_inset Newline newline", l)
555 n = find_token(document.body, "\\begin_inset Newline linebreak", l)
558 m = find_end_of_inset(document.body, n)
559 del(document.body[m:m+1])
560 document.body[n:n+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
563 # consecutive verbatim environments need to be connected
564 k = find_token(document.body, "\\begin_layout Verbatim", j)
565 if k == j + 2 and consecutive == False:
567 document.body[j:j+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
568 document.body[i:i+1] = subst_begin
570 if k == j + 2 and consecutive == True:
571 document.body[j:j+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
572 del(document.body[i:i+1])
574 if k != j + 2 and consecutive == True:
575 document.body[j:j+1] = subst_end
576 # the next paragraph must not be indented
577 document.body[j+19:j+19] = ['\\noindent']
578 del(document.body[i:i+1])
582 document.body[j:j+1] = subst_end
583 # the next paragraph must not be indented
584 document.body[j+19:j+19] = ['\\noindent']
585 document.body[i:i+1] = subst_begin
588 def revert_tipa(document):
589 " Revert native TIPA insets to mathed or ERT. "
592 i = find_token(document.body, "\\begin_inset IPA", i)
595 j = find_end_of_inset(document.body, i)
597 document.warning("Malformed lyx document: Can't find end of IPA inset")
601 n = find_token(document.body, "\\begin_layout", i, j)
603 document.warning("Malformed lyx document: IPA inset has no embedded layout")
606 m = find_end_of_layout(document.body, n)
608 document.warning("Malformed lyx document: Can't find end of embedded layout")
611 content = document.body[n+1:m]
612 p = find_token(document.body, "\\begin_layout", m, j)
613 if p != -1 or len(content) > 1:
615 content = document.body[i+1:j]
617 # IPA insets with multiple pars need to be wrapped by \begin{IPA}...\end{IPA}
618 document.body[i:j+1] = ['\\end_layout', '', '\\begin_layout Standard'] + put_cmd_in_ert("\\begin{IPA}") + ['\\end_layout'] + content + ['\\begin_layout Standard'] + put_cmd_in_ert("\\end{IPA}")
619 add_to_preamble(document, ["\\usepackage{tipa,tipx}"])
621 # single-par IPA insets can be reverted to mathed
622 document.body[i:j+1] = ["\\begin_inset Formula $\\text{\\textipa{" + content[0] + "}}$", "\\end_inset"]
626 def revert_cell_rotation(document):
627 "Revert cell rotations to TeX-code"
629 load_rotating = False
633 # first, let's find out if we need to do anything
634 i = find_token(document.body, '<cell ', i)
637 j = document.body[i].find('rotate="')
639 k = document.body[i].find('"', j + 8)
640 value = document.body[i][j + 8 : k]
642 rgx = re.compile(r' rotate="[^"]+?"')
643 # remove rotate option
644 document.body[i] = rgx.sub('', document.body[i])
646 rgx = re.compile(r' rotate="[^"]+?"')
647 document.body[i] = rgx.sub('rotate="true"', document.body[i])
649 rgx = re.compile(r' rotate="[^"]+?"')
651 # remove rotate option
652 document.body[i] = rgx.sub('', document.body[i])
654 document.body[i + 5 : i + 5] = \
655 put_cmd_in_ert("\\end{turn}")
656 document.body[i + 4 : i + 4] = \
657 put_cmd_in_ert("\\begin{turn}{" + value + "}")
663 add_to_preamble(document, ["\\@ifundefined{turnbox}{\usepackage{rotating}}{}"])
666 def convert_cell_rotation(document):
667 'Convert cell rotation statements from "true" to "90"'
671 # first, let's find out if we need to do anything
672 i = find_token(document.body, '<cell ', i)
675 j = document.body[i].find('rotate="true"')
677 rgx = re.compile(r'rotate="[^"]+?"')
678 # convert "true" to "90"
679 document.body[i] = rgx.sub('rotate="90"', document.body[i])
684 def revert_table_rotation(document):
685 "Revert table rotations to TeX-code"
687 load_rotating = False
691 # first, let's find out if we need to do anything
692 i = find_token(document.body, '<features ', i)
695 j = document.body[i].find('rotate="')
697 end_table = find_token(document.body, '</lyxtabular>', j)
698 k = document.body[i].find('"', j + 8)
699 value = document.body[i][j + 8 : k]
701 rgx = re.compile(r' rotate="[^"]+?"')
702 # remove rotate option
703 document.body[i] = rgx.sub('', document.body[i])
705 rgx = re.compile(r'rotate="[^"]+?"')
706 document.body[i] = rgx.sub('rotate="true"', document.body[i])
708 rgx = re.compile(r' rotate="[^"]+?"')
710 # remove rotate option
711 document.body[i] = rgx.sub('', document.body[i])
713 document.body[end_table + 3 : end_table + 3] = \
714 put_cmd_in_ert("\\end{turn}")
715 document.body[i - 2 : i - 2] = \
716 put_cmd_in_ert("\\begin{turn}{" + value + "}")
722 add_to_preamble(document, ["\\@ifundefined{turnbox}{\usepackage{rotating}}{}"])
725 def convert_table_rotation(document):
726 'Convert table rotation statements from "true" to "90"'
730 # first, let's find out if we need to do anything
731 i = find_token(document.body, '<features ', i)
734 j = document.body[i].find('rotate="true"')
736 rgx = re.compile(r'rotate="[^"]+?"')
737 # convert "true" to "90"
738 document.body[i] = rgx.sub('rotate="90"', document.body[i])
743 def convert_listoflistings(document):
744 'Convert ERT \lstlistoflistings to TOC lstlistoflistings inset'
745 # We can support roundtrip because the command is so simple
748 i = find_token(document.body, "\\begin_inset ERT", i)
751 j = find_end_of_inset(document.body, i)
753 document.warning("Malformed lyx document: Can't find end of ERT inset")
756 ert = get_ert(document.body, i)
757 if ert == "\\lstlistoflistings{}":
758 document.body[i:j] = ["\\begin_inset CommandInset toc", "LatexCommand lstlistoflistings", ""]
764 def revert_listoflistings(document):
765 'Convert TOC lstlistoflistings inset to ERT lstlistoflistings'
768 i = find_token(document.body, "\\begin_inset CommandInset toc", i)
771 if document.body[i+1] == "LatexCommand lstlistoflistings":
772 j = find_end_of_inset(document.body, i)
774 document.warning("Malformed lyx document: Can't find end of TOC inset")
777 subst = put_cmd_in_ert("\\lstlistoflistings{}")
778 document.body[i:j+1] = subst
779 add_to_preamble(document, ["\\usepackage{listings}"])
783 def convert_use_amssymb(document):
784 "insert use_package amssymb"
785 regexp = re.compile(r'(\\use_package\s+amsmath)')
786 i = find_re(document.header, regexp, 0)
788 document.warning("Malformed LyX document: Can't find \\use_package amsmath.")
790 value = get_value(document.header, "\\use_package" , i).split()[1]
793 useamsmath = int(value)
795 document.warning("Invalid \\use_package amsmath: " + value + ". Assuming auto.")
797 j = find_token(document.preamble, "\\usepackage{amssymb}", 0)
799 document.header.insert(i + 1, "\\use_package amssymb %d" % useamsmath)
801 document.header.insert(i + 1, "\\use_package amssymb 2")
802 del document.preamble[j]
805 def revert_use_amssymb(document):
806 "remove use_package amssymb"
807 regexp1 = re.compile(r'(\\use_package\s+amsmath)')
808 regexp2 = re.compile(r'(\\use_package\s+amssymb)')
809 i = find_re(document.header, regexp1, 0)
810 j = find_re(document.header, regexp2, 0)
811 value1 = "1" # default is auto
812 value2 = "1" # default is auto
814 value1 = get_value(document.header, "\\use_package" , i).split()[1]
816 value2 = get_value(document.header, "\\use_package" , j).split()[1]
817 del document.header[j]
818 if value1 != value2 and value2 == "2": # on
819 add_to_preamble(document, ["\\usepackage{amssymb}"])
822 def convert_use_cancel(document):
823 "insert use_package cancel"
824 convert_use_package(document, "cancel")
827 def revert_use_cancel(document):
828 "remove use_package cancel"
829 commands = ["cancel", "bcancel", "xcancel", "cancelto"]
830 revert_use_package(document, "cancel", commands, True)
833 def revert_ancientgreek(document):
834 "Set the document language for ancientgreek to greek"
836 if document.language == "ancientgreek":
837 document.language = "greek"
838 i = find_token(document.header, "\\language", 0)
840 document.header[i] = "\\language greek"
843 j = find_token(document.body, "\\lang ancientgreek", j)
847 document.body[j] = document.body[j].replace("\\lang ancientgreek", "\\lang greek")
851 def revert_languages(document):
852 "Set the document language for new supported languages to English"
855 "coptic", "divehi", "hindi", "kurmanji", "lao", "marathi", "occitan", "sanskrit",
856 "syriac", "tamil", "telugu", "urdu"
858 for n in range(len(languages)):
859 if document.language == languages[n]:
860 document.language = "english"
861 i = find_token(document.header, "\\language", 0)
863 document.header[i] = "\\language english"
865 while j < len(document.body):
866 j = find_token(document.body, "\\lang " + languages[n], j)
868 document.body[j] = document.body[j].replace("\\lang " + languages[n], "\\lang english")
871 j = len(document.body)
874 def convert_armenian(document):
875 "Use polyglossia and thus non-TeX fonts for Armenian"
877 if document.language == "armenian":
878 i = find_token(document.header, "\\use_non_tex_fonts", 0)
880 document.header[i] = "\\use_non_tex_fonts true"
883 def revert_armenian(document):
884 "Use ArmTeX and thus TeX fonts for Armenian"
886 if document.language == "armenian":
887 i = find_token(document.header, "\\use_non_tex_fonts", 0)
889 document.header[i] = "\\use_non_tex_fonts false"
892 def revert_libertine(document):
893 " Revert native libertine font definition to LaTeX "
895 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
896 i = find_token(document.header, "\\font_roman libertine", 0)
899 j = find_token(document.header, "\\font_osf true", 0)
902 preamble = "\\usepackage"
904 document.header[j] = "\\font_osf false"
907 preamble += "[lining]"
908 preamble += "{libertine-type1}"
909 add_to_preamble(document, [preamble])
910 document.header[i] = "\\font_roman default"
913 def revert_txtt(document):
914 " Revert native txtt font definition to LaTeX "
916 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
917 i = find_token(document.header, "\\font_typewriter txtt", 0)
919 preamble = "\\renewcommand{\\ttdefault}{txtt}"
920 add_to_preamble(document, [preamble])
921 document.header[i] = "\\font_typewriter default"
924 def revert_mathdesign(document):
925 " Revert native mathdesign font definition to LaTeX "
927 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
933 i = find_token(document.header, "\\font_roman", 0)
936 val = get_value(document.header, "\\font_roman", i)
937 if val in mathdesign_dict.keys():
938 preamble = "\\usepackage[%s" % mathdesign_dict[val]
940 j = find_token(document.header, "\\font_osf true", 0)
943 document.header[j] = "\\font_osf false"
944 l = find_token(document.header, "\\font_sc true", 0)
947 document.header[l] = "\\font_sc false"
949 preamble += ",expert"
950 preamble += "]{mathdesign}"
951 add_to_preamble(document, [preamble])
952 document.header[i] = "\\font_roman default"
955 def revert_texgyre(document):
956 " Revert native TeXGyre font definition to LaTeX "
958 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
959 texgyre_fonts = ["tgadventor", "tgbonum", "tgchorus", "tgcursor", \
960 "tgheros", "tgpagella", "tgschola", "tgtermes"]
961 i = find_token(document.header, "\\font_roman", 0)
963 val = get_value(document.header, "\\font_roman", i)
964 if val in texgyre_fonts:
965 preamble = "\\usepackage{%s}" % val
966 add_to_preamble(document, [preamble])
967 document.header[i] = "\\font_roman default"
968 i = find_token(document.header, "\\font_sans", 0)
970 val = get_value(document.header, "\\font_sans", i)
971 if val in texgyre_fonts:
972 preamble = "\\usepackage{%s}" % val
973 add_to_preamble(document, [preamble])
974 document.header[i] = "\\font_sans default"
975 i = find_token(document.header, "\\font_typewriter", 0)
977 val = get_value(document.header, "\\font_typewriter", i)
978 if val in texgyre_fonts:
979 preamble = "\\usepackage{%s}" % val
980 add_to_preamble(document, [preamble])
981 document.header[i] = "\\font_typewriter default"
984 def revert_ipadeco(document):
985 " Revert IPA decorations to ERT "
988 i = find_token(document.body, "\\begin_inset IPADeco", i)
991 end = find_end_of_inset(document.body, i)
993 document.warning("Can't find end of inset at line " + str(i))
996 line = document.body[i]
997 rx = re.compile(r'\\begin_inset IPADeco (.*)$')
999 decotype = m.group(1)
1000 if decotype != "toptiebar" and decotype != "bottomtiebar":
1001 document.warning("Invalid IPADeco type: " + decotype)
1004 blay = find_token(document.body, "\\begin_layout Plain Layout", i, end)
1006 document.warning("Can't find layout for inset at line " + str(i))
1009 bend = find_end_of_layout(document.body, blay)
1011 document.warning("Malformed LyX document: Could not find end of IPADeco inset's layout.")
1014 substi = ["\\begin_inset ERT", "status collapsed", "",
1015 "\\begin_layout Plain Layout", "", "", "\\backslash",
1016 decotype + "{", "\\end_layout", "", "\\end_inset"]
1017 substj = ["\\size default", "", "\\begin_inset ERT", "status collapsed", "",
1018 "\\begin_layout Plain Layout", "", "}", "\\end_layout", "", "\\end_inset"]
1019 # do the later one first so as not to mess up the numbering
1020 document.body[bend:end + 1] = substj
1021 document.body[i:blay + 1] = substi
1022 i = end + len(substi) + len(substj) - (end - bend) - (blay - i) - 2
1023 add_to_preamble(document, "\\usepackage{tipa}")
1026 def revert_ipachar(document):
1027 ' Revert \\IPAChar to ERT '
1030 while i < len(document.body):
1031 m = re.match(r'(.*)\\IPAChar \\(\w+\{\w+\})(.*)', document.body[i])
1035 ipachar = m.group(2)
1038 '\\begin_inset ERT',
1039 'status collapsed', '',
1040 '\\begin_layout Standard',
1041 '', '', '\\backslash',
1046 document.body[i: i+1] = subst
1051 add_to_preamble(document, "\\usepackage{tone}")
1054 def revert_minionpro(document):
1055 " Revert native MinionPro font definition to LaTeX "
1057 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1058 i = find_token(document.header, "\\font_roman minionpro", 0)
1061 j = find_token(document.header, "\\font_osf true", 0)
1064 preamble = "\\usepackage"
1066 document.header[j] = "\\font_osf false"
1069 preamble += "{MinionPro}"
1070 add_to_preamble(document, [preamble])
1071 document.header[i] = "\\font_roman default"
1074 def revert_mathfonts(document):
1075 " Revert native math font definitions to LaTeX "
1077 i = find_token(document.header, "\\font_math", 0)
1080 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1081 val = get_value(document.header, "\\font_math", i)
1082 if val == "eulervm":
1083 add_to_preamble(document, "\\usepackage{eulervm}")
1084 elif val == "default":
1086 "lmodern": "\\renewcommand{\\rmdefault}{lmr}",
1087 "minionpro": "\\usepackage[onlytext,lf]{MinionPro}",
1088 "minionpro-osf": "\\usepackage[onlytext]{MinionPro}",
1089 "palatino": "\\renewcommand{\\rmdefault}{ppl}",
1090 "palatino-osf": "\\renewcommand{\\rmdefault}{pplj}",
1091 "times": "\\renewcommand{\\rmdefault}{ptm}",
1092 "utopia": "\\renewcommand{\\rmdefault}{futs}",
1093 "utopia-osf": "\\renewcommand{\\rmdefault}{futj}",
1095 j = find_token(document.header, "\\font_roman", 0)
1097 rm = get_value(document.header, "\\font_roman", j)
1098 k = find_token(document.header, "\\font_osf true", 0)
1101 if rm in mathfont_dict.keys():
1102 add_to_preamble(document, mathfont_dict[rm])
1103 document.header[j] = "\\font_roman default"
1105 document.header[k] = "\\font_osf false"
1106 del document.header[i]
1109 def revert_mdnomath(document):
1110 " Revert mathdesign and fourier without math "
1112 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1114 "md-charter": "mdbch",
1115 "md-utopia": "mdput",
1116 "md-garamond": "mdugm"
1118 i = find_token(document.header, "\\font_roman", 0)
1121 val = get_value(document.header, "\\font_roman", i)
1122 if val in mathdesign_dict.keys():
1123 j = find_token(document.header, "\\font_math", 0)
1125 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1126 mval = get_value(document.header, "\\font_math", j)
1127 if mval == "default":
1128 document.header[i] = "\\font_roman default"
1129 add_to_preamble(document, "\\renewcommand{\\rmdefault}{%s}" % mathdesign_dict[val])
1131 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1134 def convert_mdnomath(document):
1135 " Change mathdesign font name "
1137 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1139 "mdbch": "md-charter",
1140 "mdput": "md-utopia",
1141 "mdugm": "md-garamond"
1143 i = find_token(document.header, "\\font_roman", 0)
1146 val = get_value(document.header, "\\font_roman", i)
1147 if val in mathdesign_dict.keys():
1148 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1151 def revert_newtxmath(document):
1152 " Revert native newtxmath definitions to LaTeX "
1154 i = find_token(document.header, "\\font_math", 0)
1157 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1158 val = get_value(document.header, "\\font_math", i)
1160 "libertine-ntxm": "\\usepackage[libertine]{newtxmath}",
1161 "minion-ntxm": "\\usepackage[minion]{newtxmath}",
1162 "newtxmath": "\\usepackage{newtxmath}",
1164 if val in mathfont_dict.keys():
1165 add_to_preamble(document, mathfont_dict[val])
1166 document.header[i] = "\\font_math auto"
1169 def revert_biolinum(document):
1170 " Revert native biolinum font definition to LaTeX "
1172 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1173 i = find_token(document.header, "\\font_sans biolinum", 0)
1176 j = find_token(document.header, "\\font_osf true", 0)
1179 preamble = "\\usepackage"
1182 preamble += "{biolinum-type1}"
1183 add_to_preamble(document, [preamble])
1184 document.header[i] = "\\font_sans default"
1187 def revert_uop(document):
1188 " Revert native URW Classico (Optima) font definition to LaTeX "
1190 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1191 i = find_token(document.header, "\\font_sans uop", 0)
1193 preamble = "\\renewcommand{\\sfdefault}{uop}"
1194 add_to_preamble(document, [preamble])
1195 document.header[i] = "\\font_sans default"
1198 def convert_latexargs(document):
1199 " Convert InsetArgument to new syntax "
1201 if find_token(document.body, "\\begin_inset Argument", 0) == -1:
1205 # A list of layouts (document classes) with only optional or no arguments.
1206 # These can be safely converted to the new syntax
1207 # (I took the liberty to add some of my personal layouts/modules here; JSP)
1208 safe_layouts = ["aa", "aapaper", "aastex", "achemso", "acmsiggraph", "AEA",
1209 "agu-dtd", "agums", "agutex", "amsart", "amsbook", "apa",
1210 "arab-article", "armenian-article", "article-beamer", "article",
1211 "beamer", "book", "broadway", "chess", "cl2emult", "ctex-article",
1212 "ctex-book", "ctex-report", "dinbrief", "docbook-book", "docbook-chapter",
1213 "docbook", "docbook-section", "doublecol-new", "dtk", "ectaart", "egs",
1214 "elsarticle", "elsart", "entcs", "europecv", "extarticle", "extbook",
1215 "extletter", "extreport", "foils", "frletter", "g-brief2", "g-brief",
1216 "heb-article", "heb-letter", "hollywood", "IEEEtran", "ijmpc", "ijmpd",
1217 "iopart", "isprs", "jarticle", "jasatex", "jbook", "jgrga", "jreport",
1218 "jsarticle", "jsbeamer", "jsbook", "jss", "kluwer", "latex8", "letter", "lettre",
1219 "literate-article", "literate-book", "literate-report", "llncs", "ltugboat",
1220 "memoir", "moderncv", "mwart", "mwbk", "mwrep", "paper", "powerdot",
1221 "recipebook", "report", "revtex4", "revtex", "scrartcl", "scrarticle-beamer",
1222 "scrbook", "scrlettr", "scrlttr2", "scrreprt", "seminar", "siamltex",
1223 "sigplanconf", "simplecv", "singlecol", "singlecol-new", "slides", "spie",
1224 "svglobal3", "svglobal", "svjog", "svmono", "svmult", "svprobth", "tarticle",
1225 "tbook", "treport", "tufte-book", "tufte-handout"]
1226 # A list of "safe" modules, same as above
1227 safe_modules = ["biblatex", "beameraddons", "beamersession", "braille", "customHeadersFooters",
1228 "endnotes", "enumitem", "eqs-within-sections", "figs-within-sections", "fix-cm",
1229 "fixltx2e", "foottoend", "hanging", "jscharstyles", "knitr", "lilypond",
1230 "linguistics", "linguisticx", "logicalmkup", "minimalistic", "nomindex", "noweb",
1231 "pdfcomment", "sweave", "tabs-within-sections", "theorems-ams-bytype",
1232 "theorems-ams-extended-bytype", "theorems-ams-extended", "theorems-ams", "theorems-bytype",
1233 "theorems-chap-bytype", "theorems-chap", "theorems-named", "theorems-sec-bytype",
1234 "theorems-sec", "theorems-starred", "theorems-std", "todonotes"]
1235 # Modules we need to take care of
1236 caveat_modules = ["initials"]
1237 # information about the relevant styles in caveat_modules (number of opt and req args)
1238 # use this if we get more caveat_modules. For now, use hard coding (see below).
1239 # initials = [{'Layout' : 'Initial', 'opt' : 1, 'req' : 1}]
1241 # Is this a known safe layout?
1242 safe_layout = document.textclass in safe_layouts
1244 document.warning("Lyx2lyx knows nothing about textclass '%s'. "
1245 "Please check if short title insets have been converted correctly."
1246 % document.textclass)
1247 # Do we use unsafe or unknown modules
1248 mods = document.get_module_list()
1249 unknown_modules = False
1250 used_caveat_modules = list()
1252 if mod in safe_modules:
1254 if mod in caveat_modules:
1255 used_caveat_modules.append(mod)
1257 unknown_modules = True
1258 document.warning("Lyx2lyx knows nothing about module '%s'. "
1259 "Please check if short title insets have been converted correctly."
1264 i = find_token(document.body, "\\begin_inset Argument", i)
1268 if not safe_layout or unknown_modules:
1269 # We cannot do more here since we have no access to this layout.
1270 # InsetArgument itself will do the real work
1271 # (see InsetArgument::updateBuffer())
1272 document.body[i] = "\\begin_inset Argument 999"
1276 # Find containing paragraph layout
1277 parent = get_containing_layout(document.body, i)
1279 document.warning("Malformed lyx document: Can't find parent paragraph layout")
1286 if len(used_caveat_modules) > 0:
1287 # We know for now that this must be the initials module with the Initial layout
1288 # If we get more such modules, we need some automating.
1289 if parent[0] == "Initial":
1290 # Layout has 1 opt and 1 req arg.
1291 # Count the actual arguments
1293 for p in range(parbeg, parend):
1294 if document.body[p] == "\\begin_inset Argument":
1299 # Collect all arguments in this paragraph
1301 for p in range(parbeg, parend):
1302 if document.body[p] == "\\begin_inset Argument":
1304 if allowed_opts != -1:
1305 # We have less arguments than opt + required.
1306 # required must take precedence.
1307 if argnr > allowed_opts and argnr < first_req:
1309 document.body[p] = "\\begin_inset Argument %d" % argnr
1313 def revert_latexargs(document):
1314 " Revert InsetArgument to old syntax "
1317 rx = re.compile(r'^\\begin_inset Argument (\d+)$')
1320 # Search for Argument insets
1321 i = find_token(document.body, "\\begin_inset Argument", i)
1324 m = rx.match(document.body[i])
1326 # No ID: inset already reverted
1329 # Find containing paragraph layout
1330 parent = get_containing_layout(document.body, i)
1332 document.warning("Malformed lyx document: Can't find parent paragraph layout")
1337 realparbeg = parent[3]
1338 # Collect all arguments in this paragraph
1340 for p in range(parbeg, parend):
1341 m = rx.match(document.body[p])
1343 val = int(m.group(1))
1344 j = find_end_of_inset(document.body, p)
1345 # Revert to old syntax
1346 document.body[p] = "\\begin_inset Argument"
1348 document.warning("Malformed lyx document: Can't find end of Argument inset")
1351 args[val] = document.body[p : j + 1]
1353 realparend = realparend - len(document.body[p : j + 1])
1354 # Remove arg inset at this position
1355 del document.body[p : j + 1]
1358 # Now sort the arg insets
1360 for f in sorted(args):
1363 # Insert the sorted arg insets at paragraph begin
1364 document.body[realparbeg : realparbeg] = subst
1366 i = realparbeg + 1 + len(subst)
1369 def revert_Argument_to_TeX_brace(document, line, endline, n, nmax, environment, opt):
1371 Reverts an InsetArgument to TeX-code
1373 revert_Argument_to_TeX_brace(document, LineOfBegin, LineOfEnd, StartArgument, EndArgument, isEnvironment, isOpt)
1374 LineOfBegin is the line of the \begin_layout or \begin_inset statement
1375 LineOfEnd is the line of the \end_layout or \end_inset statement, if "0" is given, the end of the file is used instead
1376 StartArgument is the number of the first argument that needs to be converted
1377 EndArgument is the number of the last argument that needs to be converted or the last defined one
1378 isEnvironment must be true, if the layout is for a LaTeX environment
1379 isOpt must be true, if the argument is an optional one
1383 while lineArg != -1 and n < nmax + 1:
1384 lineArg = find_token(document.body, "\\begin_inset Argument " + str(n), line)
1385 if lineArg > endline and endline != 0:
1388 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", lineArg)
1389 # we have to assure that no other inset is in the Argument
1390 beginInset = find_token(document.body, "\\begin_inset", beginPlain)
1391 endInset = find_token(document.body, "\\end_inset", beginPlain)
1394 while beginInset < endInset and beginInset != -1:
1395 beginInset = find_token(document.body, "\\begin_inset", k)
1396 endInset = find_token(document.body, "\\end_inset", l)
1399 if environment == False:
1401 document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("}{")
1402 del(document.body[lineArg : beginPlain + 1])
1405 document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("]")
1406 document.body[lineArg : beginPlain + 1] = put_cmd_in_ert("[")
1409 document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("}")
1410 document.body[lineArg : beginPlain + 1] = put_cmd_in_ert("{")
1416 def convert_TeX_brace_to_Argument(document, line, n, nmax, inset, environment):
1418 Converts TeX code for mandatory arguments to an InsetArgument
1419 The conversion of TeX code for optional arguments must be done with another routine
1420 !!! Be careful if the braces are different in your case as expected here:
1421 - "}{" separates mandatory arguments of commands
1422 - "}" + "{" separates mandatory arguments of commands
1423 - "}" + " " + "{" separates mandatory arguments of commands
1424 - { and } surround a mandatory argument of an environment
1426 convert_TeX_brace_to_Argument(document, LineOfBeginLayout/Inset, StartArgument, EndArgument, isInset, isEnvironment)
1427 LineOfBeginLayout/Inset is the line of the \begin_layout or \begin_inset statement
1428 StartArgument is the number of the first ERT that needs to be converted
1429 EndArgument is the number of the last ERT that needs to be converted
1430 isInset must be true, if braces inside an InsetLayout needs to be converted
1431 isEnvironment must be true, if the layout is for a LaTeX environment
1433 Todo: this routine can currently handle only one mandatory argument of environments
1438 while lineERT != -1 and n < nmax + 1:
1439 lineERT = find_token(document.body, "\\begin_inset ERT", lineERT)
1440 if environment == False and lineERT != -1:
1441 bracePair = find_token(document.body, "}{", lineERT)
1442 # assure that the "}{" is in this ERT
1443 if bracePair == lineERT + 5:
1444 end = find_token(document.body, "\\end_inset", bracePair)
1445 document.body[lineERT : end + 1] = ["\\end_layout", "", "\\end_inset"]
1447 # in the case that n > 1 we have optional arguments before
1448 # therefore detect them if any
1450 # first check if there is an argument
1451 lineArg = find_token(document.body, "\\begin_inset Argument", line)
1452 if lineArg < lineERT and lineArg != -1:
1453 # we have an argument, so now search backwards for its end
1454 # we must now assure that we don't find other insets like e.g. a newline
1455 endInsetArg = lineERT
1456 endLayoutArg = endInsetArg
1457 while endInsetArg != endLayoutArg + 2 and endInsetArg != -1:
1458 endInsetArg = endInsetArg - 1
1459 endLayoutArg = endInsetArg
1460 endInsetArg = find_token_backwards(document.body, "\\end_inset", endInsetArg)
1461 endLayoutArg = find_token_backwards(document.body, "\\end_layout", endLayoutArg)
1462 line = endInsetArg + 1
1464 document.body[line + 1 : line + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1466 document.body[line + 4 : line + 4] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1468 document.body[endn : endn] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1472 # now check the case that we have "}" + "{" in two ERTs
1474 endBrace = find_token(document.body, "}", lineERT)
1475 if endBrace == lineERT + 5:
1476 beginBrace = find_token(document.body, "{", endBrace)
1477 # assure that the ERTs are consecutive (11 or 12 depending if there is a space between the ERTs or not)
1478 if beginBrace == endBrace + 11 or beginBrace == endBrace + 12:
1479 end = find_token(document.body, "\\end_inset", beginBrace)
1480 document.body[lineERT : end + 1] = ["\\end_layout", "", "\\end_inset"]
1482 # in the case that n > 1 we have optional arguments before
1483 # therefore detect them if any
1485 # first check if there is an argument
1486 lineArg = find_token(document.body, "\\begin_inset Argument", line)
1487 if lineArg < lineERT and lineArg != -1:
1488 # we have an argument, so now search backwards for its end
1489 # we must now assure that we don't find other insets like e.g. a newline
1490 endInsetArg = lineERT
1491 endLayoutArg = endInsetArg
1492 while endInsetArg != endLayoutArg + 2 and endInsetArg != -1:
1493 endInsetArg = endInsetArg - 1
1494 endLayoutArg = endInsetArg
1495 endInsetArg = find_token_backwards(document.body, "\\end_inset", endInsetArg)
1496 endLayoutArg = find_token_backwards(document.body, "\\end_layout", endLayoutArg)
1497 line = endInsetArg + 1
1499 document.body[line + 1 : line + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1501 document.body[line + 4 : line + 4] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1503 document.body[endn : endn] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1506 # set the line where the next argument will be inserted
1507 if beginBrace == endBrace + 11:
1512 lineERT = lineERT + 1
1513 if environment == True and lineERT != -1:
1514 opening = find_token(document.body, "{", lineERT)
1515 if opening == lineERT + 5: # assure that the "{" is in this ERT
1516 end = find_token(document.body, "\\end_inset", opening)
1517 document.body[lineERT : end + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1519 lineERT2 = find_token(document.body, "\\begin_inset ERT", lineERT)
1520 closing = find_token(document.body, "}", lineERT2)
1521 if closing == lineERT2 + 5: # assure that the "}" is in this ERT
1522 end2 = find_token(document.body, "\\end_inset", closing)
1523 document.body[lineERT2 : end2 + 1] = ["\\end_layout", "", "\\end_inset"]
1525 lineERT = lineERT + 1
1528 def revert_IEEEtran(document):
1530 Reverts InsetArgument of
1533 Biography without photo
1536 if document.textclass == "IEEEtran":
1543 i = find_token(document.body, "\\begin_layout Page headings", i)
1545 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1548 i2 = find_token(document.body, "\\begin_inset Flex Paragraph Start", i2)
1550 revert_Argument_to_TeX_brace(document, i2, 0, 1, 1, False, False)
1553 j = find_token(document.body, "\\begin_layout Biography without photo", j)
1555 revert_Argument_to_TeX_brace(document, j, 0, 1, 1, True, False)
1558 k = find_token(document.body, "\\begin_layout Biography", k)
1559 kA = find_token(document.body, "\\begin_layout Biography without photo", k)
1560 if k == kA and k != -1:
1564 # start with the second argument, therefore 2
1565 revert_Argument_to_TeX_brace(document, k, 0, 2, 2, True, False)
1567 if i == -1 and i2 == -1 and j == -1 and k == -1:
1571 def revert_IEEEtran_2(document):
1573 Reverts Flex Paragraph Start to TeX-code
1575 if document.textclass == "IEEEtran":
1579 begin = find_token(document.body, "\\begin_inset Flex Paragraph Start", begin)
1581 end1 = find_end_of_inset(document.body, begin)
1582 document.body[end1 - 2 : end1 + 1] = put_cmd_in_ert("}")
1583 document.body[begin : begin + 4] = put_cmd_in_ert("\\IEEEPARstart{")
1589 def convert_IEEEtran(document):
1594 Biography without photo
1597 if document.textclass == "IEEEtran":
1603 i = find_token(document.body, "\\begin_layout Page headings", i)
1605 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1608 j = find_token(document.body, "\\begin_layout Biography without photo", j)
1610 convert_TeX_brace_to_Argument(document, j, 1, 1, False, True)
1613 # assure that we don't handle Biography Biography without photo
1614 k = find_token(document.body, "\\begin_layout Biography", k)
1615 kA = find_token(document.body, "\\begin_layout Biography without photo", k - 1)
1616 if k == kA and k != -1:
1620 # the argument we want to convert is the second one
1621 convert_TeX_brace_to_Argument(document, k, 2, 2, False, True)
1623 if i == -1 and j == -1 and k == -1:
1627 def revert_AASTeX(document):
1628 " Reverts InsetArgument of Altaffilation to TeX-code "
1629 if document.textclass == "aastex":
1633 i = find_token(document.body, "\\begin_layout Altaffilation", i)
1635 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1641 def convert_AASTeX(document):
1642 " Converts ERT of Altaffilation to InsetArgument "
1643 if document.textclass == "aastex":
1647 i = find_token(document.body, "\\begin_layout Altaffilation", i)
1649 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1655 def revert_AGUTeX(document):
1656 " Reverts InsetArgument of Author affiliation to TeX-code "
1657 if document.textclass == "agutex":
1661 i = find_token(document.body, "\\begin_layout Author affiliation", i)
1663 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1669 def convert_AGUTeX(document):
1670 " Converts ERT of Author affiliation to InsetArgument "
1671 if document.textclass == "agutex":
1675 i = find_token(document.body, "\\begin_layout Author affiliation", i)
1677 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1683 def revert_IJMP(document):
1684 " Reverts InsetArgument of MarkBoth to TeX-code "
1685 if document.textclass == "ijmpc" or document.textclass == "ijmpd":
1689 i = find_token(document.body, "\\begin_layout MarkBoth", i)
1691 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1697 def convert_IJMP(document):
1698 " Converts ERT of MarkBoth to InsetArgument "
1699 if document.textclass == "ijmpc" or document.textclass == "ijmpd":
1703 i = find_token(document.body, "\\begin_layout MarkBoth", i)
1705 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1711 def revert_SIGPLAN(document):
1712 " Reverts InsetArguments of SIGPLAN to TeX-code "
1713 if document.textclass == "sigplanconf":
1718 i = find_token(document.body, "\\begin_layout Conference", i)
1720 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1723 j = find_token(document.body, "\\begin_layout Author", j)
1725 revert_Argument_to_TeX_brace(document, j, 0, 1, 2, False, False)
1727 if i == -1 and j == -1:
1731 def convert_SIGPLAN(document):
1732 " Converts ERT of SIGPLAN to InsetArgument "
1733 if document.textclass == "sigplanconf":
1738 i = find_token(document.body, "\\begin_layout Conference", i)
1740 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1743 j = find_token(document.body, "\\begin_layout Author", j)
1745 convert_TeX_brace_to_Argument(document, j, 1, 2, False, False)
1747 if i == -1 and j == -1:
1751 def revert_SIGGRAPH(document):
1752 " Reverts InsetArgument of Flex CRcat to TeX-code "
1753 if document.textclass == "acmsiggraph":
1757 i = find_token(document.body, "\\begin_inset Flex CRcat", i)
1759 revert_Argument_to_TeX_brace(document, i, 0, 1, 3, False, False)
1765 def convert_SIGGRAPH(document):
1766 " Converts ERT of Flex CRcat to InsetArgument "
1767 if document.textclass == "acmsiggraph":
1771 i = find_token(document.body, "\\begin_inset Flex CRcat", i)
1773 convert_TeX_brace_to_Argument(document, i, 1, 3, True, False)
1779 def revert_EuropeCV(document):
1780 " Reverts InsetArguments of europeCV to TeX-code "
1781 if document.textclass == "europecv":
1788 i = find_token(document.body, "\\begin_layout Item", i)
1790 revert_Argument_to_TeX_brace(document, i, 0, 2, 2, False, False)
1793 j = find_token(document.body, "\\begin_layout BulletedItem", j)
1795 revert_Argument_to_TeX_brace(document, j, 0, 2, 2, False, False)
1798 k = find_token(document.body, "\\begin_layout Language", k)
1800 revert_Argument_to_TeX_brace(document, k, 0, 2, 6, False, False)
1803 m = find_token(document.body, "\\begin_layout LastLanguage", m)
1805 revert_Argument_to_TeX_brace(document, m, 0, 2, 6, False, False)
1807 if i == -1 and j == -1 and k == -1 and m == -1:
1811 def convert_EuropeCV(document):
1812 " Converts ERT of europeCV to InsetArgument "
1813 if document.textclass == "europecv":
1820 i = find_token(document.body, "\\begin_layout Item", i)
1822 convert_TeX_brace_to_Argument(document, i, 2, 2, False, False)
1825 j = find_token(document.body, "\\begin_layout BulletedItem", j)
1827 convert_TeX_brace_to_Argument(document, j, 2, 2, False, False)
1830 k = find_token(document.body, "\\begin_layout Language", k)
1832 convert_TeX_brace_to_Argument(document, k, 2, 6, False, False)
1835 m = find_token(document.body, "\\begin_layout LastLanguage", m)
1837 convert_TeX_brace_to_Argument(document, m, 2, 6, False, False)
1839 if i == -1 and j == -1 and k == -1 and m == -1:
1843 def revert_ModernCV(document):
1844 " Reverts InsetArguments of modernCV to TeX-code "
1845 if document.textclass == "moderncv":
1852 j = find_token(document.body, "\\begin_layout Entry", j)
1854 revert_Argument_to_TeX_brace(document, j, 0, 1, 5, False, False)
1857 k = find_token(document.body, "\\begin_layout Item", k)
1859 revert_Argument_to_TeX_brace(document, k, 0, 1, 1, False, False)
1862 m = find_token(document.body, "\\begin_layout ItemWithComment", m)
1864 revert_Argument_to_TeX_brace(document, m, 0, 1, 2, False, False)
1865 document.body[m] = document.body[m].replace("\\begin_layout ItemWithComment", "\\begin_layout Language")
1868 o = find_token(document.body, "\\begin_layout DoubleItem", o)
1870 revert_Argument_to_TeX_brace(document, o, 0, 1, 3, False, False)
1871 document.body[o] = document.body[o].replace("\\begin_layout DoubleItem", "\\begin_layout Computer")
1873 if j == -1 and k == -1 and m == -1 and o == -1:
1877 def revert_ModernCV_2(document):
1878 " Reverts the Flex:Column inset of modernCV to TeX-code "
1879 if document.textclass == "moderncv":
1884 flex = find_token(document.body, "\\begin_inset Flex Column", flex)
1886 flexEnd = find_end_of_inset(document.body, flex)
1887 wasOpt = revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, False, True)
1888 revert_Argument_to_TeX_brace(document, flex, 0, 2, 2, False, False)
1889 flexEnd = find_end_of_inset(document.body, flex)
1891 document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\cvcolumn")
1893 document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\cvcolumn{")
1894 document.body[flexEnd + 4 : flexEnd + 7] = put_cmd_in_ert("}")
1900 def revert_ModernCV_3(document):
1901 " Reverts the Column style of modernCV to TeX-code "
1902 if document.textclass == "moderncv":
1903 # revert the layouts
1904 revert_ModernCV(document)
1906 # get the position of the end of the last column inset
1907 LastFlexEnd = revert_ModernCV_2(document)
1910 p = find_token(document.body, "\\begin_layout Columns", p)
1912 pEnd = find_end_of_layout(document.body, p)
1913 document.body[p] = document.body[p].replace("\\begin_layout Columns", "\\begin_layout Standard")
1914 if LastFlexEnd != -1:
1915 document.body[p + 1 : p + 1] = put_cmd_in_ert("\\begin{cvcolumns}")
1916 document.body[LastFlexEnd + 24 : LastFlexEnd + 24] = put_cmd_in_ert("\\end{cvcolumns}")
1922 def convert_ModernCV(document):
1923 " Converts ERT of modernCV to InsetArgument "
1924 if document.textclass == "moderncv":
1932 i = find_token(document.body, "\\begin_layout DoubleItem", i)
1934 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1935 document.body[o] = document.body[o].replace("\\begin_layout DoubleItem", "\\begin_layout DoubleListItem")
1938 j = find_token(document.body, "\\begin_layout Entry", j)
1940 convert_TeX_brace_to_Argument(document, j, 1, 5, False, False)
1943 k = find_token(document.body, "\\begin_layout Item", k)
1945 convert_TeX_brace_to_Argument(document, k, 1, 1, False, False)
1948 m = find_token(document.body, "\\begin_layout Language", m)
1950 convert_TeX_brace_to_Argument(document, m, 1, 2, False, False)
1952 if i == -1 and j == -1 and k == -1 and m == -1:
1956 def revert_Initials(document):
1957 " Reverts InsetArgument of Initial to TeX-code "
1961 i = find_token(document.body, "\\begin_layout Initial", i)
1963 # first arg (optional) and second arg (first mandatory) are supported in LyX 2.0.x
1964 revert_Argument_to_TeX_brace(document, i, 0, 3, 3, False, False)
1970 def convert_Initials(document):
1971 " Converts ERT of Initial to InsetArgument "
1975 i = find_token(document.body, "\\begin_layout Initial", i)
1977 convert_TeX_brace_to_Argument(document, i, 3, 3, False, False)
1983 def revert_literate(document):
1984 " Revert Literate document to old format "
1985 if del_token(document.header, "noweb", 0):
1986 document.textclass = "literate-" + document.textclass
1989 i = find_token(document.body, "\\begin_layout Chunk", i)
1992 document.body[i] = "\\begin_layout Scrap"
1996 def convert_literate(document):
1997 " Convert Literate document to new format"
1998 i = find_token(document.header, "\\textclass", 0)
1999 if (i != -1) and "literate-" in document.header[i]:
2000 document.textclass = document.header[i].replace("\\textclass literate-", "")
2001 j = find_token(document.header, "\\begin_modules", 0)
2003 document.header.insert(j + 1, "noweb")
2005 document.header.insert(i + 1, "\\end_modules")
2006 document.header.insert(i + 1, "noweb")
2007 document.header.insert(i + 1, "\\begin_modules")
2010 i = find_token(document.body, "\\begin_layout Scrap", i)
2013 document.body[i] = "\\begin_layout Chunk"
2017 def revert_itemargs(document):
2018 " Reverts \\item arguments to TeX-code "
2021 i = find_token(document.body, "\\begin_inset Argument item:", i)
2024 j = find_end_of_inset(document.body, i)
2025 # Find containing paragraph layout
2026 parent = get_containing_layout(document.body, i)
2028 document.warning("Malformed lyx document: Can't find parent paragraph layout")
2032 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2033 endPlain = find_end_of_layout(document.body, beginPlain)
2034 content = document.body[beginPlain + 1 : endPlain]
2035 del document.body[i:j+1]
2036 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2037 document.body[parbeg : parbeg] = subst
2041 def revert_garamondx_newtxmath(document):
2042 " Revert native garamond newtxmath definition to LaTeX "
2044 i = find_token(document.header, "\\font_math", 0)
2047 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
2048 val = get_value(document.header, "\\font_math", i)
2049 if val == "garamondx-ntxm":
2050 add_to_preamble(document, "\\usepackage[garamondx]{newtxmath}")
2051 document.header[i] = "\\font_math auto"
2054 def revert_garamondx(document):
2055 " Revert native garamond font definition to LaTeX "
2057 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
2058 i = find_token(document.header, "\\font_roman garamondx", 0)
2061 j = find_token(document.header, "\\font_osf true", 0)
2064 preamble = "\\usepackage"
2066 preamble += "[osfI]"
2067 preamble += "{garamondx}"
2068 add_to_preamble(document, [preamble])
2069 document.header[i] = "\\font_roman default"
2072 def convert_beamerargs(document):
2073 " Converts beamer arguments to new layout "
2075 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2076 if document.textclass not in beamer_classes:
2079 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
2080 list_layouts = ["Itemize", "Enumerate", "Description"]
2081 rx = re.compile(r'^\\begin_inset Argument (\d+)$')
2085 i = find_token(document.body, "\\begin_inset Argument", i)
2088 # Find containing paragraph layout
2089 parent = get_containing_layout(document.body, i)
2091 document.warning("Malformed lyx document: Can't find parent paragraph layout")
2096 layoutname = parent[0]
2097 for p in range(parbeg, parend):
2098 if layoutname in shifted_layouts:
2099 m = rx.match(document.body[p])
2101 argnr = int(m.group(1))
2103 document.body[p] = "\\begin_inset Argument %d" % argnr
2104 if layoutname == "AgainFrame":
2105 m = rx.match(document.body[p])
2107 document.body[p] = "\\begin_inset Argument 3"
2108 if document.body[p + 4] == "\\begin_inset ERT":
2109 if document.body[p + 9].startswith("<"):
2110 # This is an overlay specification
2112 document.body[p + 9] = document.body[p + 9][1:]
2113 if document.body[p + 9].endswith(">"):
2115 document.body[p + 9] = document.body[p + 9][:-1]
2117 document.body[p] = "\\begin_inset Argument 2"
2118 if layoutname in list_layouts:
2119 m = rx.match(document.body[p])
2121 if m.group(1) == "1":
2122 if document.body[p + 4] == "\\begin_inset ERT":
2123 if document.body[p + 9].startswith("<"):
2124 # This is an overlay specification
2126 document.body[p + 9] = document.body[p + 9][1:]
2127 if document.body[p + 9].endswith(">"):
2129 document.body[p + 9] = document.body[p + 9][:-1]
2130 elif layoutname != "Itemize":
2132 document.body[p] = "\\begin_inset Argument 2"
2136 def convert_againframe_args(document):
2137 " Converts beamer AgainFrame to new layout "
2139 # FIXME: This currently only works if the arguments are in one single ERT
2141 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2142 if document.textclass not in beamer_classes:
2147 i = find_token(document.body, "\\begin_layout AgainFrame", i)
2150 parent = get_containing_layout(document.body, i)
2152 document.warning("Wrong parent layout!")
2156 if document.body[parbeg] == "\\begin_inset ERT":
2157 ertcont = parbeg + 5
2158 if document.body[ertcont].startswith("[<"):
2159 # This is a default overlay specification
2161 document.body[ertcont] = document.body[ertcont][2:]
2162 if document.body[ertcont].endswith(">]"):
2164 document.body[ertcont] = document.body[ertcont][:-2]
2165 elif document.body[ertcont].endswith("]"):
2167 tok = document.body[ertcont].find('>][')
2169 subst = [document.body[ertcont][:tok],
2170 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2171 'status collapsed', '', '\\begin_layout Plain Layout',
2172 document.body[ertcont][tok + 3:-1]]
2173 document.body[ertcont : ertcont + 1] = subst
2174 # Convert to ArgInset
2175 document.body[parbeg] = "\\begin_inset Argument 2"
2178 elif document.body[ertcont].startswith("<"):
2179 # This is an overlay specification
2181 document.body[ertcont] = document.body[ertcont][1:]
2182 if document.body[ertcont].endswith(">"):
2184 document.body[ertcont] = document.body[ertcont][:-1]
2185 # Convert to ArgInset
2186 document.body[parbeg] = "\\begin_inset Argument 1"
2187 elif document.body[ertcont].endswith(">]"):
2189 tok = document.body[ertcont].find('>[<')
2191 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2192 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2193 'status collapsed', '', '\\begin_layout Plain Layout',
2194 document.body[ertcont][tok + 3:-2]]
2195 # Convert to ArgInset
2196 document.body[parbeg] = "\\begin_inset Argument 1"
2197 elif document.body[ertcont].endswith("]"):
2199 tok = document.body[ertcont].find('>[<')
2202 tokk = document.body[ertcont].find('>][')
2204 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2205 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2206 'status collapsed', '', '\\begin_layout Plain Layout',
2207 document.body[ertcont][tok + 3:tokk],
2208 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2209 'status collapsed', '', '\\begin_layout Plain Layout',
2210 document.body[ertcont][tokk + 3:-1]]
2212 tokk = document.body[ertcont].find('>[')
2214 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tokk],
2215 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2216 'status collapsed', '', '\\begin_layout Plain Layout',
2217 document.body[ertcont][tokk + 2:-1]]
2218 # Convert to ArgInset
2219 document.body[parbeg] = "\\begin_inset Argument 1"
2222 elif document.body[ertcont].startswith("["):
2223 # This is an ERT option
2225 document.body[ertcont] = document.body[ertcont][1:]
2226 if document.body[ertcont].endswith("]"):
2228 document.body[ertcont] = document.body[ertcont][:-1]
2229 # Convert to ArgInset
2230 document.body[parbeg] = "\\begin_inset Argument 3"
2236 def convert_corollary_args(document):
2237 " Converts beamer corrolary-style ERT arguments native InsetArgs "
2239 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2240 if document.textclass not in beamer_classes:
2243 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2244 for lay in corollary_layouts:
2247 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2250 parent = get_containing_layout(document.body, i)
2252 document.warning("Wrong parent layout!")
2256 if document.body[parbeg] == "\\begin_inset ERT":
2257 ertcont = parbeg + 5
2258 if document.body[ertcont].startswith("<"):
2259 # This is an overlay specification
2261 document.body[ertcont] = document.body[ertcont][1:]
2262 if document.body[ertcont].endswith(">"):
2264 document.body[ertcont] = document.body[ertcont][:-1]
2265 elif document.body[ertcont].endswith("]"):
2267 tok = document.body[ertcont].find('>[')
2269 subst = [document.body[ertcont][:tok],
2270 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2271 'status collapsed', '', '\\begin_layout Plain Layout',
2272 document.body[ertcont][tok + 2:-1]]
2273 document.body[ertcont : ertcont + 1] = subst
2274 # Convert to ArgInset
2275 document.body[parbeg] = "\\begin_inset Argument 1"
2278 elif document.body[ertcont].startswith("["):
2279 # This is an ERT option
2281 document.body[ertcont] = document.body[ertcont][1:]
2282 if document.body[ertcont].endswith("]"):
2284 document.body[ertcont] = document.body[ertcont][:-1]
2285 # Convert to ArgInset
2286 document.body[parbeg] = "\\begin_inset Argument 2"
2293 def convert_quote_args(document):
2294 " Converts beamer quote style ERT args to native InsetArgs "
2296 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2297 if document.textclass not in beamer_classes:
2300 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2301 for lay in quote_layouts:
2304 i = find_token(document.body, "\\begin_layout " + lay, i)
2307 parent = get_containing_layout(document.body, i)
2309 document.warning("Wrong parent layout!")
2313 if document.body[parbeg] == "\\begin_inset ERT":
2314 if document.body[i + 6].startswith("<"):
2315 # This is an overlay specification
2317 document.body[i + 6] = document.body[i + 6][1:]
2318 if document.body[i + 6].endswith(">"):
2320 document.body[i + 6] = document.body[i + 6][:-1]
2321 # Convert to ArgInset
2322 document.body[i + 1] = "\\begin_inset Argument 1"
2326 def revert_beamerargs(document):
2327 " Reverts beamer arguments to old layout "
2329 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2330 if document.textclass not in beamer_classes:
2334 list_layouts = ["Itemize", "Enumerate", "Description"]
2335 headings = ["Part", "Section", "Section*", "Subsection", "Subsection*",
2336 "Subsubsection", "Subsubsection*", "FrameSubtitle", "NoteItem"]
2337 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2338 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2339 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2342 i = find_token(document.body, "\\begin_inset Argument", i)
2345 # Find containing paragraph layout
2346 parent = get_containing_layout(document.body, i)
2348 document.warning("Malformed lyx document: Can't find parent paragraph layout")
2353 realparbeg = parent[3]
2354 layoutname = parent[0]
2356 for p in range(parbeg, parend):
2360 if layoutname in headings:
2361 m = rx.match(document.body[p])
2365 # Find containing paragraph layout
2366 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2367 endPlain = find_end_of_layout(document.body, beginPlain)
2368 endInset = find_end_of_inset(document.body, p)
2369 argcontent = document.body[beginPlain + 1 : endPlain]
2371 realparend = realparend - len(document.body[p : endInset + 1])
2373 del document.body[p : endInset + 1]
2374 if layoutname == "FrameSubtitle":
2375 pre = put_cmd_in_ert("\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2376 elif layoutname == "NoteItem":
2377 pre = put_cmd_in_ert("\\note<") + argcontent + put_cmd_in_ert(">[item]")
2378 elif layoutname.endswith('*'):
2379 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower()[:-1] + "<") + argcontent + put_cmd_in_ert(">*")
2381 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2382 secarg = find_token(document.body, "\\begin_inset Argument 2", parbeg, parend)
2384 # Find containing paragraph layout
2385 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", secarg)
2386 endPlain = find_end_of_layout(document.body, beginPlain)
2387 endInset = find_end_of_inset(document.body, secarg)
2388 argcontent = document.body[beginPlain + 1 : endPlain]
2390 realparend = realparend - len(document.body[secarg : endInset + 1])
2391 del document.body[secarg : endInset + 1]
2392 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2393 pre += put_cmd_in_ert("{")
2394 document.body[parbeg] = "\\begin_layout Standard"
2395 document.body[realparbeg : realparbeg] = pre
2396 pe = find_end_of_layout(document.body, parbeg)
2397 post = put_cmd_in_ert("}")
2398 document.body[pe : pe] = post
2399 realparend += len(pre) + len(post)
2400 if layoutname == "AgainFrame":
2401 m = rx.match(document.body[p])
2405 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2406 endPlain = find_end_of_layout(document.body, beginPlain)
2407 endInset = find_end_of_inset(document.body, p)
2408 content = document.body[beginPlain + 1 : endPlain]
2410 realparend = realparend - len(document.body[p : endInset + 1])
2412 del document.body[p : endInset + 1]
2413 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2414 document.body[realparbeg : realparbeg] = subst
2415 if layoutname == "Overprint":
2416 m = rx.match(document.body[p])
2420 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2421 endPlain = find_end_of_layout(document.body, beginPlain)
2422 endInset = find_end_of_inset(document.body, p)
2423 content = document.body[beginPlain + 1 : endPlain]
2425 realparend = realparend - len(document.body[p : endInset + 1])
2427 del document.body[p : endInset + 1]
2428 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2429 document.body[realparbeg : realparbeg] = subst
2430 if layoutname == "OverlayArea":
2431 m = rx.match(document.body[p])
2435 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2436 endPlain = find_end_of_layout(document.body, beginPlain)
2437 endInset = find_end_of_inset(document.body, p)
2438 content = document.body[beginPlain + 1 : endPlain]
2440 realparend = realparend - len(document.body[p : endInset + 1])
2442 del document.body[p : endInset + 1]
2443 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2444 document.body[realparbeg : realparbeg] = subst
2445 if layoutname in list_layouts:
2446 m = rx.match(document.body[p])
2450 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2451 endPlain = find_end_of_layout(document.body, beginPlain)
2452 endInset = find_end_of_inset(document.body, p)
2453 content = document.body[beginPlain + 1 : endPlain]
2454 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2455 realparend = realparend + len(subst) - len(content)
2456 document.body[beginPlain + 1 : endPlain] = subst
2457 elif argnr == "item:1":
2458 j = find_end_of_inset(document.body, i)
2459 # Find containing paragraph layout
2460 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2461 endPlain = find_end_of_layout(document.body, beginPlain)
2462 content = document.body[beginPlain + 1 : endPlain]
2463 del document.body[i:j+1]
2464 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2465 document.body[realparbeg : realparbeg] = subst
2466 elif argnr == "item:2":
2467 j = find_end_of_inset(document.body, i)
2468 # Find containing paragraph layout
2469 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2470 endPlain = find_end_of_layout(document.body, beginPlain)
2471 content = document.body[beginPlain + 1 : endPlain]
2472 del document.body[i:j+1]
2473 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2474 document.body[realparbeg : realparbeg] = subst
2475 if layoutname in quote_layouts:
2476 m = rx.match(document.body[p])
2480 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2481 endPlain = find_end_of_layout(document.body, beginPlain)
2482 endInset = find_end_of_inset(document.body, p)
2483 content = document.body[beginPlain + 1 : endPlain]
2485 realparend = realparend - len(document.body[p : endInset + 1])
2487 del document.body[p : endInset + 1]
2488 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2489 document.body[realparbeg : realparbeg] = subst
2490 if layoutname in corollary_layouts:
2491 m = rx.match(document.body[p])
2495 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2496 endPlain = find_end_of_layout(document.body, beginPlain)
2497 endInset = find_end_of_inset(document.body, p)
2498 content = document.body[beginPlain + 1 : endPlain]
2500 realparend = realparend - len(document.body[p : endInset + 1])
2502 del document.body[p : endInset + 1]
2503 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2504 document.body[realparbeg : realparbeg] = subst
2509 def revert_beamerargs2(document):
2510 " Reverts beamer arguments to old layout, step 2 "
2512 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2513 if document.textclass not in beamer_classes:
2517 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
2518 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2519 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2522 i = find_token(document.body, "\\begin_inset Argument", i)
2525 # Find containing paragraph layout
2526 parent = get_containing_layout(document.body, i)
2528 document.warning("Malformed lyx document: Can't find parent paragraph layout")
2533 realparbeg = parent[3]
2534 layoutname = parent[0]
2536 for p in range(parbeg, parend):
2540 if layoutname in shifted_layouts:
2541 m = rx.match(document.body[p])
2545 document.body[p] = "\\begin_inset Argument 1"
2546 if layoutname in corollary_layouts:
2547 m = rx.match(document.body[p])
2551 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2552 endPlain = find_end_of_layout(document.body, beginPlain)
2553 endInset = find_end_of_inset(document.body, p)
2554 content = document.body[beginPlain + 1 : endPlain]
2556 realparend = realparend - len(document.body[p : endInset + 1])
2558 del document.body[p : endInset + 1]
2559 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2560 document.body[realparbeg : realparbeg] = subst
2561 if layoutname == "OverlayArea":
2562 m = rx.match(document.body[p])
2566 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2567 endPlain = find_end_of_layout(document.body, beginPlain)
2568 endInset = find_end_of_inset(document.body, p)
2569 content = document.body[beginPlain + 1 : endPlain]
2571 realparend = realparend - len(document.body[p : endInset + 1])
2573 del document.body[p : endInset + 1]
2574 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2575 document.body[realparbeg : realparbeg] = subst
2576 if layoutname == "AgainFrame":
2577 m = rx.match(document.body[p])
2581 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2582 endPlain = find_end_of_layout(document.body, beginPlain)
2583 endInset = find_end_of_inset(document.body, p)
2584 content = document.body[beginPlain + 1 : endPlain]
2586 realparend = realparend - len(document.body[p : endInset + 1])
2588 del document.body[p : endInset + 1]
2589 subst = put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
2590 document.body[realparbeg : realparbeg] = subst
2594 def revert_beamerargs3(document):
2595 " Reverts beamer arguments to old layout, step 3 "
2597 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2598 if document.textclass not in beamer_classes:
2601 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2604 i = find_token(document.body, "\\begin_inset Argument", i)
2607 # Find containing paragraph layout
2608 parent = get_containing_layout(document.body, i)
2610 document.warning("Malformed lyx document: Can't find parent paragraph layout")
2615 realparbeg = parent[3]
2616 layoutname = parent[0]
2618 for p in range(parbeg, parend):
2622 if layoutname == "AgainFrame":
2623 m = rx.match(document.body[p])
2627 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2628 endPlain = find_end_of_layout(document.body, beginPlain)
2629 endInset = find_end_of_inset(document.body, p)
2630 content = document.body[beginPlain + 1 : endPlain]
2632 realparend = realparend - len(document.body[p : endInset + 1])
2634 del document.body[p : endInset + 1]
2635 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2636 document.body[realparbeg : realparbeg] = subst
2640 def revert_beamerflex(document):
2641 " Reverts beamer Flex insets "
2643 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2644 if document.textclass not in beamer_classes:
2647 new_flexes = {"Bold" : "\\textbf", "Emphasize" : "\\emph", "Only" : "\\only",
2648 "Uncover" : "\\uncover", "Visible" : "\\visible",
2649 "Invisible" : "\\invisible", "Alternative" : "\\alt",
2650 "Beamer_Note" : "\\note"}
2651 old_flexes = {"Alert" : "\\alert", "Structure" : "\\structure"}
2652 rx = re.compile(r'^\\begin_inset Flex (.+)$')
2656 i = find_token(document.body, "\\begin_inset Flex", i)
2659 m = rx.match(document.body[i])
2661 flextype = m.group(1)
2662 z = find_end_of_inset(document.body, i)
2664 document.warning("Can't find end of Flex " + flextype + " inset.")
2667 if flextype in new_flexes:
2668 pre = put_cmd_in_ert(new_flexes[flextype])
2669 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2671 argend = find_end_of_inset(document.body, arg)
2673 document.warning("Can't find end of Argument!")
2676 # Find containing paragraph layout
2677 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2678 endPlain = find_end_of_layout(document.body, beginPlain)
2679 argcontent = document.body[beginPlain + 1 : endPlain]
2681 z = z - len(document.body[arg : argend + 1])
2683 del document.body[arg : argend + 1]
2684 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2685 arg = find_token(document.body, "\\begin_inset Argument 2", i, z)
2687 argend = find_end_of_inset(document.body, arg)
2689 document.warning("Can't find end of Argument!")
2692 # Find containing paragraph layout
2693 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2694 endPlain = find_end_of_layout(document.body, beginPlain)
2695 argcontent = document.body[beginPlain + 1 : endPlain]
2697 z = z - len(document.body[arg : argend + 1])
2699 del document.body[arg : argend + 1]
2700 if flextype == "Alternative":
2701 pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
2703 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2704 pre += put_cmd_in_ert("{")
2705 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2706 endPlain = find_end_of_layout(document.body, beginPlain)
2708 z = z - len(document.body[i : beginPlain + 1])
2710 document.body[i : beginPlain + 1] = pre
2711 post = put_cmd_in_ert("}")
2712 document.body[z - 2 : z + 1] = post
2713 elif flextype in old_flexes:
2714 pre = put_cmd_in_ert(old_flexes[flextype])
2715 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2719 argend = find_end_of_inset(document.body, arg)
2721 document.warning("Can't find end of Argument!")
2724 # Find containing paragraph layout
2725 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2726 endPlain = find_end_of_layout(document.body, beginPlain)
2727 argcontent = document.body[beginPlain + 1 : endPlain]
2729 z = z - len(document.body[arg : argend + 1])
2731 del document.body[arg : argend + 1]
2732 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2733 pre += put_cmd_in_ert("{")
2734 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2735 endPlain = find_end_of_layout(document.body, beginPlain)
2737 z = z - len(document.body[i : beginPlain + 1])
2739 document.body[i : beginPlain + 1] = pre
2740 post = put_cmd_in_ert("}")
2741 document.body[z - 2 : z + 1] = post
2746 def revert_beamerblocks(document):
2747 " Reverts beamer block arguments to ERT "
2749 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2750 if document.textclass not in beamer_classes:
2753 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2755 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2758 i = find_token(document.body, "\\begin_inset Argument", i)
2761 # Find containing paragraph layout
2762 parent = get_containing_layout(document.body, i)
2764 document.warning("Malformed lyx document: Can't find parent paragraph layout")
2769 realparbeg = parent[3]
2770 layoutname = parent[0]
2772 for p in range(parbeg, parend):
2776 if layoutname in blocks:
2777 m = rx.match(document.body[p])
2781 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2782 endPlain = find_end_of_layout(document.body, beginPlain)
2783 endInset = find_end_of_inset(document.body, p)
2784 content = document.body[beginPlain + 1 : endPlain]
2786 realparend = realparend - len(document.body[p : endInset + 1])
2788 del document.body[p : endInset + 1]
2789 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2790 document.body[realparbeg : realparbeg] = subst
2792 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2793 endPlain = find_end_of_layout(document.body, beginPlain)
2794 endInset = find_end_of_inset(document.body, p)
2795 content = document.body[beginPlain + 1 : endPlain]
2797 realparend = realparend - len(document.body[p : endInset + 1])
2799 del document.body[p : endInset + 1]
2800 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2801 document.body[realparbeg : realparbeg] = subst
2806 def convert_beamerblocks(document):
2807 " Converts beamer block ERT args to native InsetArgs "
2809 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2810 if document.textclass not in beamer_classes:
2813 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2817 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2820 parent = get_containing_layout(document.body, i)
2821 if parent == False or parent[1] != i:
2822 document.warning("Wrong parent layout!")
2828 if document.body[parbeg] == "\\begin_inset ERT":
2829 ertcont = parbeg + 5
2831 if document.body[ertcont].startswith("<"):
2832 # This is an overlay specification
2834 document.body[ertcont] = document.body[ertcont][1:]
2835 if document.body[ertcont].endswith(">"):
2837 document.body[ertcont] = document.body[ertcont][:-1]
2838 # Convert to ArgInset
2839 document.body[parbeg] = "\\begin_inset Argument 1"
2840 elif document.body[ertcont].endswith("}"):
2842 tok = document.body[ertcont].find('>{')
2844 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2845 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2846 'status collapsed', '', '\\begin_layout Plain Layout',
2847 document.body[ertcont][tok + 2:-1]]
2848 # Convert to ArgInset
2849 document.body[parbeg] = "\\begin_inset Argument 1"
2850 elif document.body[ertcont].startswith("{"):
2851 # This is the block title
2852 if document.body[ertcont].endswith("}"):
2853 # strip off the braces
2854 document.body[ertcont] = document.body[ertcont][1:-1]
2855 # Convert to ArgInset
2856 document.body[parbeg] = "\\begin_inset Argument 2"
2857 elif count_pars_in_inset(document.body, ertcont) > 1:
2858 # Multipar ERT. Skip this.
2861 convert_TeX_brace_to_Argument(document, i, 2, 2, False, True)
2864 j = find_end_of_layout(document.body, i)
2866 document.warning("end of layout not found!")
2867 k = find_token(document.body, "\\begin_inset Argument", i, j)
2869 document.warning("InsetArgument not found!")
2871 l = find_end_of_inset(document.body, k)
2872 m = find_token(document.body, "\\begin_inset ERT", l, j)
2880 def convert_overprint(document):
2881 " Convert old beamer overprint layouts to ERT "
2883 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2884 if document.textclass not in beamer_classes:
2889 i = find_token(document.body, "\\begin_layout Overprint", i)
2892 # Find end of sequence
2893 j = find_end_of_sequence(document.body, i)
2895 document.warning("Malformed lyx document. Cannot find end of Overprint sequence!")
2899 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
2901 if document.body[j] == "\\end_deeper":
2902 esubst = ["", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
2904 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
2905 endseq = endseq + len(esubst) - len(document.body[j : j])
2906 document.body[j : j] = esubst
2907 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
2909 argend = find_end_of_layout(document.body, argbeg)
2911 document.warning("Malformed lyx document. Cannot find end of Overprint argument!")
2914 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
2915 endPlain = find_end_of_layout(document.body, beginPlain)
2916 content = document.body[beginPlain + 1 : endPlain]
2918 endseq = endseq - len(document.body[argbeg : argend + 1])
2920 del document.body[argbeg : argend + 1]
2921 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2923 endseq = endseq - len(document.body[i : i])
2924 document.body[i : i] = subst + ["\\end_layout"]
2925 endseq += len(subst)
2927 for p in range(i, endseq):
2928 if document.body[p] == "\\begin_layout Overprint":
2929 document.body[p] = "\\begin_layout Standard"
2934 def revert_overprint(document):
2935 " Revert old beamer overprint layouts to ERT "
2937 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2938 if document.textclass not in beamer_classes:
2943 i = find_token(document.body, "\\begin_layout Overprint", i)
2946 # Find end of sequence
2947 j = find_end_of_sequence(document.body, i)
2949 document.warning("Malformed lyx document. Cannot find end of Overprint sequence!")
2953 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
2954 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}")
2955 endseq = endseq + len(esubst) - len(document.body[j : j])
2956 if document.body[j] == "\\end_deeper":
2957 document.body[j : j] = ["\\end_deeper", ""] + esubst
2959 document.body[j : j] = esubst
2962 if document.body[r] == "\\begin_deeper":
2963 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
2965 document.body[r] = ""
2966 document.body[s] = ""
2970 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
2972 argend = find_end_of_inset(document.body, argbeg)
2974 document.warning("Malformed lyx document. Cannot find end of Overprint argument!")
2977 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
2978 endPlain = find_end_of_layout(document.body, beginPlain)
2979 content = document.body[beginPlain + 1 : endPlain]
2981 endseq = endseq - len(document.body[argbeg : argend])
2983 del document.body[argbeg : argend + 1]
2984 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2986 endseq = endseq - len(document.body[i : i])
2987 document.body[i : i] = subst + ["\\end_layout"]
2988 endseq += len(subst)
2994 if document.body[p] == "\\begin_layout Overprint":
2995 q = find_end_of_layout(document.body, p)
2997 document.warning("Malformed lyx document. Cannot find end of Overprint layout!")
3000 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\onslide")
3001 argbeg = find_token(document.body, "\\begin_inset Argument item:1", p, q)
3003 argend = find_end_of_inset(document.body, argbeg)
3005 document.warning("Malformed lyx document. Cannot find end of Overprint item argument!")
3008 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3009 endPlain = find_end_of_layout(document.body, beginPlain)
3010 content = document.body[beginPlain + 1 : endPlain]
3012 endseq = endseq - len(document.body[argbeg : argend + 1])
3014 del document.body[argbeg : argend + 1]
3015 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3016 endseq = endseq - len(document.body[p : p + 1]) + len(subst)
3017 document.body[p : p + 1] = subst
3023 def revert_frametitle(document):
3024 " Reverts beamer frametitle layout to ERT "
3026 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3027 if document.textclass not in beamer_classes:
3030 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
3033 i = find_token(document.body, "\\begin_layout FrameTitle", i)
3036 j = find_end_of_layout(document.body, i)
3038 document.warning("Malformed lyx document: Can't find end of FrameTitle layout")
3042 document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
3043 endlay += len(put_cmd_in_ert("}"))
3044 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\frametitle")
3045 for p in range(i, j):
3048 m = rx.match(document.body[p])
3052 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3053 endPlain = find_end_of_layout(document.body, beginPlain)
3054 endInset = find_end_of_inset(document.body, p)
3055 content = document.body[beginPlain + 1 : endPlain]
3057 endlay = endlay - len(document.body[p : endInset + 1])
3059 del document.body[p : endInset + 1]
3060 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3062 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3063 endPlain = find_end_of_layout(document.body, beginPlain)
3064 endInset = find_end_of_inset(document.body, p)
3065 content = document.body[beginPlain + 1 : endPlain]
3067 endlay = endlay - len(document.body[p : endInset + 1])
3069 del document.body[p : endInset + 1]
3070 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3072 subst += put_cmd_in_ert("{")
3073 document.body[i : i + 1] = subst
3077 def convert_epigraph(document):
3078 " Converts memoir epigraph to new syntax "
3080 if document.textclass != "memoir":
3085 i = find_token(document.body, "\\begin_layout Epigraph", i)
3088 j = find_end_of_layout(document.body, i)
3090 document.warning("Malformed lyx document: Can't find end of Epigraph layout")
3095 ert = find_token(document.body, "\\begin_inset ERT", i, j)
3097 endInset = find_end_of_inset(document.body, ert)
3098 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", ert)
3099 endPlain = find_end_of_layout(document.body, beginPlain)
3100 ertcont = beginPlain + 2
3101 if document.body[ertcont] == "}{":
3103 # Convert to ArgInset
3104 endlay = endlay - 2 * len(document.body[j])
3105 begsubst = ['\\begin_inset Argument post:1', 'status collapsed', '',
3106 '\\begin_layout Plain Layout']
3107 endsubst = ['\\end_layout', '', '\\end_inset', '', document.body[j]]
3108 document.body[j : j + 1] = endsubst
3109 document.body[endInset + 1 : endInset + 1] = begsubst
3111 endlay += len(begsubst) + len(endsubst)
3112 endlay = endlay - len(document.body[ert : endInset + 1])
3113 del document.body[ert : endInset + 1]
3118 def revert_epigraph(document):
3119 " Reverts memoir epigraph argument to ERT "
3121 if document.textclass != "memoir":
3126 i = find_token(document.body, "\\begin_layout Epigraph", i)
3129 j = find_end_of_layout(document.body, i)
3131 document.warning("Malformed lyx document: Can't find end of Epigraph layout")
3136 p = find_token(document.body, "\\begin_layout Argument post:1", i, j)
3138 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3139 endPlain = find_end_of_layout(document.body, beginPlain)
3140 endInset = find_end_of_inset(document.body, p)
3141 content = document.body[beginPlain + 1 : endPlain]
3143 endlay = endlay - len(document.body[p : endInset + 1])
3145 del document.body[p : endInset + 1]
3146 subst += put_cmd_in_ert("}{") + content
3148 subst += put_cmd_in_ert("}{")
3150 document.body[j : j] = subst + document.body[j : j]
3154 def convert_captioninsets(document):
3155 " Converts caption insets to new syntax "
3159 i = find_token(document.body, "\\begin_inset Caption", i)
3162 document.body[i] = "\\begin_inset Caption Standard"
3167 def revert_captioninsets(document):
3168 " Reverts caption insets to old syntax "
3172 i = find_token(document.body, "\\begin_inset Caption Standard", i)
3175 document.body[i] = "\\begin_inset Caption"
3179 def convert_captionlayouts(document):
3180 " Convert caption layouts to caption insets. "
3183 "Captionabove": "Above",
3184 "Captionbelow": "Below",
3185 "FigCaption" : "FigCaption",
3186 "Table_Caption" : "Table",
3187 "CenteredCaption" : "Centered",
3188 "Bicaption" : "Bicaption",
3193 i = find_token(document.body, "\\begin_layout", i)
3196 val = get_value(document.body, "\\begin_layout", i)
3197 if val in caption_dict.keys():
3198 j = find_end_of_layout(document.body, i)
3200 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3203 document.body[j:j] = ["\\end_layout", "", "\\end_inset", "", ""]
3204 document.body[i:i+1] = ["\\begin_layout %s" % document.default_layout,
3205 "\\begin_inset Caption %s" % caption_dict[val], "",
3206 "\\begin_layout %s" % document.default_layout]
3210 def revert_captionlayouts(document):
3211 " Revert caption insets to caption layouts. "
3214 "Above" : "Captionabove",
3215 "Below" : "Captionbelow",
3216 "FigCaption" : "FigCaption",
3217 "Table" : "Table_Caption",
3218 "Centered" : "CenteredCaption",
3219 "Bicaption" : "Bicaption",
3223 rx = re.compile(r'^\\begin_inset Caption (\S+)$')
3225 i = find_token(document.body, "\\begin_inset Caption", i)
3229 m = rx.match(document.body[i])
3233 if val not in caption_dict.keys():
3237 # We either need to delete the previous \begin_layout line, or we
3238 # need to end the previous layout if this inset is not in the first
3239 # position of the paragraph.
3240 layout_before = find_token_backwards(document.body, "\\begin_layout", i)
3241 if layout_before == -1:
3242 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3244 layout_line = document.body[layout_before]
3245 del_layout_before = True
3246 l = layout_before + 1
3248 if document.body[l] != "":
3249 del_layout_before = False
3252 if del_layout_before:
3253 del document.body[layout_before:i]
3256 document.body[i:i] = ["\\end_layout", ""]
3259 # Find start of layout in the inset and end of inset
3260 j = find_token(document.body, "\\begin_layout", i)
3262 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3264 k = find_end_of_inset(document.body, i)
3266 document.warning("Malformed LyX document: Missing `\\end_inset'.")
3269 # We either need to delete the following \end_layout line, or we need
3270 # to restart the old layout if this inset is not at the paragraph end.
3271 layout_after = find_token(document.body, "\\end_layout", k)
3272 if layout_after == -1:
3273 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3275 del_layout_after = True
3277 while l < layout_after:
3278 if document.body[l] != "":
3279 del_layout_after = False
3282 if del_layout_after:
3283 del document.body[k+1:layout_after+1]
3285 document.body[k+1:k+1] = [layout_line, ""]
3287 # delete \begin_layout and \end_inset and replace \begin_inset with
3288 # "\begin_layout XXX". This works because we can only have one
3289 # paragraph in the caption inset: The old \end_layout will be recycled.
3290 del document.body[k]
3291 if document.body[k] == "":
3292 del document.body[k]
3293 del document.body[j]
3294 if document.body[j] == "":
3295 del document.body[j]
3296 document.body[i] = "\\begin_layout %s" % caption_dict[val]
3297 if document.body[i+1] == "":
3298 del document.body[i+1]
3302 def revert_fragileframe(document):
3303 " Reverts beamer FragileFrame layout to ERT "
3305 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3306 if document.textclass not in beamer_classes:
3311 i = find_token(document.body, "\\begin_layout FragileFrame", i)
3314 # Find end of sequence
3315 j = find_end_of_sequence(document.body, i)
3317 document.warning("Malformed lyx document. Cannot find end of FragileFrame sequence!")
3321 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{frame}")
3322 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{frame}")
3323 endseq = endseq + len(esubst) - len(document.body[j : j])
3324 if document.body[j] == "\\end_deeper":
3325 document.body[j : j] = ["\\end_deeper", ""] + esubst
3327 document.body[j : j] = esubst
3328 for q in range(i, j):
3329 if document.body[q] == "\\begin_layout FragileFrame":
3330 document.body[q] = "\\begin_layout %s" % document.default_layout
3333 if document.body[r] == "\\begin_deeper":
3334 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3336 document.body[r] = ""
3337 document.body[s] = ""
3341 for p in range(1, 5):
3342 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, j)
3345 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3346 endPlain = find_end_of_layout(document.body, beginPlain)
3347 endInset = find_end_of_inset(document.body, arg)
3348 content = document.body[beginPlain + 1 : endPlain]
3350 j = j - len(document.body[arg : endInset + 1])
3352 del document.body[arg : endInset + 1]
3353 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3355 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3356 endPlain = find_end_of_layout(document.body, beginPlain)
3357 endInset = find_end_of_inset(document.body, arg)
3358 content = document.body[beginPlain + 1 : endPlain]
3360 j = j - len(document.body[arg : endInset + 1])
3362 del document.body[arg : endInset + 1]
3363 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3365 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3366 endPlain = find_end_of_layout(document.body, beginPlain)
3367 endInset = find_end_of_inset(document.body, arg)
3368 content = document.body[beginPlain + 1 : endPlain]
3370 j = j - len(document.body[arg : endInset + 1])
3372 del document.body[arg : endInset + 1]
3373 subst += put_cmd_in_ert("[fragile,") + content + put_cmd_in_ert("]")
3375 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3376 endPlain = find_end_of_layout(document.body, beginPlain)
3377 endInset = find_end_of_inset(document.body, arg)
3378 content = document.body[beginPlain + 1 : endPlain]
3380 j = j - len(document.body[arg : endInset + 1])
3382 del document.body[arg : endInset + 1]
3383 subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
3385 subst += put_cmd_in_ert("[fragile]")
3387 document.body[i : i + 1] = subst
3391 def revert_newframes(document):
3392 " Reverts beamer Frame and PlainFrame layouts to old forms "
3394 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3395 if document.textclass not in beamer_classes:
3399 "Frame" : "BeginFrame",
3400 "PlainFrame" : "BeginPlainFrame",
3403 rx = re.compile(r'^\\begin_layout (\S+)$')
3406 i = find_token(document.body, "\\begin_layout", i)
3410 m = rx.match(document.body[i])
3414 if val not in frame_dict.keys():
3417 # Find end of sequence
3418 j = find_end_of_sequence(document.body, i)
3420 document.warning("Malformed lyx document. Cannot find end of Frame sequence!")
3424 subst = ["\\begin_layout %s" % frame_dict[val]]
3425 esubst = ["\\end_layout", "", "\\begin_layout EndFrame", "", "\\end_layout"]
3426 endseq = endseq + len(esubst) - len(document.body[j : j])
3427 if document.body[j] == "\\end_deeper":
3428 document.body[j : j] = ["\\end_deeper", ""] + esubst
3430 document.body[j : j] = esubst
3431 for q in range(i, j):
3432 if document.body[q] == "\\begin_layout %s" % val:
3433 document.body[q] = "\\begin_layout %s" % document.default_layout
3436 if document.body[r] == "\\begin_deeper":
3437 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3439 document.body[r] = ""
3440 document.body[s] = ""
3444 l = find_end_of_layout(document.body, i)
3445 for p in range(1, 5):
3446 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, l)
3449 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3450 endPlain = find_end_of_layout(document.body, beginPlain)
3451 endInset = find_end_of_inset(document.body, arg)
3452 content = document.body[beginPlain + 1 : endPlain]
3454 l = l - len(document.body[arg : endInset + 1])
3456 del document.body[arg : endInset + 1]
3457 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3459 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3460 endPlain = find_end_of_layout(document.body, beginPlain)
3461 endInset = find_end_of_inset(document.body, arg)
3462 content = document.body[beginPlain + 1 : endPlain]
3464 l = l - len(document.body[arg : endInset + 1])
3466 del document.body[arg : endInset + 1]
3467 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3469 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3470 endPlain = find_end_of_layout(document.body, beginPlain)
3471 endInset = find_end_of_inset(document.body, arg)
3472 content = document.body[beginPlain + 1 : endPlain]
3474 l = l - len(document.body[arg : endInset + 1])
3476 del document.body[arg : endInset + 1]
3477 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3479 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3480 endPlain = find_end_of_layout(document.body, beginPlain)
3481 endInset = find_end_of_inset(document.body, arg)
3482 content = document.body[beginPlain + 1 : endPlain]
3484 l = l - len(document.body[arg : endInset + 1])
3486 del document.body[arg : endInset + 1]
3489 document.body[i : i + 1] = subst
3492 # known encodings that do not change their names (same LyX and LaTeX names)
3493 known_enc_tuple = ("auto", "default", "ansinew", "applemac", "armscii8", "ascii",
3494 "cp437", "cp437de", "cp850", "cp852", "cp855", "cp858", "cp862", "cp865", "cp866",
3495 "cp1250", "cp1251", "cp1252", "cp1255", "cp1256", "cp1257", "koi8-r", "koi8-u",
3496 "pt154", "pt254", "tis620-0", "utf8", "utf8x", "utf8-plain")
3498 def convert_encodings(document):
3499 "Use the LyX names of the encodings instead of the LaTeX names."
3500 LaTeX2LyX_enc_dict = {
3501 "8859-6": "iso8859-6",
3502 "8859-8": "iso8859-8",
3504 "euc": "euc-jp-platex",
3509 "iso88595": "iso8859-5",
3510 "iso-8859-7": "iso8859-7",
3512 "jis": "jis-platex",
3514 "l7xenc": "iso8859-13",
3515 "latin1": "iso8859-1",
3516 "latin2": "iso8859-2",
3517 "latin3": "iso8859-3",
3518 "latin4": "iso8859-4",
3519 "latin5": "iso8859-9",
3520 "latin9": "iso8859-15",
3521 "latin10": "iso8859-16",
3522 "SJIS": "shift-jis",
3523 "sjis": "shift-jis-platex",
3526 i = find_token(document.header, "\\inputencoding" , 0)
3529 val = get_value(document.header, "\\inputencoding", i)
3530 if val in LaTeX2LyX_enc_dict.keys():
3531 document.header[i] = "\\inputencoding %s" % LaTeX2LyX_enc_dict[val]
3532 elif val not in known_enc_tuple:
3533 document.warning("Ignoring unknown input encoding: `%s'" % val)
3536 def revert_encodings(document):
3537 """Revert to using the LaTeX names of the encodings instead of the LyX names.
3538 Also revert utf8-platex to sjis, the language default when using Japanese.
3540 LyX2LaTeX_enc_dict = {
3545 "euc-jp-platex": "euc",
3548 "iso8859-1": "latin1",
3549 "iso8859-2": "latin2",
3550 "iso8859-3": "latin3",
3551 "iso8859-4": "latin4",
3552 "iso8859-5": "iso88595",
3553 "iso8859-6": "8859-6",
3554 "iso8859-7": "iso-8859-7",
3555 "iso8859-8": "8859-8",
3556 "iso8859-9": "latin5",
3557 "iso8859-13": "l7xenc",
3558 "iso8859-15": "latin9",
3559 "iso8859-16": "latin10",
3561 "jis-platex": "jis",
3562 "shift-jis": "SJIS",
3563 "shift-jis-platex": "sjis",
3565 "utf8-platex": "sjis"
3567 i = find_token(document.header, "\\inputencoding" , 0)
3570 val = get_value(document.header, "\\inputencoding", i)
3571 if val in LyX2LaTeX_enc_dict.keys():
3572 document.header[i] = "\\inputencoding %s" % LyX2LaTeX_enc_dict[val]
3573 elif val not in known_enc_tuple:
3574 document.warning("Ignoring unknown input encoding: `%s'" % val)
3577 def revert_IEEEtran_3(document):
3579 Reverts Flex Insets to TeX-code
3581 if document.textclass == "IEEEtran":
3587 h = find_token(document.body, "\\begin_inset Flex Author Mark", h)
3589 endh = find_end_of_inset(document.body, h)
3590 document.body[endh - 2 : endh + 1] = put_cmd_in_ert("}")
3591 document.body[h : h + 4] = put_cmd_in_ert("\\IEEEauthorrefmark{")
3594 i = find_token(document.body, "\\begin_inset Flex Author Name", i)
3596 endi = find_end_of_inset(document.body, i)
3597 document.body[endi - 2 : endi + 1] = put_cmd_in_ert("}")
3598 document.body[i : i + 4] = put_cmd_in_ert("\\IEEEauthorblockN{")
3601 j = find_token(document.body, "\\begin_inset Flex Author Affiliation", j)
3603 endj = find_end_of_inset(document.body, j)
3604 document.body[endj - 2 : endj + 1] = put_cmd_in_ert("}")
3605 document.body[j : j + 4] = put_cmd_in_ert("\\IEEEauthorblockA{")
3607 if i == -1 and j == -1 and h == -1:
3611 def revert_kurier_fonts(document):
3612 " Revert kurier font definition to LaTeX "
3614 i = find_token(document.header, "\\font_math", 0)
3616 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3617 val = get_value(document.header, "\\font_math", i)
3618 if val == "kurier-math":
3619 add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
3620 "\\usepackage[math]{kurier}\n" \
3621 "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
3622 document.header[i] = "\\font_math auto"
3624 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3625 kurier_fonts = ["kurier", "kurierc", "kurierl", "kurierlc"]
3626 k = find_token(document.header, "\\font_sans kurier", 0)
3628 sf = get_value(document.header, "\\font_sans", k)
3629 if sf in kurier_fonts:
3630 add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
3631 document.header[k] = "\\font_sans default"
3634 def revert_new_libertines(document):
3635 " Revert new libertine font definition to LaTeX "
3637 if find_token(document.header, "\\use_non_tex_fonts true", 0) != -1:
3640 i = find_token(document.header, "\\font_typewriter libertine-mono", 0)
3642 preamble = "\\usepackage"
3643 sc = find_token(document.header, "\\font_tt_scale", 0)
3645 scval = get_value(document.header, "\\font_tt_scale", sc)
3647 preamble += "[scale=%f]" % (float(scval) / 100)
3648 document.header[sc] = "\\font_tt_scale 100"
3649 preamble += "{libertineMono-type1}"
3650 add_to_preamble(document, [preamble])
3651 document.header[i] = "\\font_typewriter default"
3653 k = find_token(document.header, "\\font_sans biolinum", 0)
3655 preamble = "\\usepackage"
3657 j = find_token(document.header, "\\font_osf true", 0)
3662 sc = find_token(document.header, "\\font_sf_scale", 0)
3664 scval = get_value(document.header, "\\font_sf_scale", sc)
3666 options += ",scale=%f" % (float(scval) / 100)
3667 document.header[sc] = "\\font_sf_scale 100"
3669 preamble += "[" + options +"]"
3670 preamble += "{biolinum-type1}"
3671 add_to_preamble(document, [preamble])
3672 document.header[k] = "\\font_sans default"
3675 def convert_lyxframes(document):
3676 " Converts old beamer frames to new style "
3678 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3679 if document.textclass not in beamer_classes:
3682 framebeg = ["BeginFrame", "BeginPlainFrame"]
3683 frameend = ["EndFrame", "BeginFrame", "BeginPlainFrame", "AgainFrame", "Section", "Section*",
3684 "Subsection", "Subsection*", "Subsubsection", "Subsubsection*"]
3685 for lay in framebeg:
3688 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
3691 parent = get_containing_layout(document.body, i)
3692 if parent == False or parent[1] != i:
3693 document.warning("Wrong parent layout!")
3696 frametype = parent[0]
3700 # Step I: Convert ERT arguments
3701 # FIXME: This currently only works if the arguments are in one single ERT
3703 if document.body[parbeg] == "\\begin_inset ERT":
3704 ertend = find_end_of_inset(document.body, parbeg)
3706 document.warning("Malformed LyX document: missing ERT \\end_inset")
3708 ertcont = parbeg + 5
3709 if document.body[ertcont].startswith("[<"):
3710 # This is a default overlay specification
3712 document.body[ertcont] = document.body[ertcont][2:]
3713 if document.body[ertcont].endswith(">]"):
3715 document.body[ertcont] = document.body[ertcont][:-2]
3716 elif document.body[ertcont].endswith("]"):
3718 tok = document.body[ertcont].find('>][')
3720 subst = [document.body[ertcont][:tok],
3721 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
3722 'status collapsed', '', '\\begin_layout Plain Layout',
3723 document.body[ertcont][tok + 3:-1]]
3724 document.body[ertcont : ertcont + 1] = subst
3726 # Convert to ArgInset
3727 document.body[parbeg] = "\\begin_inset Argument 2"
3728 elif document.body[ertcont].startswith("<"):
3729 # This is an overlay specification
3731 document.body[ertcont] = document.body[ertcont][1:]
3732 if document.body[ertcont].endswith(">"):
3734 document.body[ertcont] = document.body[ertcont][:-1]
3735 # Convert to ArgInset
3736 document.body[parbeg] = "\\begin_inset Argument 1"
3737 elif document.body[ertcont].endswith(">]"):
3739 tok = document.body[ertcont].find('>[<')
3741 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
3742 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
3743 'status collapsed', '', '\\begin_layout Plain Layout',
3744 document.body[ertcont][tok + 3:-2]]
3745 # Convert to ArgInset
3746 document.body[parbeg] = "\\begin_inset Argument 1"
3748 elif document.body[ertcont].endswith("]"):
3750 tok = document.body[ertcont].find('>[<')
3753 tokk = document.body[ertcont].find('>][')
3755 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
3756 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
3757 'status collapsed', '', '\\begin_layout Plain Layout',
3758 document.body[ertcont][tok + 3:tokk],
3759 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
3760 'status collapsed', '', '\\begin_layout Plain Layout',
3761 document.body[ertcont][tokk + 3:-1]]
3764 tokk = document.body[ertcont].find('>[')
3766 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tokk],
3767 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
3768 'status collapsed', '', '\\begin_layout Plain Layout',
3769 document.body[ertcont][tokk + 2:-1]]
3771 # Convert to ArgInset
3772 document.body[parbeg] = "\\begin_inset Argument 1"
3773 elif document.body[ertcont].startswith("["):
3774 # This is an ERT option
3776 document.body[ertcont] = document.body[ertcont][1:]
3777 if document.body[ertcont].endswith("]"):
3779 document.body[ertcont] = document.body[ertcont][:-1]
3780 # Convert to ArgInset
3781 document.body[parbeg] = "\\begin_inset Argument 3"
3782 # End of argument conversion
3783 # Step II: Now rename the layout and convert the title to an argument
3784 j = find_end_of_layout(document.body, i)
3785 document.body[j : j + 1] = ['\\end_layout', '', '\\end_inset', '', '\\end_layout']
3786 if lay == "BeginFrame":
3787 document.body[i] = "\\begin_layout Frame"
3789 document.body[i] = "\\begin_layout PlainFrame"
3790 document.body[ertend + 1 : ertend + 1] = ['\\begin_inset Argument 4',
3791 'status open', '', '\\begin_layout Plain Layout']
3792 # Step III: find real frame end
3796 fend = find_token(document.body, "\\begin_layout", jj)
3798 document.warning("Malformed LyX document: No real frame end!")
3800 val = get_value(document.body, "\\begin_layout", fend)
3801 if val not in frameend:
3804 old = document.body[fend]
3805 if val == frametype:
3806 document.body[fend : fend] = ['\\end_deeper', '', '\\begin_layout Separator', '', '\\end_layout']
3808 document.body[fend : fend] = ['\\end_deeper']
3809 document.body[j + 1 : j + 1] = ['', '\\begin_deeper']
3814 def remove_endframes(document):
3815 " Remove deprecated beamer endframes "
3817 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3818 if document.textclass not in beamer_classes:
3823 i = find_token_exact(document.body, "\\begin_layout EndFrame", i)
3826 j = find_end_of_layout(document.body, i)
3828 document.warning("Malformed LyX document: Missing \\end_layout to EndFrame")
3831 del document.body[i : j + 1]
3838 supported_versions = ["2.1.0","2.1"]
3841 [415, [convert_undertilde]],
3843 [417, [convert_japanese_encodings]],
3846 [420, [convert_biblio_style]],
3847 [421, [convert_longtable_captions]],
3848 [422, [convert_use_packages]],
3849 [423, [convert_use_mathtools]],
3850 [424, [convert_cite_engine_type]],
3854 [428, [convert_cell_rotation]],
3855 [429, [convert_table_rotation]],
3856 [430, [convert_listoflistings]],
3857 [431, [convert_use_amssymb]],
3859 [433, [convert_armenian]],
3867 [441, [convert_mdnomath]],
3872 [446, [convert_latexargs]],
3873 [447, [convert_IEEEtran, convert_AASTeX, convert_AGUTeX, convert_IJMP, convert_SIGPLAN, convert_SIGGRAPH, convert_EuropeCV, convert_Initials, convert_ModernCV]],
3874 [448, [convert_literate]],
3877 [451, [convert_beamerargs, convert_againframe_args, convert_corollary_args, convert_quote_args]],
3878 [452, [convert_beamerblocks]],
3879 [453, [convert_use_stmaryrd]],
3880 [454, [convert_overprint]],
3882 [456, [convert_epigraph]],
3883 [457, [convert_use_stackrel]],
3884 [458, [convert_captioninsets, convert_captionlayouts]],
3889 [463, [convert_encodings]],
3890 [464, [convert_use_cancel]],
3891 [465, [convert_lyxframes, remove_endframes]]
3896 [463, [revert_use_cancel]],
3897 [462, [revert_encodings]],
3898 [461, [revert_new_libertines]],
3899 [460, [revert_kurier_fonts]],
3900 [459, [revert_IEEEtran_3]],
3901 [458, [revert_fragileframe, revert_newframes]],
3902 [457, [revert_captioninsets, revert_captionlayouts]],
3903 [456, [revert_use_stackrel]],
3904 [455, [revert_epigraph]],
3905 [454, [revert_frametitle]],
3906 [453, [revert_overprint]],
3907 [452, [revert_use_stmaryrd]],
3908 [451, [revert_beamerblocks]],
3909 [450, [revert_beamerargs, revert_beamerargs2, revert_beamerargs3, revert_beamerflex]],
3910 [449, [revert_garamondx, revert_garamondx_newtxmath]],
3911 [448, [revert_itemargs]],
3912 [447, [revert_literate]],
3913 [446, [revert_IEEEtran, revert_IEEEtran_2, revert_AASTeX, revert_AGUTeX, revert_IJMP, revert_SIGPLAN, revert_SIGGRAPH, revert_EuropeCV, revert_Initials, revert_ModernCV_3]],
3914 [445, [revert_latexargs]],
3915 [444, [revert_uop]],
3916 [443, [revert_biolinum]],
3918 [441, [revert_newtxmath]],
3919 [440, [revert_mdnomath]],
3920 [439, [revert_mathfonts]],
3921 [438, [revert_minionpro]],
3922 [437, [revert_ipadeco, revert_ipachar]],
3923 [436, [revert_texgyre]],
3924 [435, [revert_mathdesign]],
3925 [434, [revert_txtt]],
3926 [433, [revert_libertine]],
3927 [432, [revert_armenian]],
3928 [431, [revert_languages, revert_ancientgreek]],
3929 [430, [revert_use_amssymb]],
3930 [429, [revert_listoflistings]],
3931 [428, [revert_table_rotation]],
3932 [427, [revert_cell_rotation]],
3933 [426, [revert_tipa]],
3934 [425, [revert_verbatim]],
3935 [424, [revert_cancel]],
3936 [423, [revert_cite_engine_type]],
3937 [422, [revert_use_mathtools]],
3938 [421, [revert_use_packages]],
3939 [420, [revert_longtable_captions]],
3940 [419, [revert_biblio_style]],
3941 [418, [revert_australian]],
3942 [417, [revert_justification]],
3943 [416, [revert_japanese_encodings]],
3944 [415, [revert_negative_space, revert_math_spaces]],
3945 [414, [revert_undertilde]],
3946 [413, [revert_visible_space]]
3950 if __name__ == "__main__":