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_mathtools(document):
374 "insert use_package mathtools"
375 i = find_token(document.header, "\\use_package", 0)
377 document.warning("Malformed LyX document: Can't find \\use_package.")
379 j = find_token(document.preamble, "\\usepackage{mathtools}", 0)
381 document.header.insert(i + 1, "\\use_package mathtools 0")
383 document.header.insert(i + 1, "\\use_package mathtools 2")
384 del document.preamble[j]
387 def revert_use_mathtools(document):
388 "remove use_package mathtools"
389 regexp = re.compile(r'(\\use_package\s+mathtools)')
390 i = find_re(document.header, regexp, 0)
391 value = "1" # default is auto
393 value = get_value(document.header, "\\use_package" , i).split()[1]
394 del document.header[i]
395 if value == "2": # on
396 add_to_preamble(document, ["\\usepackage{mathtools}"])
397 elif value == "1": # auto
398 commands = ["mathclap", "mathllap", "mathrlap", \
399 "lgathered", "rgathered", "vcentcolon", "dblcolon", \
400 "coloneqq", "Coloneqq", "coloneq", "Coloneq", "eqqcolon", \
401 "Eqqcolon", "eqcolon", "Eqcolon", "colonapprox", \
402 "Colonapprox", "colonsim", "Colonsim"]
405 i = find_token(document.body, '\\begin_inset Formula', i)
408 j = find_end_of_inset(document.body, i)
410 document.warning("Malformed LyX document: Can't find end of Formula inset at line " + str(i))
413 code = "\n".join(document.body[i:j])
415 if code.find("\\%s" % c) != -1:
416 add_to_preamble(document, ["\\usepackage{mathtools}"])
421 def convert_use_stmaryrd(document):
422 "insert use_package stmaryrd"
423 i = find_token(document.header, "\\use_package", 0)
425 document.warning("Malformed LyX document: Can't find \\use_package.")
427 j = find_token(document.preamble, "\\usepackage{stmaryrd}", 0)
429 document.header.insert(i + 1, "\\use_package stmaryrd 0")
431 document.header.insert(i + 1, "\\use_package stmaryrd 2")
432 del document.preamble[j]
435 def revert_use_stmaryrd(document):
436 "remove use_package stmaryrd"
437 regexp = re.compile(r'(\\use_package\s+stmaryrd)')
438 i = find_re(document.header, regexp, 0)
439 value = "1" # default is auto
441 value = get_value(document.header, "\\use_package" , i).split()[1]
442 del document.header[i]
443 if value == "2": # on
444 add_to_preamble(document, ["\\usepackage{stmaryrd}"])
445 elif value == "1": # auto
446 commands = ["shortleftarrow", "shortrightarrow", "shortuparrow", \
447 "shortdownarrow", "Yup", "Ydown", "Yleft", "Yright", \
448 "varcurlyvee", "varcurlywedge", "minuso", "baro", \
449 "sslash", "bbslash", "moo", "varotimes", "varoast", \
450 "varobar", "varodot", "varoslash", "varobslash", \
451 "varocircle", "varoplus", "varominus", "boxast", \
452 "boxbar", "boxslash", "boxbslash", "boxcircle", \
453 "boxbox", "boxempty", "merge", "vartimes", \
454 "fatsemi", "sswarrow", "ssearrow", "curlywedgeuparrow", \
455 "curlywedgedownarrow", "fatslash", "fatbslash", "lbag", \
456 "rbag", "varbigcirc", "leftrightarroweq", \
457 "curlyveedownarrow", "curlyveeuparrow", "nnwarrow", \
458 "nnearrow", "leftslice", "rightslice", "varolessthan", \
459 "varogreaterthan", "varovee", "varowedge", "talloblong", \
460 "interleave", "obar", "obslash", "olessthan", \
461 "ogreaterthan", "ovee", "owedge", "oblong", "inplus", \
462 "niplus", "nplus", "subsetplus", "supsetplus", \
463 "subsetpluseq", "supsetpluseq", "Lbag", "Rbag", \
464 "llbracket", "rrbracket", "llparenthesis", \
465 "rrparenthesis", "binampersand", "bindnasrepma", \
466 "trianglelefteqslant", "trianglerighteqslant", \
467 "ntrianglelefteqslant", "ntrianglerighteqslant", \
468 "llfloor", "rrfloor", "llceil", "rrceil", "arrownot", \
469 "Arrownot", "Mapstochar", "mapsfromchar", "Mapsfromchar", \
470 "leftrightarrowtriangle", "leftarrowtriangle", \
471 "rightarrowtriangle", \
472 "bigcurlyvee", "bigcurlywedge", "bigsqcap", "bigbox", \
473 "bigparallel", "biginterleave", "bignplus", \
474 "varcopyright", "longarrownot", "Longarrownot", \
475 "Mapsto", "mapsfrom", "Mapsfrom" "Longmapsto", \
476 "longmapsfrom", "Longmapsfrom"]
477 # commands provided by stmaryrd.sty but LyX uses other packages:
478 # boxdot lightning, bigtriangledown, bigtriangleup
482 i = find_token(document.body, '\\begin_inset Formula', i)
485 j = find_end_of_inset(document.body, i)
487 document.warning("Malformed LyX document: Can't find end of Formula inset at line " + str(i))
490 code = "\n".join(document.body[i:j])
492 if code.find("\\%s" % c) != -1:
493 add_to_preamble(document, ["\\usepackage{stmaryrd}"])
498 def convert_use_stackrel(document):
499 "insert use_package stackrel"
500 i = find_token(document.header, "\\use_package", 0)
502 document.warning("Malformed LyX document: Can't find \\use_package.")
504 j = find_token(document.preamble, "\\usepackage{stackrel}", 0)
506 document.header.insert(i + 1, "\\use_package stackrel 0")
508 document.header.insert(i + 1, "\\use_package stackrel 2")
509 del document.preamble[j]
512 def revert_use_stackrel(document):
513 "remove use_package stackrel"
514 regexp = re.compile(r'(\\use_package\s+stackrel)')
515 i = find_re(document.header, regexp, 0)
516 value = "1" # default is auto
518 value = get_value(document.header, "\\use_package" , i).split()[1]
519 del document.header[i]
520 if value == "2": # on
521 add_to_preamble(document, ["\\usepackage{stackrel}"])
522 elif value == "1": # auto
523 regcmd = re.compile(r'.*\\stackrel\s*\[')
526 i = find_token(document.body, '\\begin_inset Formula', i)
529 j = find_end_of_inset(document.body, i)
531 document.warning("Malformed LyX document: Can't find end of Formula inset at line " + str(i))
534 code = "\n".join(document.body[i:j])
535 if regcmd.match(code):
536 add_to_preamble(document, ["\\usepackage{stackrel}"])
541 def convert_cite_engine_type(document):
542 "Determine the \\cite_engine_type from the citation engine."
543 i = find_token(document.header, "\\cite_engine", 0)
546 engine = get_value(document.header, "\\cite_engine", i)
548 engine, type = engine.split("_")
550 type = {"basic": "numerical", "jurabib": "authoryear"}[engine]
551 document.header[i] = "\\cite_engine " + engine
552 document.header.insert(i + 1, "\\cite_engine_type " + type)
555 def revert_cite_engine_type(document):
556 "Natbib had the type appended with an underscore."
557 engine_type = "numerical"
558 i = find_token(document.header, "\\cite_engine_type" , 0)
560 document.warning("No \\cite_engine_type line. Assuming numerical.")
562 engine_type = get_value(document.header, "\\cite_engine_type", i)
563 del document.header[i]
565 # We are looking for the natbib citation engine
566 i = find_token(document.header, "\\cite_engine natbib", 0)
569 document.header[i] = "\\cite_engine natbib_" + engine_type
572 def revert_cancel(document):
573 "add cancel to the preamble if necessary"
574 commands = ["cancelto", "cancel", "bcancel", "xcancel"]
577 i = find_token(document.body, '\\begin_inset Formula', i)
580 j = find_end_of_inset(document.body, i)
582 document.warning("Malformed LyX document: Can't find end of Formula inset at line " + str(i))
585 code = "\n".join(document.body[i:j])
587 if code.find("\\%s" % c) != -1:
588 add_to_preamble(document, ["\\usepackage{cancel}"])
593 def revert_verbatim(document):
594 " Revert verbatim einvironments completely to TeX-code. "
597 subst_end = ['\end_layout', '', '\\begin_layout Plain Layout',
599 '\\begin_layout Plain Layout', '', '',
602 '\\end_layout', '', '\\end_inset',
603 '', '', '\\end_layout']
604 subst_begin = ['\\begin_layout Standard', '\\noindent',
605 '\\begin_inset ERT', 'status collapsed', '',
606 '\\begin_layout Plain Layout', '', '', '\\backslash',
608 '\\end_layout', '', '\\begin_layout Plain Layout', '']
610 i = find_token(document.body, "\\begin_layout Verbatim", i)
613 j = find_end_of_layout(document.body, i)
615 document.warning("Malformed lyx document: Can't find end of Verbatim layout")
618 # delete all line breaks insets (there are no other insets)
621 n = find_token(document.body, "\\begin_inset Newline newline", l)
623 n = find_token(document.body, "\\begin_inset Newline linebreak", l)
626 m = find_end_of_inset(document.body, n)
627 del(document.body[m:m+1])
628 document.body[n:n+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
631 # consecutive verbatim environments need to be connected
632 k = find_token(document.body, "\\begin_layout Verbatim", j)
633 if k == j + 2 and consecutive == False:
635 document.body[j:j+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
636 document.body[i:i+1] = subst_begin
638 if k == j + 2 and consecutive == True:
639 document.body[j:j+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
640 del(document.body[i:i+1])
642 if k != j + 2 and consecutive == True:
643 document.body[j:j+1] = subst_end
644 # the next paragraph must not be indented
645 document.body[j+19:j+19] = ['\\noindent']
646 del(document.body[i:i+1])
650 document.body[j:j+1] = subst_end
651 # the next paragraph must not be indented
652 document.body[j+19:j+19] = ['\\noindent']
653 document.body[i:i+1] = subst_begin
656 def revert_tipa(document):
657 " Revert native TIPA insets to mathed or ERT. "
660 i = find_token(document.body, "\\begin_inset IPA", i)
663 j = find_end_of_inset(document.body, i)
665 document.warning("Malformed lyx document: Can't find end of IPA inset")
669 n = find_token(document.body, "\\begin_layout", i, j)
671 document.warning("Malformed lyx document: IPA inset has no embedded layout")
674 m = find_end_of_layout(document.body, n)
676 document.warning("Malformed lyx document: Can't find end of embedded layout")
679 content = document.body[n+1:m]
680 p = find_token(document.body, "\\begin_layout", m, j)
681 if p != -1 or len(content) > 1:
683 content = document.body[i+1:j]
685 # IPA insets with multiple pars need to be wrapped by \begin{IPA}...\end{IPA}
686 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}")
687 add_to_preamble(document, ["\\usepackage{tipa,tipx}"])
689 # single-par IPA insets can be reverted to mathed
690 document.body[i:j+1] = ["\\begin_inset Formula $\\text{\\textipa{" + content[0] + "}}$", "\\end_inset"]
694 def revert_cell_rotation(document):
695 "Revert cell rotations to TeX-code"
697 load_rotating = False
701 # first, let's find out if we need to do anything
702 i = find_token(document.body, '<cell ', i)
705 j = document.body[i].find('rotate="')
707 k = document.body[i].find('"', j + 8)
708 value = document.body[i][j + 8 : k]
710 rgx = re.compile(r' rotate="[^"]+?"')
711 # remove rotate option
712 document.body[i] = rgx.sub('', document.body[i])
714 rgx = re.compile(r' rotate="[^"]+?"')
715 document.body[i] = rgx.sub('rotate="true"', document.body[i])
717 rgx = re.compile(r' rotate="[^"]+?"')
719 # remove rotate option
720 document.body[i] = rgx.sub('', document.body[i])
722 document.body[i + 5 : i + 5] = \
723 put_cmd_in_ert("\\end{turn}")
724 document.body[i + 4 : i + 4] = \
725 put_cmd_in_ert("\\begin{turn}{" + value + "}")
731 add_to_preamble(document, ["\\@ifundefined{turnbox}{\usepackage{rotating}}{}"])
734 def convert_cell_rotation(document):
735 'Convert cell rotation statements from "true" to "90"'
739 # first, let's find out if we need to do anything
740 i = find_token(document.body, '<cell ', i)
743 j = document.body[i].find('rotate="true"')
745 rgx = re.compile(r'rotate="[^"]+?"')
746 # convert "true" to "90"
747 document.body[i] = rgx.sub('rotate="90"', document.body[i])
752 def revert_table_rotation(document):
753 "Revert table rotations to TeX-code"
755 load_rotating = False
759 # first, let's find out if we need to do anything
760 i = find_token(document.body, '<features ', i)
763 j = document.body[i].find('rotate="')
765 end_table = find_token(document.body, '</lyxtabular>', j)
766 k = document.body[i].find('"', j + 8)
767 value = document.body[i][j + 8 : k]
769 rgx = re.compile(r' rotate="[^"]+?"')
770 # remove rotate option
771 document.body[i] = rgx.sub('', document.body[i])
773 rgx = re.compile(r'rotate="[^"]+?"')
774 document.body[i] = rgx.sub('rotate="true"', document.body[i])
776 rgx = re.compile(r' rotate="[^"]+?"')
778 # remove rotate option
779 document.body[i] = rgx.sub('', document.body[i])
781 document.body[end_table + 3 : end_table + 3] = \
782 put_cmd_in_ert("\\end{turn}")
783 document.body[i - 2 : i - 2] = \
784 put_cmd_in_ert("\\begin{turn}{" + value + "}")
790 add_to_preamble(document, ["\\@ifundefined{turnbox}{\usepackage{rotating}}{}"])
793 def convert_table_rotation(document):
794 'Convert table rotation statements from "true" to "90"'
798 # first, let's find out if we need to do anything
799 i = find_token(document.body, '<features ', i)
802 j = document.body[i].find('rotate="true"')
804 rgx = re.compile(r'rotate="[^"]+?"')
805 # convert "true" to "90"
806 document.body[i] = rgx.sub('rotate="90"', document.body[i])
811 def convert_listoflistings(document):
812 'Convert ERT \lstlistoflistings to TOC lstlistoflistings inset'
813 # We can support roundtrip because the command is so simple
816 i = find_token(document.body, "\\begin_inset ERT", i)
819 j = find_end_of_inset(document.body, i)
821 document.warning("Malformed lyx document: Can't find end of ERT inset")
824 ert = get_ert(document.body, i)
825 if ert == "\\lstlistoflistings{}":
826 document.body[i:j] = ["\\begin_inset CommandInset toc", "LatexCommand lstlistoflistings", ""]
832 def revert_listoflistings(document):
833 'Convert TOC lstlistoflistings inset to ERT lstlistoflistings'
836 i = find_token(document.body, "\\begin_inset CommandInset toc", i)
839 if document.body[i+1] == "LatexCommand lstlistoflistings":
840 j = find_end_of_inset(document.body, i)
842 document.warning("Malformed lyx document: Can't find end of TOC inset")
845 subst = put_cmd_in_ert("\\lstlistoflistings{}")
846 document.body[i:j+1] = subst
847 add_to_preamble(document, ["\\usepackage{listings}"])
851 def convert_use_amssymb(document):
852 "insert use_package amssymb"
853 regexp = re.compile(r'(\\use_package\s+amsmath)')
854 i = find_re(document.header, regexp, 0)
856 document.warning("Malformed LyX document: Can't find \\use_package amsmath.")
858 value = get_value(document.header, "\\use_package" , i).split()[1]
861 useamsmath = int(value)
863 document.warning("Invalid \\use_package amsmath: " + value + ". Assuming auto.")
865 j = find_token(document.preamble, "\\usepackage{amssymb}", 0)
867 document.header.insert(i + 1, "\\use_package amssymb %d" % useamsmath)
869 document.header.insert(i + 1, "\\use_package amssymb 2")
870 del document.preamble[j]
873 def revert_use_amssymb(document):
874 "remove use_package amssymb"
875 regexp1 = re.compile(r'(\\use_package\s+amsmath)')
876 regexp2 = re.compile(r'(\\use_package\s+amssymb)')
877 i = find_re(document.header, regexp1, 0)
878 j = find_re(document.header, regexp2, 0)
879 value1 = "1" # default is auto
880 value2 = "1" # default is auto
882 value1 = get_value(document.header, "\\use_package" , i).split()[1]
884 value2 = get_value(document.header, "\\use_package" , j).split()[1]
885 del document.header[j]
886 if value1 != value2 and value2 == "2": # on
887 add_to_preamble(document, ["\\usepackage{amssymb}"])
890 def revert_ancientgreek(document):
891 "Set the document language for ancientgreek to greek"
893 if document.language == "ancientgreek":
894 document.language = "greek"
895 i = find_token(document.header, "\\language", 0)
897 document.header[i] = "\\language greek"
900 j = find_token(document.body, "\\lang ancientgreek", j)
904 document.body[j] = document.body[j].replace("\\lang ancientgreek", "\\lang greek")
908 def revert_languages(document):
909 "Set the document language for new supported languages to English"
912 "coptic", "divehi", "hindi", "kurmanji", "lao", "marathi", "occitan", "sanskrit",
913 "syriac", "tamil", "telugu", "urdu"
915 for n in range(len(languages)):
916 if document.language == languages[n]:
917 document.language = "english"
918 i = find_token(document.header, "\\language", 0)
920 document.header[i] = "\\language english"
922 while j < len(document.body):
923 j = find_token(document.body, "\\lang " + languages[n], j)
925 document.body[j] = document.body[j].replace("\\lang " + languages[n], "\\lang english")
928 j = len(document.body)
931 def convert_armenian(document):
932 "Use polyglossia and thus non-TeX fonts for Armenian"
934 if document.language == "armenian":
935 i = find_token(document.header, "\\use_non_tex_fonts", 0)
937 document.header[i] = "\\use_non_tex_fonts true"
940 def revert_armenian(document):
941 "Use ArmTeX and thus TeX fonts for Armenian"
943 if document.language == "armenian":
944 i = find_token(document.header, "\\use_non_tex_fonts", 0)
946 document.header[i] = "\\use_non_tex_fonts false"
949 def revert_libertine(document):
950 " Revert native libertine font definition to LaTeX "
952 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
953 i = find_token(document.header, "\\font_roman libertine", 0)
956 j = find_token(document.header, "\\font_osf true", 0)
959 preamble = "\\usepackage"
961 document.header[j] = "\\font_osf false"
963 preamble += "[lining]"
964 preamble += "{libertine-type1}"
965 add_to_preamble(document, [preamble])
966 document.header[i] = "\\font_roman default"
969 def revert_txtt(document):
970 " Revert native txtt font definition to LaTeX "
972 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
973 i = find_token(document.header, "\\font_typewriter txtt", 0)
975 preamble = "\\renewcommand{\\ttdefault}{txtt}"
976 add_to_preamble(document, [preamble])
977 document.header[i] = "\\font_typewriter default"
980 def revert_mathdesign(document):
981 " Revert native mathdesign font definition to LaTeX "
983 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
989 i = find_token(document.header, "\\font_roman", 0)
992 val = get_value(document.header, "\\font_roman", i)
993 if val in mathdesign_dict.keys():
994 preamble = "\\usepackage[%s" % mathdesign_dict[val]
996 j = find_token(document.header, "\\font_osf true", 0)
999 document.header[j] = "\\font_osf false"
1000 l = find_token(document.header, "\\font_sc true", 0)
1003 document.header[l] = "\\font_sc false"
1005 preamble += ",expert"
1006 preamble += "]{mathdesign}"
1007 add_to_preamble(document, [preamble])
1008 document.header[i] = "\\font_roman default"
1011 def revert_texgyre(document):
1012 " Revert native TeXGyre font definition to LaTeX "
1014 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1015 texgyre_fonts = ["tgadventor", "tgbonum", "tgchorus", "tgcursor", \
1016 "tgheros", "tgpagella", "tgschola", "tgtermes"]
1017 i = find_token(document.header, "\\font_roman", 0)
1019 val = get_value(document.header, "\\font_roman", i)
1020 if val in texgyre_fonts:
1021 preamble = "\\usepackage{%s}" % val
1022 add_to_preamble(document, [preamble])
1023 document.header[i] = "\\font_roman default"
1024 i = find_token(document.header, "\\font_sans", 0)
1026 val = get_value(document.header, "\\font_sans", i)
1027 if val in texgyre_fonts:
1028 preamble = "\\usepackage{%s}" % val
1029 add_to_preamble(document, [preamble])
1030 document.header[i] = "\\font_sans default"
1031 i = find_token(document.header, "\\font_typewriter", 0)
1033 val = get_value(document.header, "\\font_typewriter", i)
1034 if val in texgyre_fonts:
1035 preamble = "\\usepackage{%s}" % val
1036 add_to_preamble(document, [preamble])
1037 document.header[i] = "\\font_typewriter default"
1040 def revert_ipadeco(document):
1041 " Revert IPA decorations to ERT "
1044 i = find_token(document.body, "\\begin_inset IPADeco", i)
1047 end = find_end_of_inset(document.body, i)
1049 document.warning("Can't find end of inset at line " + str(i))
1052 line = document.body[i]
1053 rx = re.compile(r'\\begin_inset IPADeco (.*)$')
1055 decotype = m.group(1)
1056 if decotype != "toptiebar" and decotype != "bottomtiebar":
1057 document.warning("Invalid IPADeco type: " + decotype)
1060 blay = find_token(document.body, "\\begin_layout Plain Layout", i, end)
1062 document.warning("Can't find layout for inset at line " + str(i))
1065 bend = find_end_of_layout(document.body, blay)
1067 document.warning("Malformed LyX document: Could not find end of IPADeco inset's layout.")
1070 substi = ["\\begin_inset ERT", "status collapsed", "",
1071 "\\begin_layout Plain Layout", "", "", "\\backslash",
1072 decotype + "{", "\\end_layout", "", "\\end_inset"]
1073 substj = ["\\size default", "", "\\begin_inset ERT", "status collapsed", "",
1074 "\\begin_layout Plain Layout", "", "}", "\\end_layout", "", "\\end_inset"]
1075 # do the later one first so as not to mess up the numbering
1076 document.body[bend:end + 1] = substj
1077 document.body[i:blay + 1] = substi
1078 i = end + len(substi) + len(substj) - (end - bend) - (blay - i) - 2
1079 add_to_preamble(document, "\\usepackage{tipa}")
1082 def revert_ipachar(document):
1083 ' Revert \\IPAChar to ERT '
1086 while i < len(document.body):
1087 m = re.match(r'(.*)\\IPAChar \\(\w+\{\w+\})(.*)', document.body[i])
1091 ipachar = m.group(2)
1094 '\\begin_inset ERT',
1095 'status collapsed', '',
1096 '\\begin_layout Standard',
1097 '', '', '\\backslash',
1102 document.body[i: i+1] = subst
1107 add_to_preamble(document, "\\usepackage{tone}")
1110 def revert_minionpro(document):
1111 " Revert native MinionPro font definition to LaTeX "
1113 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1114 i = find_token(document.header, "\\font_roman minionpro", 0)
1117 j = find_token(document.header, "\\font_osf true", 0)
1120 preamble = "\\usepackage"
1122 document.header[j] = "\\font_osf false"
1125 preamble += "{MinionPro}"
1126 add_to_preamble(document, [preamble])
1127 document.header[i] = "\\font_roman default"
1130 def revert_mathfonts(document):
1131 " Revert native math font definitions to LaTeX "
1133 i = find_token(document.header, "\\font_math", 0)
1136 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1137 val = get_value(document.header, "\\font_math", i)
1138 if val == "eulervm":
1139 add_to_preamble(document, "\\usepackage{eulervm}")
1140 elif val == "default":
1142 "lmodern": "\\renewcommand{\\rmdefault}{lmr}",
1143 "minionpro": "\\usepackage[onlytext,lf]{MinionPro}",
1144 "minionpro-osf": "\\usepackage[onlytext]{MinionPro}",
1145 "palatino": "\\renewcommand{\\rmdefault}{ppl}",
1146 "palatino-osf": "\\renewcommand{\\rmdefault}{pplj}",
1147 "times": "\\renewcommand{\\rmdefault}{ptm}",
1148 "utopia": "\\renewcommand{\\rmdefault}{futs}",
1149 "utopia-osf": "\\renewcommand{\\rmdefault}{futj}",
1151 j = find_token(document.header, "\\font_roman", 0)
1153 rm = get_value(document.header, "\\font_roman", j)
1154 k = find_token(document.header, "\\font_osf true", 0)
1157 if rm in mathfont_dict.keys():
1158 add_to_preamble(document, mathfont_dict[rm])
1159 document.header[j] = "\\font_roman default"
1161 document.header[k] = "\\font_osf false"
1162 del document.header[i]
1165 def revert_mdnomath(document):
1166 " Revert mathdesign and fourier without math "
1168 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1170 "md-charter": "mdbch",
1171 "md-utopia": "mdput",
1172 "md-garamond": "mdugm"
1174 i = find_token(document.header, "\\font_roman", 0)
1177 val = get_value(document.header, "\\font_roman", i)
1178 if val in mathdesign_dict.keys():
1179 j = find_token(document.header, "\\font_math", 0)
1181 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1182 mval = get_value(document.header, "\\font_math", j)
1183 if mval == "default":
1184 document.header[i] = "\\font_roman default"
1185 add_to_preamble(document, "\\renewcommand{\\rmdefault}{%s}" % mathdesign_dict[val])
1187 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1190 def convert_mdnomath(document):
1191 " Change mathdesign font name "
1193 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1195 "mdbch": "md-charter",
1196 "mdput": "md-utopia",
1197 "mdugm": "md-garamond"
1199 i = find_token(document.header, "\\font_roman", 0)
1202 val = get_value(document.header, "\\font_roman", i)
1203 if val in mathdesign_dict.keys():
1204 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1207 def revert_newtxmath(document):
1208 " Revert native newtxmath definitions to LaTeX "
1210 i = find_token(document.header, "\\font_math", 0)
1213 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1214 val = get_value(document.header, "\\font_math", i)
1216 "libertine-ntxm": "\\usepackage[libertine]{newtxmath}",
1217 "minion-ntxm": "\\usepackage[minion]{newtxmath}",
1218 "newtxmath": "\\usepackage{newtxmath}",
1220 if val in mathfont_dict.keys():
1221 add_to_preamble(document, mathfont_dict[val])
1222 document.header[i] = "\\font_math auto"
1225 def revert_biolinum(document):
1226 " Revert native biolinum font definition to LaTeX "
1228 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1229 i = find_token(document.header, "\\font_sans biolinum", 0)
1232 j = find_token(document.header, "\\font_osf true", 0)
1235 preamble = "\\usepackage"
1238 preamble += "{biolinum-type1}"
1239 add_to_preamble(document, [preamble])
1240 document.header[i] = "\\font_sans default"
1243 def revert_uop(document):
1244 " Revert native URW Classico (Optima) font definition to LaTeX "
1246 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1247 i = find_token(document.header, "\\font_sans uop", 0)
1249 preamble = "\\renewcommand{\\sfdefault}{uop}"
1250 add_to_preamble(document, [preamble])
1251 document.header[i] = "\\font_sans default"
1254 def convert_latexargs(document):
1255 " Convert InsetArgument to new syntax "
1257 if find_token(document.body, "\\begin_inset Argument", 0) == -1:
1261 # A list of layouts (document classes) with only optional or no arguments.
1262 # These can be safely converted to the new syntax
1263 # (I took the liberty to add some of my personal layouts/modules here; JSP)
1264 safe_layouts = ["aa", "aapaper", "aastex", "achemso", "acmsiggraph", "AEA",
1265 "agu-dtd", "agums", "agutex", "amsart", "amsbook", "apa",
1266 "arab-article", "armenian-article", "article-beamer", "article",
1267 "beamer", "book", "broadway", "chess", "cl2emult", "ctex-article",
1268 "ctex-book", "ctex-report", "dinbrief", "docbook-book", "docbook-chapter",
1269 "docbook", "docbook-section", "doublecol-new", "dtk", "ectaart", "egs",
1270 "elsarticle", "elsart", "entcs", "europecv", "extarticle", "extbook",
1271 "extletter", "extreport", "foils", "frletter", "g-brief2", "g-brief",
1272 "heb-article", "heb-letter", "hollywood", "IEEEtran", "ijmpc", "ijmpd",
1273 "iopart", "isprs", "jarticle", "jasatex", "jbook", "jgrga", "jreport",
1274 "jsarticle", "jsbeamer", "jsbook", "jss", "kluwer", "latex8", "letter", "lettre",
1275 "literate-article", "literate-book", "literate-report", "llncs", "ltugboat",
1276 "memoir", "moderncv", "mwart", "mwbk", "mwrep", "paper", "powerdot",
1277 "recipebook", "report", "revtex4", "revtex", "scrartcl", "scrarticle-beamer",
1278 "scrbook", "scrlettr", "scrlttr2", "scrreprt", "seminar", "siamltex",
1279 "sigplanconf", "simplecv", "singlecol", "singlecol-new", "slides", "spie",
1280 "svglobal3", "svglobal", "svjog", "svmono", "svmult", "svprobth", "tarticle",
1281 "tbook", "treport", "tufte-book", "tufte-handout"]
1282 # A list of "safe" modules, same as above
1283 safe_modules = ["biblatex", "beameraddons", "beamersession", "braille", "customHeadersFooters",
1284 "endnotes", "enumitem", "eqs-within-sections", "figs-within-sections", "fix-cm",
1285 "fixltx2e", "foottoend", "hanging", "jscharstyles", "knitr", "lilypond",
1286 "linguistics", "linguisticx", "logicalmkup", "minimalistic", "nomindex", "noweb",
1287 "pdfcomment", "sweave", "tabs-within-sections", "theorems-ams-bytype",
1288 "theorems-ams-extended-bytype", "theorems-ams-extended", "theorems-ams", "theorems-bytype",
1289 "theorems-chap-bytype", "theorems-chap", "theorems-named", "theorems-sec-bytype",
1290 "theorems-sec", "theorems-starred", "theorems-std", "todonotes"]
1291 # Modules we need to take care of
1292 caveat_modules = ["initials"]
1293 # information about the relevant styles in caveat_modules (number of opt and req args)
1294 # use this if we get more caveat_modules. For now, use hard coding (see below).
1295 # initials = [{'Layout' : 'Initial', 'opt' : 1, 'req' : 1}]
1297 # Is this a known safe layout?
1298 safe_layout = document.textclass in safe_layouts
1300 document.warning("Lyx2lyx knows nothing about textclass '%s'. "
1301 "Please check if short title insets have been converted correctly."
1302 % document.textclass)
1303 # Do we use unsafe or unknown modules
1304 mods = document.get_module_list()
1305 unknown_modules = False
1306 used_caveat_modules = list()
1308 if mod in safe_modules:
1310 if mod in caveat_modules:
1311 used_caveat_modules.append(mod)
1313 unknown_modules = True
1314 document.warning("Lyx2lyx knows nothing about module '%s'. "
1315 "Please check if short title insets have been converted correctly."
1320 i = find_token(document.body, "\\begin_inset Argument", i)
1324 if not safe_layout or unknown_modules:
1325 # We cannot do more here since we have no access to this layout.
1326 # InsetArgument itself will do the real work
1327 # (see InsetArgument::updateBuffer())
1328 document.body[i] = "\\begin_inset Argument 999"
1332 # Find containing paragraph layout
1333 parent = get_containing_layout(document.body, i)
1335 document.warning("Malformed lyx document: Can't find parent paragraph layout")
1342 if len(used_caveat_modules) > 0:
1343 # We know for now that this must be the initials module with the Initial layout
1344 # If we get more such modules, we need some automating.
1345 if parent[0] == "Initial":
1346 # Layout has 1 opt and 1 req arg.
1347 # Count the actual arguments
1349 for p in range(parbeg, parend):
1350 if document.body[p] == "\\begin_inset Argument":
1355 # Collect all arguments in this paragraph
1357 for p in range(parbeg, parend):
1358 if document.body[p] == "\\begin_inset Argument":
1360 if allowed_opts != -1:
1361 # We have less arguments than opt + required.
1362 # required must take precedence.
1363 if argnr > allowed_opts and argnr < first_req:
1365 document.body[p] = "\\begin_inset Argument %d" % argnr
1369 def revert_latexargs(document):
1370 " Revert InsetArgument to old syntax "
1373 rx = re.compile(r'^\\begin_inset Argument (\d+)$')
1376 # Search for Argument insets
1377 i = find_token(document.body, "\\begin_inset Argument", i)
1380 m = rx.match(document.body[i])
1382 # No ID: inset already reverted
1385 # Find containing paragraph layout
1386 parent = get_containing_layout(document.body, i)
1388 document.warning("Malformed lyx document: Can't find parent paragraph layout")
1393 realparbeg = parent[3]
1394 # Collect all arguments in this paragraph
1396 for p in range(parbeg, parend):
1397 m = rx.match(document.body[p])
1399 val = int(m.group(1))
1400 j = find_end_of_inset(document.body, p)
1401 # Revert to old syntax
1402 document.body[p] = "\\begin_inset Argument"
1404 document.warning("Malformed lyx document: Can't find end of Argument inset")
1407 args[val] = document.body[p : j + 1]
1409 realparend = realparend - len(document.body[p : j + 1])
1410 # Remove arg inset at this position
1411 del document.body[p : j + 1]
1414 # Now sort the arg insets
1416 for f in sorted(args):
1419 # Insert the sorted arg insets at paragraph begin
1420 document.body[realparbeg : realparbeg] = subst
1422 i = realparbeg + 1 + len(subst)
1425 def revert_Argument_to_TeX_brace(document, line, n, nmax, environment):
1427 Reverts an InsetArgument to TeX-code
1429 revert_Argument_to_TeX_brace(document, LineOfBeginLayout, StartArgument, EndArgument, isEnvironment)
1430 LineOfBeginLayout is the line of the \begin_layout statement
1431 StartArgument is the number of the first argument that needs to be converted
1432 EndArgument is the number of the last argument that needs to be converted or the last defined one
1433 isEnvironment must be true, if the layout id for a LaTeX environment
1436 while lineArg != -1 and n < nmax + 1:
1437 lineArg = find_token(document.body, "\\begin_inset Argument " + str(n), line)
1439 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", lineArg)
1440 # we have to assure that no other inset is in the Argument
1441 beginInset = find_token(document.body, "\\begin_inset", beginPlain)
1442 endInset = find_token(document.body, "\\end_inset", beginPlain)
1445 while beginInset < endInset and beginInset != -1:
1446 beginInset = find_token(document.body, "\\begin_inset", k)
1447 endInset = find_token(document.body, "\\end_inset", l)
1450 if environment == False:
1451 document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("}{")
1452 del(document.body[lineArg : beginPlain + 1])
1454 document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("}")
1455 document.body[lineArg : beginPlain + 1] = put_cmd_in_ert("{")
1459 def convert_TeX_brace_to_Argument(document, line, n, nmax, inset, environment):
1461 Converts TeX code for mandatory arguments to an InsetArgument
1462 The conversion of TeX code for optional arguments must be done with another routine
1463 !!! Be careful if the braces are different in your case as expected here:
1464 - "}{" separates mandatory arguments of commands
1465 - "}" + "{" separates mandatory arguments of commands
1466 - "}" + " " + "{" separates mandatory arguments of commands
1467 - { and } surround a mandatory argument of an environment
1469 convert_TeX_brace_to_Argument(document, LineOfBeginLayout/Inset, StartArgument, EndArgument, isInset, isEnvironment)
1470 LineOfBeginLayout/Inset is the line of the \begin_layout or \begin_inset statement
1471 StartArgument is the number of the first ERT that needs to be converted
1472 EndArgument is the number of the last ERT that needs to be converted
1473 isInset must be true, if braces inside an InsetLayout needs to be converted
1474 isEnvironment must be true, if the layout is for a LaTeX environment
1476 Todo: this routine can currently handle only one mandatory argument of environments
1481 while lineERT != -1 and n < nmax + 1:
1482 lineERT = find_token(document.body, "\\begin_inset ERT", lineERT)
1483 if environment == False and lineERT != -1:
1484 bracePair = find_token(document.body, "}{", lineERT)
1485 # assure that the "}{" is in this ERT
1486 if bracePair == lineERT + 5:
1487 end = find_token(document.body, "\\end_inset", bracePair)
1488 document.body[lineERT : end + 1] = ["\\end_layout", "", "\\end_inset"]
1490 # in the case that n > 1 we have optional arguments before
1491 # therefore detect them if any
1493 # first check if there is an argument
1494 lineArg = find_token(document.body, "\\begin_inset Argument", line)
1495 if lineArg < lineERT and lineArg != -1:
1496 # we have an argument, so now search backwards for its end
1497 # we must now assure that we don't find other insets like e.g. a newline
1498 endInsetArg = lineERT
1499 endLayoutArg = endInsetArg
1500 while endInsetArg != endLayoutArg + 2 and endInsetArg != -1:
1501 endInsetArg = endInsetArg - 1
1502 endLayoutArg = endInsetArg
1503 endInsetArg = find_token_backwards(document.body, "\\end_inset", endInsetArg)
1504 endLayoutArg = find_token_backwards(document.body, "\\end_layout", endLayoutArg)
1505 line = endInsetArg + 1
1507 document.body[line + 1 : line + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1509 document.body[line + 4 : line + 4] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1511 document.body[endn : endn] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1515 # now check the case that we have "}" + "{" in two ERTs
1517 endBrace = find_token(document.body, "}", lineERT)
1518 if endBrace == lineERT + 5:
1519 beginBrace = find_token(document.body, "{", endBrace)
1520 # assure that the ERTs are consecutive (11 or 12 depending if there is a space between the ERTs or not)
1521 if beginBrace == endBrace + 11 or beginBrace == endBrace + 12:
1522 end = find_token(document.body, "\\end_inset", beginBrace)
1523 document.body[lineERT : end + 1] = ["\\end_layout", "", "\\end_inset"]
1525 # in the case that n > 1 we have optional arguments before
1526 # therefore detect them if any
1528 # first check if there is an argument
1529 lineArg = find_token(document.body, "\\begin_inset Argument", line)
1530 if lineArg < lineERT and lineArg != -1:
1531 # we have an argument, so now search backwards for its end
1532 # we must now assure that we don't find other insets like e.g. a newline
1533 endInsetArg = lineERT
1534 endLayoutArg = endInsetArg
1535 while endInsetArg != endLayoutArg + 2 and endInsetArg != -1:
1536 endInsetArg = endInsetArg - 1
1537 endLayoutArg = endInsetArg
1538 endInsetArg = find_token_backwards(document.body, "\\end_inset", endInsetArg)
1539 endLayoutArg = find_token_backwards(document.body, "\\end_layout", endLayoutArg)
1540 line = endInsetArg + 1
1542 document.body[line + 1 : line + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1544 document.body[line + 4 : line + 4] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1546 document.body[endn : endn] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1549 # set the line where the next argument will be inserted
1550 if beginBrace == endBrace + 11:
1555 lineERT = lineERT + 1
1556 if environment == True and lineERT != -1:
1557 opening = find_token(document.body, "{", lineERT)
1558 if opening == lineERT + 5: # assure that the "{" is in this ERT
1559 end = find_token(document.body, "\\end_inset", opening)
1560 document.body[lineERT : end + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1562 lineERT2 = find_token(document.body, "\\begin_inset ERT", lineERT)
1563 closing = find_token(document.body, "}", lineERT2)
1564 if closing == lineERT2 + 5: # assure that the "}" is in this ERT
1565 end2 = find_token(document.body, "\\end_inset", closing)
1566 document.body[lineERT2 : end2 + 1] = ["\\end_layout", "", "\\end_inset"]
1568 lineERT = lineERT + 1
1571 def revert_IEEEtran(document):
1573 Reverts InsetArgument of
1576 Biography without photo
1579 if document.textclass == "IEEEtran":
1586 i = find_token(document.body, "\\begin_layout Page headings", i)
1588 revert_Argument_to_TeX_brace(document, i, 1, 1, False)
1591 i2 = find_token(document.body, "\\begin_inset Flex Paragraph Start", i2)
1593 revert_Argument_to_TeX_brace(document, i2, 1, 1, False)
1596 j = find_token(document.body, "\\begin_layout Biography without photo", j)
1598 revert_Argument_to_TeX_brace(document, j, 1, 1, True)
1601 k = find_token(document.body, "\\begin_layout Biography", k)
1602 kA = find_token(document.body, "\\begin_layout Biography without photo", k)
1603 if k == kA and k != -1:
1607 # start with the second argument, therefore 2
1608 revert_Argument_to_TeX_brace(document, k, 2, 2, True)
1610 if i == -1 and i2 == -1 and j == -1 and k == -1:
1614 def revert_IEEEtran_2(document):
1616 Reverts Flex Paragraph Start to TeX-code
1618 if document.textclass == "IEEEtran":
1622 begin = find_token(document.body, "\\begin_inset Flex Paragraph Start", begin)
1624 end1 = find_end_of_inset(document.body, begin)
1625 document.body[end1 - 2 : end1 + 1] = put_cmd_in_ert("}")
1626 document.body[begin : begin + 4] = put_cmd_in_ert("\\IEEEPARstart{")
1632 def convert_IEEEtran(document):
1637 Biography without photo
1640 if document.textclass == "IEEEtran":
1646 i = find_token(document.body, "\\begin_layout Page headings", i)
1648 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1651 j = find_token(document.body, "\\begin_layout Biography without photo", j)
1653 convert_TeX_brace_to_Argument(document, j, 1, 1, False, True)
1656 # assure that we don't handle Biography Biography without photo
1657 k = find_token(document.body, "\\begin_layout Biography", k)
1658 kA = find_token(document.body, "\\begin_layout Biography without photo", k - 1)
1659 if k == kA and k != -1:
1663 # the argument we want to convert is the second one
1664 convert_TeX_brace_to_Argument(document, k, 2, 2, False, True)
1666 if i == -1 and j == -1 and k == -1:
1670 def revert_AASTeX(document):
1671 " Reverts InsetArgument of Altaffilation to TeX-code "
1672 if document.textclass == "aastex":
1676 i = find_token(document.body, "\\begin_layout Altaffilation", i)
1678 revert_Argument_to_TeX_brace(document, i, 1, 1, False)
1684 def convert_AASTeX(document):
1685 " Converts ERT of Altaffilation to InsetArgument "
1686 if document.textclass == "aastex":
1690 i = find_token(document.body, "\\begin_layout Altaffilation", i)
1692 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1698 def revert_AGUTeX(document):
1699 " Reverts InsetArgument of Author affiliation to TeX-code "
1700 if document.textclass == "agutex":
1704 i = find_token(document.body, "\\begin_layout Author affiliation", i)
1706 revert_Argument_to_TeX_brace(document, i, 1, 1, False)
1712 def convert_AGUTeX(document):
1713 " Converts ERT of Author affiliation to InsetArgument "
1714 if document.textclass == "agutex":
1718 i = find_token(document.body, "\\begin_layout Author affiliation", i)
1720 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1726 def revert_IJMP(document):
1727 " Reverts InsetArgument of MarkBoth to TeX-code "
1728 if document.textclass == "ijmpc" or document.textclass == "ijmpd":
1732 i = find_token(document.body, "\\begin_layout MarkBoth", i)
1734 revert_Argument_to_TeX_brace(document, i, 1, 1, False)
1740 def convert_IJMP(document):
1741 " Converts ERT of MarkBoth to InsetArgument "
1742 if document.textclass == "ijmpc" or document.textclass == "ijmpd":
1746 i = find_token(document.body, "\\begin_layout MarkBoth", i)
1748 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1754 def revert_SIGPLAN(document):
1755 " Reverts InsetArguments of SIGPLAN to TeX-code "
1756 if document.textclass == "sigplanconf":
1761 i = find_token(document.body, "\\begin_layout Conference", i)
1763 revert_Argument_to_TeX_brace(document, i, 1, 1, False)
1766 j = find_token(document.body, "\\begin_layout Author", j)
1768 revert_Argument_to_TeX_brace(document, j, 1, 2, False)
1770 if i == -1 and j == -1:
1774 def convert_SIGPLAN(document):
1775 " Converts ERT of SIGPLAN to InsetArgument "
1776 if document.textclass == "sigplanconf":
1781 i = find_token(document.body, "\\begin_layout Conference", i)
1783 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1786 j = find_token(document.body, "\\begin_layout Author", j)
1788 convert_TeX_brace_to_Argument(document, j, 1, 2, False, False)
1790 if i == -1 and j == -1:
1794 def revert_SIGGRAPH(document):
1795 " Reverts InsetArgument of Flex CRcat to TeX-code "
1796 if document.textclass == "acmsiggraph":
1800 i = find_token(document.body, "\\begin_inset Flex CRcat", i)
1802 revert_Argument_to_TeX_brace(document, i, 1, 3, False)
1808 def convert_SIGGRAPH(document):
1809 " Converts ERT of Flex CRcat to InsetArgument "
1810 if document.textclass == "acmsiggraph":
1814 i = find_token(document.body, "\\begin_inset Flex CRcat", i)
1816 convert_TeX_brace_to_Argument(document, i, 1, 3, True, False)
1822 def revert_EuropeCV(document):
1823 " Reverts InsetArguments of europeCV to TeX-code "
1824 if document.textclass == "europecv":
1831 i = find_token(document.body, "\\begin_layout Item", i)
1833 revert_Argument_to_TeX_brace(document, i, 2, 2, False)
1836 j = find_token(document.body, "\\begin_layout BulletedItem", j)
1838 revert_Argument_to_TeX_brace(document, j, 2, 2, False)
1841 k = find_token(document.body, "\\begin_layout Language", k)
1843 revert_Argument_to_TeX_brace(document, k, 2, 6, False)
1846 m = find_token(document.body, "\\begin_layout LastLanguage", m)
1848 revert_Argument_to_TeX_brace(document, m, 2, 6, False)
1850 if i == -1 and j == -1 and k == -1 and m == -1:
1854 def convert_EuropeCV(document):
1855 " Converts ERT of europeCV to InsetArgument "
1856 if document.textclass == "europecv":
1863 i = find_token(document.body, "\\begin_layout Item", i)
1865 convert_TeX_brace_to_Argument(document, i, 2, 2, False, False)
1868 j = find_token(document.body, "\\begin_layout BulletedItem", j)
1870 convert_TeX_brace_to_Argument(document, j, 2, 2, False, False)
1873 k = find_token(document.body, "\\begin_layout Language", k)
1875 convert_TeX_brace_to_Argument(document, k, 2, 6, False, False)
1878 m = find_token(document.body, "\\begin_layout LastLanguage", m)
1880 convert_TeX_brace_to_Argument(document, m, 2, 6, False, False)
1882 if i == -1 and j == -1 and k == -1 and m == -1:
1886 def revert_ModernCV(document):
1887 " Reverts InsetArguments of modernCV to TeX-code "
1888 if document.textclass == "moderncv":
1896 i = find_token(document.body, "\\begin_layout DoubleItem", i)
1898 revert_Argument_to_TeX_brace(document, i, 1, 3, False)
1901 j = find_token(document.body, "\\begin_layout Entry", j)
1903 revert_Argument_to_TeX_brace(document, j, 1, 5, False)
1906 k = find_token(document.body, "\\begin_layout Item", k)
1908 revert_Argument_to_TeX_brace(document, k, 1, 1, False)
1911 m = find_token(document.body, "\\begin_layout ItemWithComment", m)
1913 revert_Argument_to_TeX_brace(document, m, 1, 2, False)
1914 document.body[m] = document.body[m].replace("\\begin_layout ItemWithComment", "\\begin_layout Language")
1917 o = find_token(document.body, "\\begin_layout DoubleItem", o)
1919 revert_Argument_to_TeX_brace(document, o, 1, 3, False)
1920 document.body[o] = document.body[o].replace("\\begin_layout DoubleItem", "\\begin_layout Computer")
1922 if i == -1 and j == -1 and k == -1 and m == -1 and o == -1:
1926 def convert_ModernCV(document):
1927 " Converts ERT of modernCV to InsetArgument "
1928 if document.textclass == "moderncv":
1936 i = find_token(document.body, "\\begin_layout DoubleItem", i)
1938 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1939 document.body[o] = document.body[o].replace("\\begin_layout DoubleItem", "\\begin_layout DoubleListItem")
1942 j = find_token(document.body, "\\begin_layout Entry", j)
1944 convert_TeX_brace_to_Argument(document, j, 1, 5, False, False)
1947 k = find_token(document.body, "\\begin_layout Item", k)
1949 convert_TeX_brace_to_Argument(document, k, 1, 1, False, False)
1952 m = find_token(document.body, "\\begin_layout Language", m)
1954 convert_TeX_brace_to_Argument(document, m, 1, 2, False, False)
1956 if i == -1 and j == -1 and k == -1 and m == -1:
1960 def revert_Initials(document):
1961 " Reverts InsetArgument of Initial to TeX-code "
1965 i = find_token(document.body, "\\begin_layout Initial", i)
1967 # first arg (optional) and second arg (first mandatory) are supported in LyX 2.0.x
1968 revert_Argument_to_TeX_brace(document, i, 3, 3, False)
1974 def convert_Initials(document):
1975 " Converts ERT of Initial to InsetArgument "
1979 i = find_token(document.body, "\\begin_layout Initial", i)
1981 convert_TeX_brace_to_Argument(document, i, 3, 3, False, False)
1987 def revert_literate(document):
1988 " Revert Literate document to old format "
1989 if del_token(document.header, "noweb", 0):
1990 document.textclass = "literate-" + document.textclass
1993 i = find_token(document.body, "\\begin_layout Chunk", i)
1996 document.body[i] = "\\begin_layout Scrap"
2000 def convert_literate(document):
2001 " Convert Literate document to new format"
2002 i = find_token(document.header, "\\textclass", 0)
2003 if (i != -1) and "literate-" in document.header[i]:
2004 document.textclass = document.header[i].replace("\\textclass literate-", "")
2005 j = find_token(document.header, "\\begin_modules", 0)
2007 document.header.insert(j + 1, "noweb")
2009 document.header.insert(i + 1, "\\end_modules")
2010 document.header.insert(i + 1, "noweb")
2011 document.header.insert(i + 1, "\\begin_modules")
2014 i = find_token(document.body, "\\begin_layout Scrap", i)
2017 document.body[i] = "\\begin_layout Chunk"
2021 def revert_itemargs(document):
2022 " Reverts \\item arguments to TeX-code "
2025 i = find_token(document.body, "\\begin_inset Argument item:", i)
2028 j = find_end_of_inset(document.body, i)
2029 # Find containing paragraph layout
2030 parent = get_containing_layout(document.body, i)
2032 document.warning("Malformed lyx document: Can't find parent paragraph layout")
2036 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2037 endPlain = find_end_of_layout(document.body, beginPlain)
2038 content = document.body[beginPlain + 1 : endPlain]
2039 del document.body[i:j+1]
2040 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2041 document.body[parbeg : parbeg] = subst
2045 def revert_garamondx_newtxmath(document):
2046 " Revert native garamond newtxmath definition to LaTeX "
2048 i = find_token(document.header, "\\font_math", 0)
2051 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
2052 val = get_value(document.header, "\\font_math", i)
2053 if val == "garamondx-ntxm":
2054 add_to_preamble(document, "\\usepackage[garamondx]{newtxmath}")
2055 document.header[i] = "\\font_math auto"
2058 def revert_garamondx(document):
2059 " Revert native garamond font definition to LaTeX "
2061 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
2062 i = find_token(document.header, "\\font_roman garamondx", 0)
2065 j = find_token(document.header, "\\font_osf true", 0)
2068 preamble = "\\usepackage"
2070 preamble += "[osfI]"
2071 preamble += "{garamondx}"
2072 add_to_preamble(document, [preamble])
2073 document.header[i] = "\\font_roman default"
2076 def convert_beamerargs(document):
2077 " Converts beamer arguments to new layout "
2079 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2080 if document.textclass not in beamer_classes:
2083 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
2084 list_layouts = ["Itemize", "Enumerate", "Description"]
2085 rx = re.compile(r'^\\begin_inset Argument (\d+)$')
2089 i = find_token(document.body, "\\begin_inset Argument", i)
2092 # Find containing paragraph layout
2093 parent = get_containing_layout(document.body, i)
2095 document.warning("Malformed lyx document: Can't find parent paragraph layout")
2100 layoutname = parent[0]
2101 for p in range(parbeg, parend):
2102 if layoutname in shifted_layouts:
2103 m = rx.match(document.body[p])
2105 argnr = int(m.group(1))
2107 document.body[p] = "\\begin_inset Argument %d" % argnr
2108 if layoutname == "AgainFrame":
2109 m = rx.match(document.body[p])
2111 document.body[p] = "\\begin_inset Argument 3"
2112 if document.body[p + 4] == "\\begin_inset ERT":
2113 if document.body[p + 9].startswith("<"):
2114 # This is an overlay specification
2116 document.body[p + 9] = document.body[p + 9][1:]
2117 if document.body[p + 9].endswith(">"):
2119 document.body[p + 9] = document.body[p + 9][:-1]
2121 document.body[p] = "\\begin_inset Argument 2"
2122 if layoutname in list_layouts:
2123 m = rx.match(document.body[p])
2125 if m.group(1) == "1":
2126 if document.body[p + 4] == "\\begin_inset ERT":
2127 if document.body[p + 9].startswith("<"):
2128 # This is an overlay specification
2130 document.body[p + 9] = document.body[p + 9][1:]
2131 if document.body[p + 9].endswith(">"):
2133 document.body[p + 9] = document.body[p + 9][:-1]
2134 elif layoutname != "Itemize":
2136 document.body[p] = "\\begin_inset Argument 2"
2140 def convert_againframe_args(document):
2141 " Converts beamer AgainFrame to new layout "
2143 # FIXME: This currently only works if the arguments are in one single ERT
2145 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2146 if document.textclass not in beamer_classes:
2151 i = find_token(document.body, "\\begin_layout AgainFrame", i)
2154 parent = get_containing_layout(document.body, i)
2156 document.warning("Wrong parent layout!")
2160 if document.body[parbeg] == "\\begin_inset ERT":
2161 ertcont = parbeg + 5
2162 if document.body[ertcont].startswith("[<"):
2163 # This is a default overlay specification
2165 document.body[ertcont] = document.body[ertcont][2:]
2166 if document.body[ertcont].endswith(">]"):
2168 document.body[ertcont] = document.body[ertcont][:-2]
2169 elif document.body[ertcont].endswith("]"):
2171 tok = document.body[ertcont].find('>][')
2173 subst = [document.body[ertcont][:tok],
2174 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2175 'status collapsed', '', '\\begin_layout Plain Layout',
2176 document.body[ertcont][tok + 3:-1]]
2177 document.body[ertcont : ertcont + 1] = subst
2178 # Convert to ArgInset
2179 document.body[parbeg] = "\\begin_inset Argument 2"
2182 elif document.body[ertcont].startswith("<"):
2183 # This is an overlay specification
2185 document.body[ertcont] = document.body[ertcont][1:]
2186 if document.body[ertcont].endswith(">"):
2188 document.body[ertcont] = document.body[ertcont][:-1]
2189 # Convert to ArgInset
2190 document.body[parbeg] = "\\begin_inset Argument 1"
2191 elif document.body[ertcont].endswith(">]"):
2193 tok = document.body[ertcont].find('>[<')
2195 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2196 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2197 'status collapsed', '', '\\begin_layout Plain Layout',
2198 document.body[ertcont][tok + 3:-2]]
2199 # Convert to ArgInset
2200 document.body[parbeg] = "\\begin_inset Argument 1"
2201 elif document.body[ertcont].endswith("]"):
2203 tok = document.body[ertcont].find('>[<')
2206 tokk = document.body[ertcont].find('>][')
2208 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2209 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2210 'status collapsed', '', '\\begin_layout Plain Layout',
2211 document.body[ertcont][tok + 3:tokk],
2212 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2213 'status collapsed', '', '\\begin_layout Plain Layout',
2214 document.body[ertcont][tokk + 3:-1]]
2216 tokk = document.body[ertcont].find('>[')
2218 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tokk],
2219 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2220 'status collapsed', '', '\\begin_layout Plain Layout',
2221 document.body[ertcont][tokk + 2:-1]]
2222 # Convert to ArgInset
2223 document.body[parbeg] = "\\begin_inset Argument 1"
2226 elif document.body[ertcont].startswith("["):
2227 # This is an ERT option
2229 document.body[ertcont] = document.body[ertcont][1:]
2230 if document.body[ertcont].endswith("]"):
2232 document.body[ertcont] = document.body[ertcont][:-1]
2233 # Convert to ArgInset
2234 document.body[parbeg] = "\\begin_inset Argument 3"
2240 def convert_corollary_args(document):
2241 " Converts beamer corrolary-style ERT arguments native InsetArgs "
2243 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2244 if document.textclass not in beamer_classes:
2247 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2248 for lay in corollary_layouts:
2251 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2254 parent = get_containing_layout(document.body, i)
2256 document.warning("Wrong parent layout!")
2260 if document.body[parbeg] == "\\begin_inset ERT":
2261 ertcont = parbeg + 5
2262 if document.body[ertcont].startswith("<"):
2263 # This is an overlay specification
2265 document.body[ertcont] = document.body[ertcont][1:]
2266 if document.body[ertcont].endswith(">"):
2268 document.body[ertcont] = document.body[ertcont][:-1]
2269 elif document.body[ertcont].endswith("]"):
2271 tok = document.body[ertcont].find('>[')
2273 subst = [document.body[ertcont][:tok],
2274 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2275 'status collapsed', '', '\\begin_layout Plain Layout',
2276 document.body[ertcont][tok + 2:-1]]
2277 document.body[ertcont : ertcont + 1] = subst
2278 # Convert to ArgInset
2279 document.body[parbeg] = "\\begin_inset Argument 1"
2282 elif document.body[ertcont].startswith("["):
2283 # This is an ERT option
2285 document.body[ertcont] = document.body[ertcont][1:]
2286 if document.body[ertcont].endswith("]"):
2288 document.body[ertcont] = document.body[ertcont][:-1]
2289 # Convert to ArgInset
2290 document.body[parbeg] = "\\begin_inset Argument 2"
2297 def convert_quote_args(document):
2298 " Converts beamer quote style ERT args to native InsetArgs "
2300 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2301 if document.textclass not in beamer_classes:
2304 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2305 for lay in quote_layouts:
2308 i = find_token(document.body, "\\begin_layout " + lay, i)
2311 parent = get_containing_layout(document.body, i)
2313 document.warning("Wrong parent layout!")
2317 if document.body[parbeg] == "\\begin_inset ERT":
2318 if document.body[i + 6].startswith("<"):
2319 # This is an overlay specification
2321 document.body[i + 6] = document.body[i + 6][1:]
2322 if document.body[i + 6].endswith(">"):
2324 document.body[i + 6] = document.body[i + 6][:-1]
2325 # Convert to ArgInset
2326 document.body[i + 1] = "\\begin_inset Argument 1"
2330 def revert_beamerargs(document):
2331 " Reverts beamer arguments to old layout "
2333 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2334 if document.textclass not in beamer_classes:
2338 list_layouts = ["Itemize", "Enumerate", "Description"]
2339 headings = ["Part", "Section", "Section*", "Subsection", "Subsection*",
2340 "Subsubsection", "Subsubsection*", "FrameSubtitle", "NoteItem"]
2341 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2342 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2343 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2346 i = find_token(document.body, "\\begin_inset Argument", i)
2349 # Find containing paragraph layout
2350 parent = get_containing_layout(document.body, i)
2352 document.warning("Malformed lyx document: Can't find parent paragraph layout")
2357 realparbeg = parent[3]
2358 layoutname = parent[0]
2360 for p in range(parbeg, parend):
2364 if layoutname in headings:
2365 m = rx.match(document.body[p])
2369 # Find containing paragraph layout
2370 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2371 endPlain = find_end_of_layout(document.body, beginPlain)
2372 endInset = find_end_of_inset(document.body, p)
2373 argcontent = document.body[beginPlain + 1 : endPlain]
2375 realparend = realparend - len(document.body[p : endInset + 1])
2377 del document.body[p : endInset + 1]
2378 if layoutname == "FrameSubtitle":
2379 pre = put_cmd_in_ert("\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2380 elif layoutname == "NoteItem":
2381 pre = put_cmd_in_ert("\\note<") + argcontent + put_cmd_in_ert(">[item]")
2382 elif layoutname.endswith('*'):
2383 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower()[:-1] + "<") + argcontent + put_cmd_in_ert(">*")
2385 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2386 secarg = find_token(document.body, "\\begin_inset Argument 2", parbeg, parend)
2388 # Find containing paragraph layout
2389 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", secarg)
2390 endPlain = find_end_of_layout(document.body, beginPlain)
2391 endInset = find_end_of_inset(document.body, secarg)
2392 argcontent = document.body[beginPlain + 1 : endPlain]
2394 realparend = realparend - len(document.body[secarg : endInset + 1])
2395 del document.body[secarg : endInset + 1]
2396 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2397 pre += put_cmd_in_ert("{")
2398 document.body[parbeg] = "\\begin_layout Standard"
2399 document.body[realparbeg : realparbeg] = pre
2400 pe = find_end_of_layout(document.body, parbeg)
2401 post = put_cmd_in_ert("}")
2402 document.body[pe : pe] = post
2403 realparend += len(pre) + len(post)
2404 if layoutname == "AgainFrame":
2405 m = rx.match(document.body[p])
2409 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2410 endPlain = find_end_of_layout(document.body, beginPlain)
2411 endInset = find_end_of_inset(document.body, p)
2412 content = document.body[beginPlain + 1 : endPlain]
2414 realparend = realparend - len(document.body[p : endInset + 1])
2416 del document.body[p : endInset + 1]
2417 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2418 document.body[realparbeg : realparbeg] = subst
2419 if layoutname == "Overprint":
2420 m = rx.match(document.body[p])
2424 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2425 endPlain = find_end_of_layout(document.body, beginPlain)
2426 endInset = find_end_of_inset(document.body, p)
2427 content = document.body[beginPlain + 1 : endPlain]
2429 realparend = realparend - len(document.body[p : endInset + 1])
2431 del document.body[p : endInset + 1]
2432 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2433 document.body[realparbeg : realparbeg] = subst
2434 if layoutname == "OverlayArea":
2435 m = rx.match(document.body[p])
2439 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2440 endPlain = find_end_of_layout(document.body, beginPlain)
2441 endInset = find_end_of_inset(document.body, p)
2442 content = document.body[beginPlain + 1 : endPlain]
2444 realparend = realparend - len(document.body[p : endInset + 1])
2446 del document.body[p : endInset + 1]
2447 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2448 document.body[realparbeg : realparbeg] = subst
2449 if layoutname in list_layouts:
2450 m = rx.match(document.body[p])
2454 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2455 endPlain = find_end_of_layout(document.body, beginPlain)
2456 endInset = find_end_of_inset(document.body, p)
2457 content = document.body[beginPlain + 1 : endPlain]
2458 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2459 realparend = realparend + len(subst) - len(content)
2460 document.body[beginPlain + 1 : endPlain] = subst
2461 elif argnr == "item:1":
2462 j = find_end_of_inset(document.body, i)
2463 # Find containing paragraph layout
2464 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2465 endPlain = find_end_of_layout(document.body, beginPlain)
2466 content = document.body[beginPlain + 1 : endPlain]
2467 del document.body[i:j+1]
2468 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2469 document.body[realparbeg : realparbeg] = subst
2470 elif argnr == "item:2":
2471 j = find_end_of_inset(document.body, i)
2472 # Find containing paragraph layout
2473 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2474 endPlain = find_end_of_layout(document.body, beginPlain)
2475 content = document.body[beginPlain + 1 : endPlain]
2476 del document.body[i:j+1]
2477 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2478 document.body[realparbeg : realparbeg] = subst
2479 if layoutname in quote_layouts:
2480 m = rx.match(document.body[p])
2484 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2485 endPlain = find_end_of_layout(document.body, beginPlain)
2486 endInset = find_end_of_inset(document.body, p)
2487 content = document.body[beginPlain + 1 : endPlain]
2489 realparend = realparend - len(document.body[p : endInset + 1])
2491 del document.body[p : endInset + 1]
2492 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2493 document.body[realparbeg : realparbeg] = subst
2494 if layoutname in corollary_layouts:
2495 m = rx.match(document.body[p])
2499 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2500 endPlain = find_end_of_layout(document.body, beginPlain)
2501 endInset = find_end_of_inset(document.body, p)
2502 content = document.body[beginPlain + 1 : endPlain]
2504 realparend = realparend - len(document.body[p : endInset + 1])
2506 del document.body[p : endInset + 1]
2507 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2508 document.body[realparbeg : realparbeg] = subst
2513 def revert_beamerargs2(document):
2514 " Reverts beamer arguments to old layout, step 2 "
2516 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2517 if document.textclass not in beamer_classes:
2521 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
2522 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2523 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2526 i = find_token(document.body, "\\begin_inset Argument", i)
2529 # Find containing paragraph layout
2530 parent = get_containing_layout(document.body, i)
2532 document.warning("Malformed lyx document: Can't find parent paragraph layout")
2537 realparbeg = parent[3]
2538 layoutname = parent[0]
2540 for p in range(parbeg, parend):
2544 if layoutname in shifted_layouts:
2545 m = rx.match(document.body[p])
2549 document.body[p] = "\\begin_inset Argument 1"
2550 if layoutname in corollary_layouts:
2551 m = rx.match(document.body[p])
2555 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2556 endPlain = find_end_of_layout(document.body, beginPlain)
2557 endInset = find_end_of_inset(document.body, p)
2558 content = document.body[beginPlain + 1 : endPlain]
2560 realparend = realparend - len(document.body[p : endInset + 1])
2562 del document.body[p : endInset + 1]
2563 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2564 document.body[realparbeg : realparbeg] = subst
2565 if layoutname == "OverlayArea":
2566 m = rx.match(document.body[p])
2570 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2571 endPlain = find_end_of_layout(document.body, beginPlain)
2572 endInset = find_end_of_inset(document.body, p)
2573 content = document.body[beginPlain + 1 : endPlain]
2575 realparend = realparend - len(document.body[p : endInset + 1])
2577 del document.body[p : endInset + 1]
2578 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2579 document.body[realparbeg : realparbeg] = subst
2580 if layoutname == "AgainFrame":
2581 m = rx.match(document.body[p])
2585 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2586 endPlain = find_end_of_layout(document.body, beginPlain)
2587 endInset = find_end_of_inset(document.body, p)
2588 content = document.body[beginPlain + 1 : endPlain]
2590 realparend = realparend - len(document.body[p : endInset + 1])
2592 del document.body[p : endInset + 1]
2593 subst = put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
2594 document.body[realparbeg : realparbeg] = subst
2598 def revert_beamerargs3(document):
2599 " Reverts beamer arguments to old layout, step 3 "
2601 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2602 if document.textclass not in beamer_classes:
2605 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2608 i = find_token(document.body, "\\begin_inset Argument", i)
2611 # Find containing paragraph layout
2612 parent = get_containing_layout(document.body, i)
2614 document.warning("Malformed lyx document: Can't find parent paragraph layout")
2619 realparbeg = parent[3]
2620 layoutname = parent[0]
2622 for p in range(parbeg, parend):
2626 if layoutname == "AgainFrame":
2627 m = rx.match(document.body[p])
2631 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2632 endPlain = find_end_of_layout(document.body, beginPlain)
2633 endInset = find_end_of_inset(document.body, p)
2634 content = document.body[beginPlain + 1 : endPlain]
2636 realparend = realparend - len(document.body[p : endInset + 1])
2638 del document.body[p : endInset + 1]
2639 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2640 document.body[realparbeg : realparbeg] = subst
2644 def revert_beamerflex(document):
2645 " Reverts beamer Flex insets "
2647 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2648 if document.textclass not in beamer_classes:
2651 new_flexes = {"Bold" : "\\textbf", "Emphasize" : "\\emph", "Only" : "\\only",
2652 "Uncover" : "\\uncover", "Visible" : "\\visible",
2653 "Invisible" : "\\invisible", "Alternative" : "\\alt",
2654 "Beamer_Note" : "\\note"}
2655 old_flexes = {"Alert" : "\\alert", "Structure" : "\\structure"}
2656 rx = re.compile(r'^\\begin_inset Flex (.+)$')
2660 i = find_token(document.body, "\\begin_inset Flex", i)
2663 m = rx.match(document.body[i])
2665 flextype = m.group(1)
2666 z = find_end_of_inset(document.body, i)
2668 document.warning("Can't find end of Flex " + flextype + " inset.")
2671 if flextype in new_flexes:
2672 pre = put_cmd_in_ert(new_flexes[flextype])
2673 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2675 argend = find_end_of_inset(document.body, arg)
2677 document.warning("Can't find end of Argument!")
2680 # Find containing paragraph layout
2681 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2682 endPlain = find_end_of_layout(document.body, beginPlain)
2683 argcontent = document.body[beginPlain + 1 : endPlain]
2685 z = z - len(document.body[arg : argend + 1])
2687 del document.body[arg : argend + 1]
2688 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2689 arg = find_token(document.body, "\\begin_inset Argument 2", i, z)
2691 argend = find_end_of_inset(document.body, arg)
2693 document.warning("Can't find end of Argument!")
2696 # Find containing paragraph layout
2697 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2698 endPlain = find_end_of_layout(document.body, beginPlain)
2699 argcontent = document.body[beginPlain + 1 : endPlain]
2701 z = z - len(document.body[arg : argend + 1])
2703 del document.body[arg : argend + 1]
2704 if flextype == "Alternative":
2705 pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
2707 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2708 pre += put_cmd_in_ert("{")
2709 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2710 endPlain = find_end_of_layout(document.body, beginPlain)
2712 z = z - len(document.body[i : beginPlain + 1])
2714 document.body[i : beginPlain + 1] = pre
2715 post = put_cmd_in_ert("}")
2716 document.body[z - 2 : z + 1] = post
2717 elif flextype in old_flexes:
2718 pre = put_cmd_in_ert(old_flexes[flextype])
2719 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2723 argend = find_end_of_inset(document.body, arg)
2725 document.warning("Can't find end of Argument!")
2728 # Find containing paragraph layout
2729 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2730 endPlain = find_end_of_layout(document.body, beginPlain)
2731 argcontent = document.body[beginPlain + 1 : endPlain]
2733 z = z - len(document.body[arg : argend + 1])
2735 del document.body[arg : argend + 1]
2736 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2737 pre += put_cmd_in_ert("{")
2738 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2739 endPlain = find_end_of_layout(document.body, beginPlain)
2741 z = z - len(document.body[i : beginPlain + 1])
2743 document.body[i : beginPlain + 1] = pre
2744 post = put_cmd_in_ert("}")
2745 document.body[z - 2 : z + 1] = post
2750 def revert_beamerblocks(document):
2751 " Reverts beamer block arguments to ERT "
2753 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2754 if document.textclass not in beamer_classes:
2757 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2759 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2762 i = find_token(document.body, "\\begin_inset Argument", i)
2765 # Find containing paragraph layout
2766 parent = get_containing_layout(document.body, i)
2768 document.warning("Malformed lyx document: Can't find parent paragraph layout")
2773 realparbeg = parent[3]
2774 layoutname = parent[0]
2776 for p in range(parbeg, parend):
2780 if layoutname in blocks:
2781 m = rx.match(document.body[p])
2785 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2786 endPlain = find_end_of_layout(document.body, beginPlain)
2787 endInset = find_end_of_inset(document.body, p)
2788 content = document.body[beginPlain + 1 : endPlain]
2790 realparend = realparend - len(document.body[p : endInset + 1])
2792 del document.body[p : endInset + 1]
2793 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2794 document.body[realparbeg : realparbeg] = subst
2796 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2797 endPlain = find_end_of_layout(document.body, beginPlain)
2798 endInset = find_end_of_inset(document.body, p)
2799 content = document.body[beginPlain + 1 : endPlain]
2801 realparend = realparend - len(document.body[p : endInset + 1])
2803 del document.body[p : endInset + 1]
2804 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2805 document.body[realparbeg : realparbeg] = subst
2810 def convert_beamerblocks(document):
2811 " Converts beamer block ERT args to native InsetArgs "
2813 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2814 if document.textclass not in beamer_classes:
2817 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2821 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2824 parent = get_containing_layout(document.body, i)
2825 if parent == False or parent[1] != i:
2826 document.warning("Wrong parent layout!")
2832 if document.body[parbeg] == "\\begin_inset ERT":
2833 ertcont = parbeg + 5
2835 if document.body[ertcont].startswith("<"):
2836 # This is an overlay specification
2838 document.body[ertcont] = document.body[ertcont][1:]
2839 if document.body[ertcont].endswith(">"):
2841 document.body[ertcont] = document.body[ertcont][:-1]
2842 # Convert to ArgInset
2843 document.body[parbeg] = "\\begin_inset Argument 1"
2844 elif document.body[ertcont].endswith("}"):
2846 tok = document.body[ertcont].find('>{')
2848 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2849 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2850 'status collapsed', '', '\\begin_layout Plain Layout',
2851 document.body[ertcont][tok + 2:-1]]
2852 # Convert to ArgInset
2853 document.body[parbeg] = "\\begin_inset Argument 1"
2854 elif document.body[ertcont].startswith("{"):
2855 # This is the block title
2856 if document.body[ertcont].endswith("}"):
2857 # strip off the braces
2858 document.body[ertcont] = document.body[ertcont][1:-1]
2859 # Convert to ArgInset
2860 document.body[parbeg] = "\\begin_inset Argument 2"
2861 elif count_pars_in_inset(document.body, ertcont) > 1:
2862 # Multipar ERT. Skip this.
2865 convert_TeX_brace_to_Argument(document, i, 2, 2, False, True)
2868 j = find_end_of_layout(document.body, i)
2870 document.warning("end of layout not found!")
2871 k = find_token(document.body, "\\begin_inset Argument", i, j)
2873 document.warning("InsetArgument not found!")
2875 l = find_end_of_inset(document.body, k)
2876 m = find_token(document.body, "\\begin_inset ERT", l, j)
2884 def convert_overprint(document):
2885 " Convert old beamer overprint layouts to ERT "
2887 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2888 if document.textclass not in beamer_classes:
2893 i = find_token(document.body, "\\begin_layout Overprint", i)
2896 # Find end of sequence
2897 j = find_end_of_sequence(document.body, i)
2899 document.warning("Malformed lyx document. Cannot find end of Overprint sequence!")
2903 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
2905 if document.body[j] == "\\end_deeper":
2906 esubst = ["", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
2908 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
2909 endseq = endseq + len(esubst) - len(document.body[j : j])
2910 document.body[j : j] = esubst
2911 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
2913 argend = find_end_of_layout(document.body, argbeg)
2915 document.warning("Malformed lyx document. Cannot find end of Overprint argument!")
2918 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
2919 endPlain = find_end_of_layout(document.body, beginPlain)
2920 content = document.body[beginPlain + 1 : endPlain]
2922 endseq = endseq - len(document.body[argbeg : argend + 1])
2924 del document.body[argbeg : argend + 1]
2925 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2927 endseq = endseq - len(document.body[i : i])
2928 document.body[i : i] = subst + ["\\end_layout"]
2929 endseq += len(subst)
2931 for p in range(i, endseq):
2932 if document.body[p] == "\\begin_layout Overprint":
2933 document.body[p] = "\\begin_layout Standard"
2938 def revert_overprint(document):
2939 " Revert old beamer overprint layouts to ERT "
2941 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2942 if document.textclass not in beamer_classes:
2947 i = find_token(document.body, "\\begin_layout Overprint", i)
2950 # Find end of sequence
2951 j = find_end_of_sequence(document.body, i)
2953 document.warning("Malformed lyx document. Cannot find end of Overprint sequence!")
2957 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
2958 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}")
2959 endseq = endseq + len(esubst) - len(document.body[j : j])
2960 if document.body[j] == "\\end_deeper":
2961 document.body[j : j] = ["\\end_deeper", ""] + esubst
2963 document.body[j : j] = esubst
2966 if document.body[r] == "\\begin_deeper":
2967 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
2969 document.body[r] = ""
2970 document.body[s] = ""
2974 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
2976 argend = find_end_of_inset(document.body, argbeg)
2978 document.warning("Malformed lyx document. Cannot find end of Overprint argument!")
2981 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
2982 endPlain = find_end_of_layout(document.body, beginPlain)
2983 content = document.body[beginPlain + 1 : endPlain]
2985 endseq = endseq - len(document.body[argbeg : argend])
2987 del document.body[argbeg : argend + 1]
2988 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2990 endseq = endseq - len(document.body[i : i])
2991 document.body[i : i] = subst + ["\\end_layout"]
2992 endseq += len(subst)
2998 if document.body[p] == "\\begin_layout Overprint":
2999 q = find_end_of_layout(document.body, p)
3001 document.warning("Malformed lyx document. Cannot find end of Overprint layout!")
3004 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\onslide")
3005 argbeg = find_token(document.body, "\\begin_inset Argument item:1", p, q)
3007 argend = find_end_of_inset(document.body, argbeg)
3009 document.warning("Malformed lyx document. Cannot find end of Overprint item argument!")
3012 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3013 endPlain = find_end_of_layout(document.body, beginPlain)
3014 content = document.body[beginPlain + 1 : endPlain]
3016 endseq = endseq - len(document.body[argbeg : argend + 1])
3018 del document.body[argbeg : argend + 1]
3019 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3020 endseq = endseq - len(document.body[p : p + 1]) + len(subst)
3021 document.body[p : p + 1] = subst
3027 def revert_frametitle(document):
3028 " Reverts beamer frametitle layout to ERT "
3030 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3031 if document.textclass not in beamer_classes:
3034 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
3037 i = find_token(document.body, "\\begin_layout FrameTitle", i)
3040 j = find_end_of_layout(document.body, i)
3042 document.warning("Malformed lyx document: Can't find end of FrameTitle layout")
3046 document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
3047 endlay += len(put_cmd_in_ert("}"))
3048 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\frametitle")
3049 for p in range(i, j):
3052 m = rx.match(document.body[p])
3056 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3057 endPlain = find_end_of_layout(document.body, beginPlain)
3058 endInset = find_end_of_inset(document.body, p)
3059 content = document.body[beginPlain + 1 : endPlain]
3061 endlay = endlay - len(document.body[p : endInset + 1])
3063 del document.body[p : endInset + 1]
3064 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3066 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3067 endPlain = find_end_of_layout(document.body, beginPlain)
3068 endInset = find_end_of_inset(document.body, p)
3069 content = document.body[beginPlain + 1 : endPlain]
3071 endlay = endlay - len(document.body[p : endInset + 1])
3073 del document.body[p : endInset + 1]
3074 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3076 subst += put_cmd_in_ert("{")
3077 document.body[i : i + 1] = subst
3081 def convert_epigraph(document):
3082 " Converts memoir epigraph to new syntax "
3084 if document.textclass != "memoir":
3089 i = find_token(document.body, "\\begin_layout Epigraph", i)
3092 j = find_end_of_layout(document.body, i)
3094 document.warning("Malformed lyx document: Can't find end of Epigraph layout")
3099 ert = find_token(document.body, "\\begin_inset ERT", i, j)
3101 endInset = find_end_of_inset(document.body, ert)
3102 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", ert)
3103 endPlain = find_end_of_layout(document.body, beginPlain)
3104 ertcont = beginPlain + 2
3105 if document.body[ertcont] == "}{":
3107 # Convert to ArgInset
3108 endlay = endlay - 2 * len(document.body[j])
3109 begsubst = ['\\begin_inset Argument post:1', 'status collapsed', '',
3110 '\\begin_layout Plain Layout']
3111 endsubst = ['\\end_layout', '', '\\end_inset', '', document.body[j]]
3112 document.body[j : j + 1] = endsubst
3113 document.body[endInset + 1 : endInset + 1] = begsubst
3115 endlay += len(begsubst) + len(endsubst)
3116 endlay = endlay - len(document.body[ert : endInset + 1])
3117 del document.body[ert : endInset + 1]
3122 def revert_epigraph(document):
3123 " Reverts memoir epigraph argument to ERT "
3125 if document.textclass != "memoir":
3130 i = find_token(document.body, "\\begin_layout Epigraph", i)
3133 j = find_end_of_layout(document.body, i)
3135 document.warning("Malformed lyx document: Can't find end of Epigraph layout")
3140 p = find_token(document.body, "\\begin_layout Argument post:1", i, j)
3142 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3143 endPlain = find_end_of_layout(document.body, beginPlain)
3144 endInset = find_end_of_inset(document.body, p)
3145 content = document.body[beginPlain + 1 : endPlain]
3147 endlay = endlay - len(document.body[p : endInset + 1])
3149 del document.body[p : endInset + 1]
3150 subst += put_cmd_in_ert("}{") + content
3152 subst += put_cmd_in_ert("}{")
3154 document.body[j : j] = subst + document.body[j : j]
3158 def convert_captioninsets(document):
3159 " Converts caption insets to new syntax "
3163 i = find_token(document.body, "\\begin_inset Caption", i)
3166 document.body[i] = "\\begin_inset Caption Standard"
3171 def revert_captioninsets(document):
3172 " Reverts caption insets to old syntax "
3176 i = find_token(document.body, "\\begin_inset Caption Standard", i)
3179 document.body[i] = "\\begin_inset Caption"
3183 def convert_captionlayouts(document):
3184 " Convert caption layouts to caption insets. "
3187 "Captionabove": "Above",
3188 "Captionbelow": "Below",
3189 "FigCaption" : "FigCaption",
3190 "Table_Caption" : "Table",
3191 "CenteredCaption" : "Centered",
3192 "Bicaption" : "Bicaption",
3197 i = find_token(document.body, "\\begin_layout", i)
3200 val = get_value(document.body, "\\begin_layout", i)
3201 if val in caption_dict.keys():
3202 j = find_end_of_layout(document.body, i)
3204 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3207 document.body[j:j] = ["\\end_layout", "", "\\end_inset", "", ""]
3208 document.body[i:i+1] = ["\\begin_layout %s" % document.default_layout,
3209 "\\begin_inset Caption %s" % caption_dict[val], "",
3210 "\\begin_layout %s" % document.default_layout]
3214 def revert_captionlayouts(document):
3215 " Revert caption insets to caption layouts. "
3218 "Above" : "Captionabove",
3219 "Below" : "Captionbelow",
3220 "FigCaption" : "FigCaption",
3221 "Table" : "Table_Caption",
3222 "Centered" : "CenteredCaption",
3223 "Bicaption" : "Bicaption",
3227 rx = re.compile(r'^\\begin_inset Caption (\S+)$')
3229 i = find_token(document.body, "\\begin_inset Caption", i)
3233 m = rx.match(document.body[i])
3237 if val not in caption_dict.keys():
3241 # We either need to delete the previous \begin_layout line, or we
3242 # need to end the previous layout if this inset is not in the first
3243 # position of the paragraph.
3244 layout_before = find_token_backwards(document.body, "\\begin_layout", i)
3245 if layout_before == -1:
3246 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3248 layout_line = document.body[layout_before]
3249 del_layout_before = True
3250 l = layout_before + 1
3252 if document.body[l] != "":
3253 del_layout_before = False
3256 if del_layout_before:
3257 del document.body[layout_before:i]
3260 document.body[i:i] = ["\\end_layout", ""]
3263 # Find start of layout in the inset and end of inset
3264 j = find_token(document.body, "\\begin_layout", i)
3266 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3268 k = find_end_of_inset(document.body, i)
3270 document.warning("Malformed LyX document: Missing `\\end_inset'.")
3273 # We either need to delete the following \end_layout line, or we need
3274 # to restart the old layout if this inset is not at the paragraph end.
3275 layout_after = find_token(document.body, "\\end_layout", k)
3276 if layout_after == -1:
3277 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3279 del_layout_after = True
3281 while l < layout_after:
3282 if document.body[l] != "":
3283 del_layout_after = False
3286 if del_layout_after:
3287 del document.body[k+1:layout_after+1]
3289 document.body[k+1:k+1] = [layout_line, ""]
3291 # delete \begin_layout and \end_inset and replace \begin_inset with
3292 # "\begin_layout XXX". This works because we can only have one
3293 # paragraph in the caption inset: The old \end_layout will be recycled.
3294 del document.body[k]
3295 if document.body[k] == "":
3296 del document.body[k]
3297 del document.body[j]
3298 if document.body[j] == "":
3299 del document.body[j]
3300 document.body[i] = "\\begin_layout %s" % caption_dict[val]
3301 if document.body[i+1] == "":
3302 del document.body[i+1]
3306 def revert_fragileframe(document):
3307 " Reverts beamer FragileFrame layout to ERT "
3309 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3310 if document.textclass not in beamer_classes:
3315 i = find_token(document.body, "\\begin_layout FragileFrame", i)
3318 # Find end of sequence
3319 j = find_end_of_sequence(document.body, i)
3321 document.warning("Malformed lyx document. Cannot find end of FragileFrame sequence!")
3325 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{frame}")
3326 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{frame}")
3327 endseq = endseq + len(esubst) - len(document.body[j : j])
3328 if document.body[j] == "\\end_deeper":
3329 document.body[j : j] = ["\\end_deeper", ""] + esubst
3331 document.body[j : j] = esubst
3332 for q in range(i, j):
3333 if document.body[q] == "\\begin_layout FragileFrame":
3334 document.body[q] = "\\begin_layout %s" % document.default_layout
3337 if document.body[r] == "\\begin_deeper":
3338 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3340 document.body[r] = ""
3341 document.body[s] = ""
3345 for p in range(1, 5):
3346 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, j)
3349 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3350 endPlain = find_end_of_layout(document.body, beginPlain)
3351 endInset = find_end_of_inset(document.body, arg)
3352 content = document.body[beginPlain + 1 : endPlain]
3354 j = j - len(document.body[arg : endInset + 1])
3356 del document.body[arg : endInset + 1]
3357 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3359 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3360 endPlain = find_end_of_layout(document.body, beginPlain)
3361 endInset = find_end_of_inset(document.body, arg)
3362 content = document.body[beginPlain + 1 : endPlain]
3364 j = j - len(document.body[arg : endInset + 1])
3366 del document.body[arg : endInset + 1]
3367 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3369 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3370 endPlain = find_end_of_layout(document.body, beginPlain)
3371 endInset = find_end_of_inset(document.body, arg)
3372 content = document.body[beginPlain + 1 : endPlain]
3374 j = j - len(document.body[arg : endInset + 1])
3376 del document.body[arg : endInset + 1]
3377 subst += put_cmd_in_ert("[fragile,") + content + put_cmd_in_ert("]")
3379 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3380 endPlain = find_end_of_layout(document.body, beginPlain)
3381 endInset = find_end_of_inset(document.body, arg)
3382 content = document.body[beginPlain + 1 : endPlain]
3384 j = j - len(document.body[arg : endInset + 1])
3386 del document.body[arg : endInset + 1]
3387 subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
3389 subst += put_cmd_in_ert("[fragile]")
3391 document.body[i : i + 1] = subst
3395 def revert_newframes(document):
3396 " Reverts beamer Frame and PlainFrame layouts to old forms "
3398 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3399 if document.textclass not in beamer_classes:
3403 "Frame" : "BeginFrame",
3404 "PlainFrame" : "BeginPlainFrame",
3407 rx = re.compile(r'^\\begin_layout (\S+)$')
3410 i = find_token(document.body, "\\begin_layout", i)
3414 m = rx.match(document.body[i])
3418 if val not in frame_dict.keys():
3421 # Find end of sequence
3422 j = find_end_of_sequence(document.body, i)
3424 document.warning("Malformed lyx document. Cannot find end of Frame sequence!")
3428 subst = ["\\begin_layout %s" % frame_dict[val]]
3429 esubst = ["\\end_layout", "", "\\begin_layout EndFrame", "", "\\end_layout"]
3430 endseq = endseq + len(esubst) - len(document.body[j : j])
3431 if document.body[j] == "\\end_deeper":
3432 document.body[j : j] = ["\\end_deeper", ""] + esubst
3434 document.body[j : j] = esubst
3435 for q in range(i, j):
3436 if document.body[q] == "\\begin_layout %s" % val:
3437 document.body[q] = "\\begin_layout %s" % document.default_layout
3440 if document.body[r] == "\\begin_deeper":
3441 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3443 document.body[r] = ""
3444 document.body[s] = ""
3448 l = find_end_of_layout(document.body, i)
3449 for p in range(1, 5):
3450 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, l)
3453 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3454 endPlain = find_end_of_layout(document.body, beginPlain)
3455 endInset = find_end_of_inset(document.body, arg)
3456 content = document.body[beginPlain + 1 : endPlain]
3458 l = l - len(document.body[arg : endInset + 1])
3460 del document.body[arg : endInset + 1]
3461 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3463 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3464 endPlain = find_end_of_layout(document.body, beginPlain)
3465 endInset = find_end_of_inset(document.body, arg)
3466 content = document.body[beginPlain + 1 : endPlain]
3468 l = l - len(document.body[arg : endInset + 1])
3470 del document.body[arg : endInset + 1]
3471 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3473 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3474 endPlain = find_end_of_layout(document.body, beginPlain)
3475 endInset = find_end_of_inset(document.body, arg)
3476 content = document.body[beginPlain + 1 : endPlain]
3478 l = l - len(document.body[arg : endInset + 1])
3480 del document.body[arg : endInset + 1]
3481 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3483 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3484 endPlain = find_end_of_layout(document.body, beginPlain)
3485 endInset = find_end_of_inset(document.body, arg)
3486 content = document.body[beginPlain + 1 : endPlain]
3488 l = l - len(document.body[arg : endInset + 1])
3490 del document.body[arg : endInset + 1]
3493 document.body[i : i + 1] = subst
3501 supported_versions = ["2.1.0","2.1"]
3504 [415, [convert_undertilde]],
3506 [417, [convert_japanese_encodings]],
3509 [420, [convert_biblio_style]],
3510 [421, [convert_longtable_captions]],
3511 [422, [convert_use_packages]],
3512 [423, [convert_use_mathtools]],
3513 [424, [convert_cite_engine_type]],
3517 [428, [convert_cell_rotation]],
3518 [429, [convert_table_rotation]],
3519 [430, [convert_listoflistings]],
3520 [431, [convert_use_amssymb]],
3522 [433, [convert_armenian]],
3530 [441, [convert_mdnomath]],
3535 [446, [convert_latexargs]],
3536 [447, [convert_IEEEtran, convert_AASTeX, convert_AGUTeX, convert_IJMP, convert_SIGPLAN, convert_SIGGRAPH, convert_EuropeCV, convert_Initials, convert_ModernCV]],
3537 [448, [convert_literate]],
3540 [451, [convert_beamerargs, convert_againframe_args, convert_corollary_args, convert_quote_args]],
3541 [452, [convert_beamerblocks]],
3542 [453, [convert_use_stmaryrd]],
3543 [454, [convert_overprint]],
3545 [456, [convert_epigraph]],
3546 [457, [convert_use_stackrel]],
3547 [458, [convert_captioninsets, convert_captionlayouts]],
3552 [458, [revert_fragileframe, revert_newframes]],
3553 [457, [revert_captioninsets, revert_captionlayouts]],
3554 [456, [revert_use_stackrel]],
3555 [455, [revert_epigraph]],
3556 [454, [revert_frametitle]],
3557 [453, [revert_overprint]],
3558 [452, [revert_use_stmaryrd]],
3559 [451, [revert_beamerblocks]],
3560 [450, [revert_beamerargs, revert_beamerargs2, revert_beamerargs3, revert_beamerflex]],
3561 [449, [revert_garamondx, revert_garamondx_newtxmath]],
3562 [448, [revert_itemargs]],
3563 [447, [revert_literate]],
3564 [446, [revert_IEEEtran, revert_IEEEtran_2, revert_AASTeX, revert_AGUTeX, revert_IJMP, revert_SIGPLAN, revert_SIGGRAPH, revert_EuropeCV, revert_Initials, revert_ModernCV]],
3565 [445, [revert_latexargs]],
3566 [444, [revert_uop]],
3567 [443, [revert_biolinum]],
3569 [441, [revert_newtxmath]],
3570 [440, [revert_mdnomath]],
3571 [439, [revert_mathfonts]],
3572 [438, [revert_minionpro]],
3573 [437, [revert_ipadeco, revert_ipachar]],
3574 [436, [revert_texgyre]],
3575 [435, [revert_mathdesign]],
3576 [434, [revert_txtt]],
3577 [433, [revert_libertine]],
3578 [432, [revert_armenian]],
3579 [431, [revert_languages, revert_ancientgreek]],
3580 [430, [revert_use_amssymb]],
3581 [429, [revert_listoflistings]],
3582 [428, [revert_table_rotation]],
3583 [427, [revert_cell_rotation]],
3584 [426, [revert_tipa]],
3585 [425, [revert_verbatim]],
3586 [424, [revert_cancel]],
3587 [423, [revert_cite_engine_type]],
3588 [422, [revert_use_mathtools]],
3589 [421, [revert_use_packages]],
3590 [420, [revert_longtable_captions]],
3591 [419, [revert_biblio_style]],
3592 [418, [revert_australian]],
3593 [417, [revert_justification]],
3594 [416, [revert_japanese_encodings]],
3595 [415, [revert_negative_space, revert_math_spaces]],
3596 [414, [revert_undertilde]],
3597 [413, [revert_visible_space]]
3601 if __name__ == "__main__":