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 revert_IEEEtran(document):
1461 Reverts InsetArgument of
1464 Biography without photo
1467 if document.textclass == "IEEEtran":
1473 i = find_token(document.body, "\\begin_layout Page headings", i)
1475 revert_Argument_to_TeX_brace(document, i, 1, 1, False)
1478 j = find_token(document.body, "\\begin_layout Biography without photo", j)
1480 revert_Argument_to_TeX_brace(document, j, 1, 1, True)
1483 k = find_token(document.body, "\\begin_layout Biography", k)
1484 kA = find_token(document.body, "\\begin_layout Biography without photo", k)
1485 if k == kA and k != -1:
1489 # start with the second argument, therefore 2
1490 revert_Argument_to_TeX_brace(document, k, 2, 2, True)
1492 if i == -1 and j == -1 and k == -1:
1496 def convert_TeX_brace_to_Argument(document, line, n, nmax, inset, environment):
1498 Converts TeX code for mandatory arguments to an InsetArgument
1499 The conversion of TeX code for optional arguments must be done with another routine
1500 !!! Be careful if the braces are different in your case as expected here:
1501 - "}{" separates mandatory arguments of commands
1502 - "}" + "{" separates mandatory arguments of commands
1503 - "}" + " " + "{" separates mandatory arguments of commands
1504 - { and } surround a mandatory argument of an environment
1506 convert_TeX_brace_to_Argument(document, LineOfBeginLayout/Inset, StartArgument, EndArgument, isInset, isEnvironment)
1507 LineOfBeginLayout/Inset is the line of the \begin_layout or \begin_inset statement
1508 StartArgument is the number of the first ERT that needs to be converted
1509 EndArgument is the number of the last ERT that needs to be converted
1510 isInset must be true, if braces inside an InsetLayout needs to be converted
1511 isEnvironment must be true, if the layout is for a LaTeX environment
1513 Todo: this routine can currently handle only one mandatory argument of environments
1518 while lineERT != -1 and n < nmax + 1:
1519 lineERT = find_token(document.body, "\\begin_inset ERT", lineERT)
1520 if environment == False and lineERT != -1:
1521 bracePair = find_token(document.body, "}{", lineERT)
1522 # assure that the "}{" is in this ERT
1523 if bracePair == lineERT + 5:
1524 end = find_token(document.body, "\\end_inset", bracePair)
1525 document.body[lineERT : end + 1] = ["\\end_layout", "", "\\end_inset"]
1527 # in the case that n > 1 we have optional arguments before
1528 # therefore detect them if any
1530 # first check if there is an argument
1531 lineArg = find_token(document.body, "\\begin_inset Argument", line)
1532 if lineArg < lineERT and lineArg != -1:
1533 # we have an argument, so now search backwards for its end
1534 # we must now assure that we don't find other insets like e.g. a newline
1535 endInsetArg = lineERT
1536 endLayoutArg = endInsetArg
1537 while endInsetArg != endLayoutArg + 2 and endInsetArg != -1:
1538 endInsetArg = endInsetArg - 1
1539 endLayoutArg = endInsetArg
1540 endInsetArg = find_token_backwards(document.body, "\\end_inset", endInsetArg)
1541 endLayoutArg = find_token_backwards(document.body, "\\end_layout", endLayoutArg)
1542 line = endInsetArg + 1
1544 document.body[line + 1 : line + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1546 document.body[line + 4 : line + 4] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1548 document.body[endn : endn] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1552 # now check the case that we have "}" + "{" in two ERTs
1554 endBrace = find_token(document.body, "}", lineERT)
1555 if endBrace == lineERT + 5:
1556 beginBrace = find_token(document.body, "{", endBrace)
1557 # assure that the ERTs are consecutive (11 or 12 depending if there is a space between the ERTs or not)
1558 if beginBrace == endBrace + 11 or beginBrace == endBrace + 12:
1559 end = find_token(document.body, "\\end_inset", beginBrace)
1560 document.body[lineERT : end + 1] = ["\\end_layout", "", "\\end_inset"]
1562 # in the case that n > 1 we have optional arguments before
1563 # therefore detect them if any
1565 # first check if there is an argument
1566 lineArg = find_token(document.body, "\\begin_inset Argument", line)
1567 if lineArg < lineERT and lineArg != -1:
1568 # we have an argument, so now search backwards for its end
1569 # we must now assure that we don't find other insets like e.g. a newline
1570 endInsetArg = lineERT
1571 endLayoutArg = endInsetArg
1572 while endInsetArg != endLayoutArg + 2 and endInsetArg != -1:
1573 endInsetArg = endInsetArg - 1
1574 endLayoutArg = endInsetArg
1575 endInsetArg = find_token_backwards(document.body, "\\end_inset", endInsetArg)
1576 endLayoutArg = find_token_backwards(document.body, "\\end_layout", endLayoutArg)
1577 line = endInsetArg + 1
1579 document.body[line + 1 : line + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1581 document.body[line + 4 : line + 4] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1583 document.body[endn : endn] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1586 # set the line where the next argument will be inserted
1587 if beginBrace == endBrace + 11:
1592 lineERT = lineERT + 1
1593 if environment == True and lineERT != -1:
1594 opening = find_token(document.body, "{", lineERT)
1595 if opening == lineERT + 5: # assure that the "{" is in this ERT
1596 end = find_token(document.body, "\\end_inset", opening)
1597 document.body[lineERT : end + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1599 lineERT2 = find_token(document.body, "\\begin_inset ERT", lineERT)
1600 closing = find_token(document.body, "}", lineERT2)
1601 if closing == lineERT2 + 5: # assure that the "}" is in this ERT
1602 end2 = find_token(document.body, "\\end_inset", closing)
1603 document.body[lineERT2 : end2 + 1] = ["\\end_layout", "", "\\end_inset"]
1605 lineERT = lineERT + 1
1608 def convert_IEEEtran(document):
1613 Biography without photo
1616 if document.textclass == "IEEEtran":
1622 i = find_token(document.body, "\\begin_layout Page headings", i)
1624 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1627 j = find_token(document.body, "\\begin_layout Biography without photo", j)
1629 convert_TeX_brace_to_Argument(document, j, 1, 1, False, True)
1632 # assure that we don't handle Biography Biography without photo
1633 k = find_token(document.body, "\\begin_layout Biography", k)
1634 kA = find_token(document.body, "\\begin_layout Biography without photo", k - 1)
1635 if k == kA and k != -1:
1639 # the argument we want to convert is the second one
1640 convert_TeX_brace_to_Argument(document, k, 2, 2, False, True)
1642 if i == -1 and j == -1 and k == -1:
1646 def revert_AASTeX(document):
1647 " Reverts InsetArgument of Altaffilation to TeX-code "
1648 if document.textclass == "aastex":
1652 i = find_token(document.body, "\\begin_layout Altaffilation", i)
1654 revert_Argument_to_TeX_brace(document, i, 1, 1, False)
1660 def convert_AASTeX(document):
1661 " Converts ERT of Altaffilation to InsetArgument "
1662 if document.textclass == "aastex":
1666 i = find_token(document.body, "\\begin_layout Altaffilation", i)
1668 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1674 def revert_AGUTeX(document):
1675 " Reverts InsetArgument of Author affiliation to TeX-code "
1676 if document.textclass == "agutex":
1680 i = find_token(document.body, "\\begin_layout Author affiliation", i)
1682 revert_Argument_to_TeX_brace(document, i, 1, 1, False)
1688 def convert_AGUTeX(document):
1689 " Converts ERT of Author affiliation to InsetArgument "
1690 if document.textclass == "agutex":
1694 i = find_token(document.body, "\\begin_layout Author affiliation", i)
1696 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1702 def revert_IJMP(document):
1703 " Reverts InsetArgument of MarkBoth to TeX-code "
1704 if document.textclass == "ijmpc" or document.textclass == "ijmpd":
1708 i = find_token(document.body, "\\begin_layout MarkBoth", i)
1710 revert_Argument_to_TeX_brace(document, i, 1, 1, False)
1716 def convert_IJMP(document):
1717 " Converts ERT of MarkBoth to InsetArgument "
1718 if document.textclass == "ijmpc" or document.textclass == "ijmpd":
1722 i = find_token(document.body, "\\begin_layout MarkBoth", i)
1724 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1730 def revert_SIGPLAN(document):
1731 " Reverts InsetArgument of MarkBoth to TeX-code "
1732 if document.textclass == "sigplanconf":
1737 i = find_token(document.body, "\\begin_layout Conference", i)
1739 revert_Argument_to_TeX_brace(document, i, 1, 1, False)
1742 j = find_token(document.body, "\\begin_layout Author", j)
1744 revert_Argument_to_TeX_brace(document, j, 1, 2, False)
1746 if i == -1 and j == -1:
1750 def convert_SIGPLAN(document):
1751 " Converts ERT of MarkBoth to InsetArgument "
1752 if document.textclass == "sigplanconf":
1757 i = find_token(document.body, "\\begin_layout Conference", i)
1759 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1762 j = find_token(document.body, "\\begin_layout Author", j)
1764 convert_TeX_brace_to_Argument(document, j, 1, 2, False, False)
1766 if i == -1 and j == -1:
1770 def revert_SIGGRAPH(document):
1771 " Reverts InsetArgument of Flex CRcat to TeX-code "
1772 if document.textclass == "acmsiggraph":
1776 i = find_token(document.body, "\\begin_inset Flex CRcat", i)
1778 revert_Argument_to_TeX_brace(document, i, 1, 3, False)
1784 def convert_SIGGRAPH(document):
1785 " Converts ERT of Flex CRcat to InsetArgument "
1786 if document.textclass == "acmsiggraph":
1790 i = find_token(document.body, "\\begin_inset Flex CRcat", i)
1792 convert_TeX_brace_to_Argument(document, i, 1, 3, True, False)
1798 def revert_EuropeCV(document):
1799 " Reverts InsetArgument of Flex CRcat to TeX-code "
1800 if document.textclass == "europecv":
1807 i = find_token(document.body, "\\begin_layout Item", i)
1809 revert_Argument_to_TeX_brace(document, i, 2, 2, False)
1812 j = find_token(document.body, "\\begin_layout BulletedItem", j)
1814 revert_Argument_to_TeX_brace(document, j, 2, 2, False)
1817 k = find_token(document.body, "\\begin_layout Language", k)
1819 revert_Argument_to_TeX_brace(document, k, 2, 6, False)
1822 m = find_token(document.body, "\\begin_layout LastLanguage", m)
1824 revert_Argument_to_TeX_brace(document, m, 2, 6, False)
1826 if i == -1 and j == -1 and k == -1 and m == -1:
1830 def convert_EuropeCV(document):
1831 " Converts ERT of Flex CRcat to InsetArgument "
1832 if document.textclass == "europecv":
1839 i = find_token(document.body, "\\begin_layout Item", i)
1841 convert_TeX_brace_to_Argument(document, i, 2, 2, False, False)
1844 j = find_token(document.body, "\\begin_layout BulletedItem", j)
1846 convert_TeX_brace_to_Argument(document, j, 2, 2, False, False)
1849 k = find_token(document.body, "\\begin_layout Language", k)
1851 convert_TeX_brace_to_Argument(document, k, 2, 6, False, False)
1854 m = find_token(document.body, "\\begin_layout LastLanguage", m)
1856 convert_TeX_brace_to_Argument(document, m, 2, 6, False, False)
1858 if i == -1 and j == -1 and k == -1 and m == -1:
1862 def revert_literate(document):
1863 " Revert Literate document to old format "
1864 if del_token(document.header, "noweb", 0):
1865 document.textclass = "literate-" + document.textclass
1868 i = find_token(document.body, "\\begin_layout Chunk", i)
1871 document.body[i] = "\\begin_layout Scrap"
1875 def convert_literate(document):
1876 " Convert Literate document to new format"
1877 i = find_token(document.header, "\\textclass", 0)
1878 if (i != -1) and "literate-" in document.header[i]:
1879 document.textclass = document.header[i].replace("\\textclass literate-", "")
1880 j = find_token(document.header, "\\begin_modules", 0)
1882 document.header.insert(j + 1, "noweb")
1884 document.header.insert(i + 1, "\\end_modules")
1885 document.header.insert(i + 1, "noweb")
1886 document.header.insert(i + 1, "\\begin_modules")
1889 i = find_token(document.body, "\\begin_layout Scrap", i)
1892 document.body[i] = "\\begin_layout Chunk"
1896 def revert_itemargs(document):
1897 " Reverts \\item arguments to TeX-code "
1900 i = find_token(document.body, "\\begin_inset Argument item:", i)
1903 j = find_end_of_inset(document.body, i)
1904 # Find containing paragraph layout
1905 parent = get_containing_layout(document.body, i)
1907 document.warning("Malformed lyx document: Can't find parent paragraph layout")
1911 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
1912 endPlain = find_end_of_layout(document.body, beginPlain)
1913 content = document.body[beginPlain + 1 : endPlain]
1914 del document.body[i:j+1]
1915 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
1916 document.body[parbeg : parbeg] = subst
1920 def revert_garamondx_newtxmath(document):
1921 " Revert native garamond newtxmath definition to LaTeX "
1923 i = find_token(document.header, "\\font_math", 0)
1926 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1927 val = get_value(document.header, "\\font_math", i)
1928 if val == "garamondx-ntxm":
1929 add_to_preamble(document, "\\usepackage[garamondx]{newtxmath}")
1930 document.header[i] = "\\font_math auto"
1933 def revert_garamondx(document):
1934 " Revert native garamond font definition to LaTeX "
1936 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1937 i = find_token(document.header, "\\font_roman garamondx", 0)
1940 j = find_token(document.header, "\\font_osf true", 0)
1943 preamble = "\\usepackage"
1945 preamble += "[osfI]"
1946 preamble += "{garamondx}"
1947 add_to_preamble(document, [preamble])
1948 document.header[i] = "\\font_roman default"
1951 def convert_beamerargs(document):
1952 " Converts beamer arguments to new layout "
1954 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
1955 if document.textclass not in beamer_classes:
1958 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
1959 list_layouts = ["Itemize", "Enumerate", "Description"]
1960 rx = re.compile(r'^\\begin_inset Argument (\d+)$')
1964 i = find_token(document.body, "\\begin_inset Argument", i)
1967 # Find containing paragraph layout
1968 parent = get_containing_layout(document.body, i)
1970 document.warning("Malformed lyx document: Can't find parent paragraph layout")
1975 layoutname = parent[0]
1976 for p in range(parbeg, parend):
1977 if layoutname in shifted_layouts:
1978 m = rx.match(document.body[p])
1980 argnr = int(m.group(1))
1982 document.body[p] = "\\begin_inset Argument %d" % argnr
1983 if layoutname == "AgainFrame":
1984 m = rx.match(document.body[p])
1986 document.body[p] = "\\begin_inset Argument 3"
1987 if document.body[p + 4] == "\\begin_inset ERT":
1988 if document.body[p + 9].startswith("<"):
1989 # This is an overlay specification
1991 document.body[p + 9] = document.body[p + 9][1:]
1992 if document.body[p + 9].endswith(">"):
1994 document.body[p + 9] = document.body[p + 9][:-1]
1996 document.body[p] = "\\begin_inset Argument 2"
1997 if layoutname in list_layouts:
1998 m = rx.match(document.body[p])
2000 if m.group(1) == "1":
2001 if document.body[p + 4] == "\\begin_inset ERT":
2002 if document.body[p + 9].startswith("<"):
2003 # This is an overlay specification
2005 document.body[p + 9] = document.body[p + 9][1:]
2006 if document.body[p + 9].endswith(">"):
2008 document.body[p + 9] = document.body[p + 9][:-1]
2009 elif layoutname != "Itemize":
2011 document.body[p] = "\\begin_inset Argument 2"
2015 def convert_againframe_args(document):
2016 " Converts beamer AgainFrame to new layout "
2018 # FIXME: This currently only works if the arguments are in one single ERT
2020 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2021 if document.textclass not in beamer_classes:
2026 i = find_token(document.body, "\\begin_layout AgainFrame", i)
2029 parent = get_containing_layout(document.body, i)
2031 document.warning("Wrong parent layout!")
2035 if document.body[parbeg] == "\\begin_inset ERT":
2036 ertcont = parbeg + 5
2037 if document.body[ertcont].startswith("[<"):
2038 # This is a default overlay specification
2040 document.body[ertcont] = document.body[ertcont][2:]
2041 if document.body[ertcont].endswith(">]"):
2043 document.body[ertcont] = document.body[ertcont][:-2]
2044 elif document.body[ertcont].endswith("]"):
2046 tok = document.body[ertcont].find('>][')
2048 subst = [document.body[ertcont][:tok],
2049 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2050 'status collapsed', '', '\\begin_layout Plain Layout',
2051 document.body[ertcont][tok + 3:-1]]
2052 document.body[ertcont : ertcont + 1] = subst
2053 # Convert to ArgInset
2054 document.body[parbeg] = "\\begin_inset Argument 2"
2057 elif document.body[ertcont].startswith("<"):
2058 # This is an overlay specification
2060 document.body[ertcont] = document.body[ertcont][1:]
2061 if document.body[ertcont].endswith(">"):
2063 document.body[ertcont] = document.body[ertcont][:-1]
2064 # Convert to ArgInset
2065 document.body[parbeg] = "\\begin_inset Argument 1"
2066 elif document.body[ertcont].endswith(">]"):
2068 tok = document.body[ertcont].find('>[<')
2070 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2071 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2072 'status collapsed', '', '\\begin_layout Plain Layout',
2073 document.body[ertcont][tok + 3:-2]]
2074 # Convert to ArgInset
2075 document.body[parbeg] = "\\begin_inset Argument 1"
2076 elif document.body[ertcont].endswith("]"):
2078 tok = document.body[ertcont].find('>[<')
2081 tokk = document.body[ertcont].find('>][')
2083 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2084 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2085 'status collapsed', '', '\\begin_layout Plain Layout',
2086 document.body[ertcont][tok + 3:tokk],
2087 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2088 'status collapsed', '', '\\begin_layout Plain Layout',
2089 document.body[ertcont][tokk + 3:-1]]
2091 tokk = document.body[ertcont].find('>[')
2093 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tokk],
2094 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2095 'status collapsed', '', '\\begin_layout Plain Layout',
2096 document.body[ertcont][tokk + 2:-1]]
2097 # Convert to ArgInset
2098 document.body[parbeg] = "\\begin_inset Argument 1"
2101 elif document.body[ertcont].startswith("["):
2102 # This is an ERT option
2104 document.body[ertcont] = document.body[ertcont][1:]
2105 if document.body[ertcont].endswith("]"):
2107 document.body[ertcont] = document.body[ertcont][:-1]
2108 # Convert to ArgInset
2109 document.body[parbeg] = "\\begin_inset Argument 3"
2115 def convert_corollary_args(document):
2116 " Converts beamer corrolary-style ERT arguments native InsetArgs "
2118 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2119 if document.textclass not in beamer_classes:
2122 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2123 for lay in corollary_layouts:
2126 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2129 parent = get_containing_layout(document.body, i)
2131 document.warning("Wrong parent layout!")
2135 if document.body[parbeg] == "\\begin_inset ERT":
2136 ertcont = parbeg + 5
2137 if document.body[ertcont].startswith("<"):
2138 # This is an overlay specification
2140 document.body[ertcont] = document.body[ertcont][1:]
2141 if document.body[ertcont].endswith(">"):
2143 document.body[ertcont] = document.body[ertcont][:-1]
2144 elif document.body[ertcont].endswith("]"):
2146 tok = document.body[ertcont].find('>[')
2148 subst = [document.body[ertcont][:tok],
2149 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2150 'status collapsed', '', '\\begin_layout Plain Layout',
2151 document.body[ertcont][tok + 2:-1]]
2152 document.body[ertcont : ertcont + 1] = subst
2153 # Convert to ArgInset
2154 document.body[parbeg] = "\\begin_inset Argument 1"
2157 elif document.body[ertcont].startswith("["):
2158 # This is an ERT option
2160 document.body[ertcont] = document.body[ertcont][1:]
2161 if document.body[ertcont].endswith("]"):
2163 document.body[ertcont] = document.body[ertcont][:-1]
2164 # Convert to ArgInset
2165 document.body[parbeg] = "\\begin_inset Argument 2"
2172 def convert_quote_args(document):
2173 " Converts beamer quote style ERT args to native InsetArgs "
2175 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2176 if document.textclass not in beamer_classes:
2179 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2180 for lay in quote_layouts:
2183 i = find_token(document.body, "\\begin_layout " + lay, i)
2186 parent = get_containing_layout(document.body, i)
2188 document.warning("Wrong parent layout!")
2192 if document.body[parbeg] == "\\begin_inset ERT":
2193 if document.body[i + 6].startswith("<"):
2194 # This is an overlay specification
2196 document.body[i + 6] = document.body[i + 6][1:]
2197 if document.body[i + 6].endswith(">"):
2199 document.body[i + 6] = document.body[i + 6][:-1]
2200 # Convert to ArgInset
2201 document.body[i + 1] = "\\begin_inset Argument 1"
2205 def revert_beamerargs(document):
2206 " Reverts beamer arguments to old layout "
2208 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2209 if document.textclass not in beamer_classes:
2213 list_layouts = ["Itemize", "Enumerate", "Description"]
2214 headings = ["Part", "Section", "Section*", "Subsection", "Subsection*",
2215 "Subsubsection", "Subsubsection*", "FrameSubtitle", "NoteItem"]
2216 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2217 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2218 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2221 i = find_token(document.body, "\\begin_inset Argument", i)
2224 # Find containing paragraph layout
2225 parent = get_containing_layout(document.body, i)
2227 document.warning("Malformed lyx document: Can't find parent paragraph layout")
2232 realparbeg = parent[3]
2233 layoutname = parent[0]
2235 for p in range(parbeg, parend):
2239 if layoutname in headings:
2240 m = rx.match(document.body[p])
2244 # Find containing paragraph layout
2245 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2246 endPlain = find_end_of_layout(document.body, beginPlain)
2247 endInset = find_end_of_inset(document.body, p)
2248 argcontent = document.body[beginPlain + 1 : endPlain]
2250 realparend = realparend - len(document.body[p : endInset + 1])
2252 del document.body[p : endInset + 1]
2253 if layoutname == "FrameSubtitle":
2254 pre = put_cmd_in_ert("\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2255 elif layoutname == "NoteItem":
2256 pre = put_cmd_in_ert("\\note<") + argcontent + put_cmd_in_ert(">[item]")
2257 elif layoutname.endswith('*'):
2258 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower()[:-1] + "<") + argcontent + put_cmd_in_ert(">*")
2260 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2261 secarg = find_token(document.body, "\\begin_inset Argument 2", parbeg, parend)
2263 # Find containing paragraph layout
2264 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", secarg)
2265 endPlain = find_end_of_layout(document.body, beginPlain)
2266 endInset = find_end_of_inset(document.body, secarg)
2267 argcontent = document.body[beginPlain + 1 : endPlain]
2269 realparend = realparend - len(document.body[secarg : endInset + 1])
2270 del document.body[secarg : endInset + 1]
2271 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2272 pre += put_cmd_in_ert("{")
2273 document.body[parbeg] = "\\begin_layout Standard"
2274 document.body[realparbeg : realparbeg] = pre
2275 pe = find_end_of_layout(document.body, parbeg)
2276 post = put_cmd_in_ert("}")
2277 document.body[pe : pe] = post
2278 realparend += len(pre) + len(post)
2279 if layoutname == "AgainFrame":
2280 m = rx.match(document.body[p])
2284 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2285 endPlain = find_end_of_layout(document.body, beginPlain)
2286 endInset = find_end_of_inset(document.body, p)
2287 content = document.body[beginPlain + 1 : endPlain]
2289 realparend = realparend - len(document.body[p : endInset + 1])
2291 del document.body[p : endInset + 1]
2292 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2293 document.body[realparbeg : realparbeg] = subst
2294 if layoutname == "Overprint":
2295 m = rx.match(document.body[p])
2299 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2300 endPlain = find_end_of_layout(document.body, beginPlain)
2301 endInset = find_end_of_inset(document.body, p)
2302 content = document.body[beginPlain + 1 : endPlain]
2304 realparend = realparend - len(document.body[p : endInset + 1])
2306 del document.body[p : endInset + 1]
2307 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2308 document.body[realparbeg : realparbeg] = subst
2309 if layoutname == "OverlayArea":
2310 m = rx.match(document.body[p])
2314 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2315 endPlain = find_end_of_layout(document.body, beginPlain)
2316 endInset = find_end_of_inset(document.body, p)
2317 content = document.body[beginPlain + 1 : endPlain]
2319 realparend = realparend - len(document.body[p : endInset + 1])
2321 del document.body[p : endInset + 1]
2322 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2323 document.body[realparbeg : realparbeg] = subst
2324 if layoutname in list_layouts:
2325 m = rx.match(document.body[p])
2329 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2330 endPlain = find_end_of_layout(document.body, beginPlain)
2331 endInset = find_end_of_inset(document.body, p)
2332 content = document.body[beginPlain + 1 : endPlain]
2333 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2334 realparend = realparend + len(subst) - len(content)
2335 document.body[beginPlain + 1 : endPlain] = subst
2336 elif argnr == "item:1":
2337 j = find_end_of_inset(document.body, i)
2338 # Find containing paragraph layout
2339 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2340 endPlain = find_end_of_layout(document.body, beginPlain)
2341 content = document.body[beginPlain + 1 : endPlain]
2342 del document.body[i:j+1]
2343 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2344 document.body[realparbeg : realparbeg] = subst
2345 elif argnr == "item:2":
2346 j = find_end_of_inset(document.body, i)
2347 # Find containing paragraph layout
2348 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2349 endPlain = find_end_of_layout(document.body, beginPlain)
2350 content = document.body[beginPlain + 1 : endPlain]
2351 del document.body[i:j+1]
2352 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2353 document.body[realparbeg : realparbeg] = subst
2354 if layoutname in quote_layouts:
2355 m = rx.match(document.body[p])
2359 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2360 endPlain = find_end_of_layout(document.body, beginPlain)
2361 endInset = find_end_of_inset(document.body, p)
2362 content = document.body[beginPlain + 1 : endPlain]
2364 realparend = realparend - len(document.body[p : endInset + 1])
2366 del document.body[p : endInset + 1]
2367 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2368 document.body[realparbeg : realparbeg] = subst
2369 if layoutname in corollary_layouts:
2370 m = rx.match(document.body[p])
2374 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2375 endPlain = find_end_of_layout(document.body, beginPlain)
2376 endInset = find_end_of_inset(document.body, p)
2377 content = document.body[beginPlain + 1 : endPlain]
2379 realparend = realparend - len(document.body[p : endInset + 1])
2381 del document.body[p : endInset + 1]
2382 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2383 document.body[realparbeg : realparbeg] = subst
2388 def revert_beamerargs2(document):
2389 " Reverts beamer arguments to old layout, step 2 "
2391 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2392 if document.textclass not in beamer_classes:
2396 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
2397 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2398 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2401 i = find_token(document.body, "\\begin_inset Argument", i)
2404 # Find containing paragraph layout
2405 parent = get_containing_layout(document.body, i)
2407 document.warning("Malformed lyx document: Can't find parent paragraph layout")
2412 realparbeg = parent[3]
2413 layoutname = parent[0]
2415 for p in range(parbeg, parend):
2419 if layoutname in shifted_layouts:
2420 m = rx.match(document.body[p])
2424 document.body[p] = "\\begin_inset Argument 1"
2425 if layoutname in corollary_layouts:
2426 m = rx.match(document.body[p])
2430 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2431 endPlain = find_end_of_layout(document.body, beginPlain)
2432 endInset = find_end_of_inset(document.body, p)
2433 content = document.body[beginPlain + 1 : endPlain]
2435 realparend = realparend - len(document.body[p : endInset + 1])
2437 del document.body[p : endInset + 1]
2438 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2439 document.body[realparbeg : realparbeg] = subst
2440 if layoutname == "OverlayArea":
2441 m = rx.match(document.body[p])
2445 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2446 endPlain = find_end_of_layout(document.body, beginPlain)
2447 endInset = find_end_of_inset(document.body, p)
2448 content = document.body[beginPlain + 1 : endPlain]
2450 realparend = realparend - len(document.body[p : endInset + 1])
2452 del document.body[p : endInset + 1]
2453 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2454 document.body[realparbeg : realparbeg] = subst
2455 if layoutname == "AgainFrame":
2456 m = rx.match(document.body[p])
2460 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2461 endPlain = find_end_of_layout(document.body, beginPlain)
2462 endInset = find_end_of_inset(document.body, p)
2463 content = document.body[beginPlain + 1 : endPlain]
2465 realparend = realparend - len(document.body[p : endInset + 1])
2467 del document.body[p : endInset + 1]
2468 subst = put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
2469 document.body[realparbeg : realparbeg] = subst
2473 def revert_beamerargs3(document):
2474 " Reverts beamer arguments to old layout, step 3 "
2476 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2477 if document.textclass not in beamer_classes:
2480 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2483 i = find_token(document.body, "\\begin_inset Argument", i)
2486 # Find containing paragraph layout
2487 parent = get_containing_layout(document.body, i)
2489 document.warning("Malformed lyx document: Can't find parent paragraph layout")
2494 realparbeg = parent[3]
2495 layoutname = parent[0]
2497 for p in range(parbeg, parend):
2501 if layoutname == "AgainFrame":
2502 m = rx.match(document.body[p])
2506 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2507 endPlain = find_end_of_layout(document.body, beginPlain)
2508 endInset = find_end_of_inset(document.body, p)
2509 content = document.body[beginPlain + 1 : endPlain]
2511 realparend = realparend - len(document.body[p : endInset + 1])
2513 del document.body[p : endInset + 1]
2514 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2515 document.body[realparbeg : realparbeg] = subst
2519 def revert_beamerflex(document):
2520 " Reverts beamer Flex insets "
2522 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2523 if document.textclass not in beamer_classes:
2526 new_flexes = {"Bold" : "\\textbf", "Emphasize" : "\\emph", "Only" : "\\only",
2527 "Uncover" : "\\uncover", "Visible" : "\\visible",
2528 "Invisible" : "\\invisible", "Alternative" : "\\alt",
2529 "Beamer_Note" : "\\note"}
2530 old_flexes = {"Alert" : "\\alert", "Structure" : "\\structure"}
2531 rx = re.compile(r'^\\begin_inset Flex (.+)$')
2535 i = find_token(document.body, "\\begin_inset Flex", i)
2538 m = rx.match(document.body[i])
2540 flextype = m.group(1)
2541 z = find_end_of_inset(document.body, i)
2543 document.warning("Can't find end of Flex " + flextype + " inset.")
2546 if flextype in new_flexes:
2547 pre = put_cmd_in_ert(new_flexes[flextype])
2548 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2550 argend = find_end_of_inset(document.body, arg)
2552 document.warning("Can't find end of Argument!")
2555 # Find containing paragraph layout
2556 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2557 endPlain = find_end_of_layout(document.body, beginPlain)
2558 argcontent = document.body[beginPlain + 1 : endPlain]
2560 z = z - len(document.body[arg : argend + 1])
2562 del document.body[arg : argend + 1]
2563 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2564 arg = find_token(document.body, "\\begin_inset Argument 2", i, z)
2566 argend = find_end_of_inset(document.body, arg)
2568 document.warning("Can't find end of Argument!")
2571 # Find containing paragraph layout
2572 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2573 endPlain = find_end_of_layout(document.body, beginPlain)
2574 argcontent = document.body[beginPlain + 1 : endPlain]
2576 z = z - len(document.body[arg : argend + 1])
2578 del document.body[arg : argend + 1]
2579 if flextype == "Alternative":
2580 pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
2582 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2583 pre += put_cmd_in_ert("{")
2584 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2585 endPlain = find_end_of_layout(document.body, beginPlain)
2587 z = z - len(document.body[i : beginPlain + 1])
2589 document.body[i : beginPlain + 1] = pre
2590 post = put_cmd_in_ert("}")
2591 document.body[z - 2 : z + 1] = post
2592 elif flextype in old_flexes:
2593 pre = put_cmd_in_ert(old_flexes[flextype])
2594 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2598 argend = find_end_of_inset(document.body, arg)
2600 document.warning("Can't find end of Argument!")
2603 # Find containing paragraph layout
2604 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2605 endPlain = find_end_of_layout(document.body, beginPlain)
2606 argcontent = document.body[beginPlain + 1 : endPlain]
2608 z = z - len(document.body[arg : argend + 1])
2610 del document.body[arg : argend + 1]
2611 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2612 pre += put_cmd_in_ert("{")
2613 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2614 endPlain = find_end_of_layout(document.body, beginPlain)
2616 z = z - len(document.body[i : beginPlain + 1])
2618 document.body[i : beginPlain + 1] = pre
2619 post = put_cmd_in_ert("}")
2620 document.body[z - 2 : z + 1] = post
2625 def revert_beamerblocks(document):
2626 " Reverts beamer block arguments to ERT "
2628 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2629 if document.textclass not in beamer_classes:
2632 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2634 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2637 i = find_token(document.body, "\\begin_inset Argument", i)
2640 # Find containing paragraph layout
2641 parent = get_containing_layout(document.body, i)
2643 document.warning("Malformed lyx document: Can't find parent paragraph layout")
2648 realparbeg = parent[3]
2649 layoutname = parent[0]
2651 for p in range(parbeg, parend):
2655 if layoutname in blocks:
2656 m = rx.match(document.body[p])
2660 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2661 endPlain = find_end_of_layout(document.body, beginPlain)
2662 endInset = find_end_of_inset(document.body, p)
2663 content = document.body[beginPlain + 1 : endPlain]
2665 realparend = realparend - len(document.body[p : endInset + 1])
2667 del document.body[p : endInset + 1]
2668 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2669 document.body[realparbeg : realparbeg] = subst
2671 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2672 endPlain = find_end_of_layout(document.body, beginPlain)
2673 endInset = find_end_of_inset(document.body, p)
2674 content = document.body[beginPlain + 1 : endPlain]
2676 realparend = realparend - len(document.body[p : endInset + 1])
2678 del document.body[p : endInset + 1]
2679 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2680 document.body[realparbeg : realparbeg] = subst
2685 def convert_beamerblocks(document):
2686 " Converts beamer block ERT args to native InsetArgs "
2688 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2689 if document.textclass not in beamer_classes:
2692 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2696 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2699 parent = get_containing_layout(document.body, i)
2700 if parent == False or parent[1] != i:
2701 document.warning("Wrong parent layout!")
2707 if document.body[parbeg] == "\\begin_inset ERT":
2708 ertcont = parbeg + 5
2710 if document.body[ertcont].startswith("<"):
2711 # This is an overlay specification
2713 document.body[ertcont] = document.body[ertcont][1:]
2714 if document.body[ertcont].endswith(">"):
2716 document.body[ertcont] = document.body[ertcont][:-1]
2717 # Convert to ArgInset
2718 document.body[parbeg] = "\\begin_inset Argument 1"
2719 elif document.body[ertcont].endswith("}"):
2721 tok = document.body[ertcont].find('>{')
2723 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2724 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2725 'status collapsed', '', '\\begin_layout Plain Layout',
2726 document.body[ertcont][tok + 2:-1]]
2727 # Convert to ArgInset
2728 document.body[parbeg] = "\\begin_inset Argument 1"
2729 elif document.body[ertcont].startswith("{"):
2730 # This is the block title
2731 if document.body[ertcont].endswith("}"):
2732 # strip off the braces
2733 document.body[ertcont] = document.body[ertcont][1:-1]
2734 # Convert to ArgInset
2735 document.body[parbeg] = "\\begin_inset Argument 2"
2736 elif count_pars_in_inset(document.body, ertcont) > 1:
2737 # Multipar ERT. Skip this.
2740 convert_TeX_brace_to_Argument(document, i, 2, 2, False, True)
2743 j = find_end_of_layout(document.body, i)
2745 document.warning("end of layout not found!")
2746 k = find_token(document.body, "\\begin_inset Argument", i, j)
2748 document.warning("InsetArgument not found!")
2750 l = find_end_of_inset(document.body, k)
2751 m = find_token(document.body, "\\begin_inset ERT", l, j)
2759 def convert_overprint(document):
2760 " Convert old beamer overprint layouts to ERT "
2762 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2763 if document.textclass not in beamer_classes:
2768 i = find_token(document.body, "\\begin_layout Overprint", i)
2771 # Find end of sequence
2772 j = find_end_of_sequence(document.body, i)
2774 document.warning("Malformed lyx document. Cannot find end of Overprint sequence!")
2778 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
2780 if document.body[j] == "\\end_deeper":
2781 esubst = ["", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
2783 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
2784 endseq = endseq + len(esubst) - len(document.body[j : j])
2785 document.body[j : j] = esubst
2786 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
2788 argend = find_end_of_layout(document.body, argbeg)
2790 document.warning("Malformed lyx document. Cannot find end of Overprint argument!")
2793 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
2794 endPlain = find_end_of_layout(document.body, beginPlain)
2795 content = document.body[beginPlain + 1 : endPlain]
2797 endseq = endseq - len(document.body[argbeg : argend + 1])
2799 del document.body[argbeg : argend + 1]
2800 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2802 endseq = endseq - len(document.body[i : i])
2803 document.body[i : i] = subst + ["\\end_layout"]
2804 endseq += len(subst)
2806 for p in range(i, endseq):
2807 if document.body[p] == "\\begin_layout Overprint":
2808 document.body[p] = "\\begin_layout Standard"
2813 def revert_overprint(document):
2814 " Revert old beamer overprint layouts to ERT "
2816 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2817 if document.textclass not in beamer_classes:
2822 i = find_token(document.body, "\\begin_layout Overprint", i)
2825 # Find end of sequence
2826 j = find_end_of_sequence(document.body, i)
2828 document.warning("Malformed lyx document. Cannot find end of Overprint sequence!")
2832 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
2833 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}")
2834 endseq = endseq + len(esubst) - len(document.body[j : j])
2835 if document.body[j] == "\\end_deeper":
2836 document.body[j : j] = ["\\end_deeper", ""] + esubst
2838 document.body[j : j] = esubst
2841 if document.body[r] == "\\begin_deeper":
2842 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
2844 document.body[r] = ""
2845 document.body[s] = ""
2849 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
2851 argend = find_end_of_inset(document.body, argbeg)
2853 document.warning("Malformed lyx document. Cannot find end of Overprint argument!")
2856 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
2857 endPlain = find_end_of_layout(document.body, beginPlain)
2858 content = document.body[beginPlain + 1 : endPlain]
2860 endseq = endseq - len(document.body[argbeg : argend])
2862 del document.body[argbeg : argend + 1]
2863 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2865 endseq = endseq - len(document.body[i : i])
2866 document.body[i : i] = subst + ["\\end_layout"]
2867 endseq += len(subst)
2873 if document.body[p] == "\\begin_layout Overprint":
2874 q = find_end_of_layout(document.body, p)
2876 document.warning("Malformed lyx document. Cannot find end of Overprint layout!")
2879 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\onslide")
2880 argbeg = find_token(document.body, "\\begin_inset Argument item:1", p, q)
2882 argend = find_end_of_inset(document.body, argbeg)
2884 document.warning("Malformed lyx document. Cannot find end of Overprint item argument!")
2887 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
2888 endPlain = find_end_of_layout(document.body, beginPlain)
2889 content = document.body[beginPlain + 1 : endPlain]
2891 endseq = endseq - len(document.body[argbeg : argend + 1])
2893 del document.body[argbeg : argend + 1]
2894 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2895 endseq = endseq - len(document.body[p : p + 1]) + len(subst)
2896 document.body[p : p + 1] = subst
2902 def revert_frametitle(document):
2903 " Reverts beamer frametitle layout to ERT "
2905 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2906 if document.textclass not in beamer_classes:
2909 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2912 i = find_token(document.body, "\\begin_layout FrameTitle", i)
2915 j = find_end_of_layout(document.body, i)
2917 document.warning("Malformed lyx document: Can't find end of FrameTitle layout")
2921 document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
2922 endlay += len(put_cmd_in_ert("}"))
2923 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\frametitle")
2924 for p in range(i, j):
2927 m = rx.match(document.body[p])
2931 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2932 endPlain = find_end_of_layout(document.body, beginPlain)
2933 endInset = find_end_of_inset(document.body, p)
2934 content = document.body[beginPlain + 1 : endPlain]
2936 endlay = endlay - len(document.body[p : endInset + 1])
2938 del document.body[p : endInset + 1]
2939 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2941 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2942 endPlain = find_end_of_layout(document.body, beginPlain)
2943 endInset = find_end_of_inset(document.body, p)
2944 content = document.body[beginPlain + 1 : endPlain]
2946 endlay = endlay - len(document.body[p : endInset + 1])
2948 del document.body[p : endInset + 1]
2949 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2951 subst += put_cmd_in_ert("{")
2952 document.body[i : i + 1] = subst
2956 def convert_epigraph(document):
2957 " Converts memoir epigraph to new syntax "
2959 if document.textclass != "memoir":
2964 i = find_token(document.body, "\\begin_layout Epigraph", i)
2967 j = find_end_of_layout(document.body, i)
2969 document.warning("Malformed lyx document: Can't find end of Epigraph layout")
2974 ert = find_token(document.body, "\\begin_inset ERT", i, j)
2976 endInset = find_end_of_inset(document.body, ert)
2977 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", ert)
2978 endPlain = find_end_of_layout(document.body, beginPlain)
2979 ertcont = beginPlain + 2
2980 if document.body[ertcont] == "}{":
2982 # Convert to ArgInset
2983 endlay = endlay - 2 * len(document.body[j])
2984 begsubst = ['\\begin_inset Argument post:1', 'status collapsed', '',
2985 '\\begin_layout Plain Layout']
2986 endsubst = ['\\end_layout', '', '\\end_inset', '', document.body[j]]
2987 document.body[j : j + 1] = endsubst
2988 document.body[endInset + 1 : endInset + 1] = begsubst
2990 endlay += len(begsubst) + len(endsubst)
2991 endlay = endlay - len(document.body[ert : endInset + 1])
2992 del document.body[ert : endInset + 1]
2997 def revert_epigraph(document):
2998 " Reverts memoir epigraph argument to ERT "
3000 if document.textclass != "memoir":
3005 i = find_token(document.body, "\\begin_layout Epigraph", i)
3008 j = find_end_of_layout(document.body, i)
3010 document.warning("Malformed lyx document: Can't find end of Epigraph layout")
3015 p = find_token(document.body, "\\begin_layout Argument post:1", i, j)
3017 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3018 endPlain = find_end_of_layout(document.body, beginPlain)
3019 endInset = find_end_of_inset(document.body, p)
3020 content = document.body[beginPlain + 1 : endPlain]
3022 endlay = endlay - len(document.body[p : endInset + 1])
3024 del document.body[p : endInset + 1]
3025 subst += put_cmd_in_ert("}{") + content
3027 subst += put_cmd_in_ert("}{")
3029 document.body[j : j] = subst + document.body[j : j]
3033 def convert_captioninsets(document):
3034 " Converts caption insets to new syntax "
3038 i = find_token(document.body, "\\begin_inset Caption", i)
3041 document.body[i] = "\\begin_inset Caption Standard"
3046 def revert_captioninsets(document):
3047 " Reverts caption insets to old syntax "
3051 i = find_token(document.body, "\\begin_inset Caption Standard", i)
3054 document.body[i] = "\\begin_inset Caption"
3058 def convert_captionlayouts(document):
3059 " Convert caption layouts to caption insets. "
3062 "Captionabove": "Above",
3063 "Captionbelow": "Below",
3064 "FigCaption" : "FigCaption",
3065 "Table_Caption" : "Table",
3066 "CenteredCaption" : "Centered",
3067 "Bicaption" : "Bicaption",
3072 i = find_token(document.body, "\\begin_layout", i)
3075 val = get_value(document.body, "\\begin_layout", i)
3076 if val in caption_dict.keys():
3077 j = find_end_of_layout(document.body, i)
3079 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3082 document.body[j:j] = ["\\end_layout", "", "\\end_inset", "", ""]
3083 document.body[i:i+1] = ["\\begin_layout %s" % document.default_layout,
3084 "\\begin_inset Caption %s" % caption_dict[val], "",
3085 "\\begin_layout %s" % document.default_layout]
3089 def revert_captionlayouts(document):
3090 " Revert caption insets to caption layouts. "
3093 "Above" : "Captionabove",
3094 "Below" : "Captionbelow",
3095 "FigCaption" : "FigCaption",
3096 "Table" : "Table_Caption",
3097 "Centered" : "CenteredCaption",
3098 "Bicaption" : "Bicaption",
3102 rx = re.compile(r'^\\begin_inset Caption (\S+)$')
3104 i = find_token(document.body, "\\begin_inset Caption", i)
3108 m = rx.match(document.body[i])
3112 if val not in caption_dict.keys():
3116 # We either need to delete the previous \begin_layout line, or we
3117 # need to end the previous layout if this inset is not in the first
3118 # position of the paragraph.
3119 layout_before = find_token_backwards(document.body, "\\begin_layout", i)
3120 if layout_before == -1:
3121 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3123 layout_line = document.body[layout_before]
3124 del_layout_before = True
3125 l = layout_before + 1
3127 if document.body[l] != "":
3128 del_layout_before = False
3131 if del_layout_before:
3132 del document.body[layout_before:i]
3135 document.body[i:i] = ["\\end_layout", ""]
3138 # Find start of layout in the inset and end of inset
3139 j = find_token(document.body, "\\begin_layout", i)
3141 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3143 k = find_end_of_inset(document.body, i)
3145 document.warning("Malformed LyX document: Missing `\\end_inset'.")
3148 # We either need to delete the following \end_layout line, or we need
3149 # to restart the old layout if this inset is not at the paragraph end.
3150 layout_after = find_token(document.body, "\\end_layout", k)
3151 if layout_after == -1:
3152 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3154 del_layout_after = True
3156 while l < layout_after:
3157 if document.body[l] != "":
3158 del_layout_after = False
3161 if del_layout_after:
3162 del document.body[k+1:layout_after+1]
3164 document.body[k+1:k+1] = [layout_line, ""]
3166 # delete \begin_layout and \end_inset and replace \begin_inset with
3167 # "\begin_layout XXX". This works because we can only have one
3168 # paragraph in the caption inset: The old \end_layout will be recycled.
3169 del document.body[k]
3170 if document.body[k] == "":
3171 del document.body[k]
3172 del document.body[j]
3173 if document.body[j] == "":
3174 del document.body[j]
3175 document.body[i] = "\\begin_layout %s" % caption_dict[val]
3176 if document.body[i+1] == "":
3177 del document.body[i+1]
3181 def revert_fragileframe(document):
3182 " Reverts beamer FragileFrame layout to ERT "
3184 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3185 if document.textclass not in beamer_classes:
3190 i = find_token(document.body, "\\begin_layout FragileFrame", i)
3193 # Find end of sequence
3194 j = find_end_of_sequence(document.body, i)
3196 document.warning("Malformed lyx document. Cannot find end of FragileFrame sequence!")
3200 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{frame}")
3201 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{frame}")
3202 endseq = endseq + len(esubst) - len(document.body[j : j])
3203 if document.body[j] == "\\end_deeper":
3204 document.body[j : j] = ["\\end_deeper", ""] + esubst
3206 document.body[j : j] = esubst
3207 for q in range(i, j):
3208 if document.body[q] == "\\begin_layout FragileFrame":
3209 document.body[q] = "\\begin_layout %s" % document.default_layout
3212 if document.body[r] == "\\begin_deeper":
3213 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3215 document.body[r] = ""
3216 document.body[s] = ""
3220 for p in range(1, 5):
3221 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, j)
3224 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3225 endPlain = find_end_of_layout(document.body, beginPlain)
3226 endInset = find_end_of_inset(document.body, arg)
3227 content = document.body[beginPlain + 1 : endPlain]
3229 j = j - len(document.body[arg : endInset + 1])
3231 del document.body[arg : endInset + 1]
3232 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3234 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3235 endPlain = find_end_of_layout(document.body, beginPlain)
3236 endInset = find_end_of_inset(document.body, arg)
3237 content = document.body[beginPlain + 1 : endPlain]
3239 j = j - len(document.body[arg : endInset + 1])
3241 del document.body[arg : endInset + 1]
3242 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3244 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3245 endPlain = find_end_of_layout(document.body, beginPlain)
3246 endInset = find_end_of_inset(document.body, arg)
3247 content = document.body[beginPlain + 1 : endPlain]
3249 j = j - len(document.body[arg : endInset + 1])
3251 del document.body[arg : endInset + 1]
3252 subst += put_cmd_in_ert("[fragile,") + content + put_cmd_in_ert("]")
3254 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3255 endPlain = find_end_of_layout(document.body, beginPlain)
3256 endInset = find_end_of_inset(document.body, arg)
3257 content = document.body[beginPlain + 1 : endPlain]
3259 j = j - len(document.body[arg : endInset + 1])
3261 del document.body[arg : endInset + 1]
3262 subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
3264 subst += put_cmd_in_ert("[fragile]")
3266 document.body[i : i + 1] = subst
3270 def revert_newframes(document):
3271 " Reverts beamer Frame and PlainFrame layouts to old forms "
3273 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3274 if document.textclass not in beamer_classes:
3278 "Frame" : "BeginFrame",
3279 "PlainFrame" : "BeginPlainFrame",
3282 rx = re.compile(r'^\\begin_layout (\S+)$')
3285 i = find_token(document.body, "\\begin_layout", i)
3289 m = rx.match(document.body[i])
3293 if val not in frame_dict.keys():
3296 # Find end of sequence
3297 j = find_end_of_sequence(document.body, i)
3299 document.warning("Malformed lyx document. Cannot find end of Frame sequence!")
3303 subst = ["\\begin_layout %s" % frame_dict[val]]
3304 esubst = ["\\end_layout", "", "\\begin_layout EndFrame", "", "\\end_layout"]
3305 endseq = endseq + len(esubst) - len(document.body[j : j])
3306 if document.body[j] == "\\end_deeper":
3307 document.body[j : j] = ["\\end_deeper", ""] + esubst
3309 document.body[j : j] = esubst
3310 for q in range(i, j):
3311 if document.body[q] == "\\begin_layout %s" % val:
3312 document.body[q] = "\\begin_layout %s" % document.default_layout
3315 if document.body[r] == "\\begin_deeper":
3316 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3318 document.body[r] = ""
3319 document.body[s] = ""
3323 l = find_end_of_layout(document.body, i)
3324 for p in range(1, 5):
3325 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, l)
3328 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3329 endPlain = find_end_of_layout(document.body, beginPlain)
3330 endInset = find_end_of_inset(document.body, arg)
3331 content = document.body[beginPlain + 1 : endPlain]
3333 l = l - len(document.body[arg : endInset + 1])
3335 del document.body[arg : endInset + 1]
3336 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3338 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3339 endPlain = find_end_of_layout(document.body, beginPlain)
3340 endInset = find_end_of_inset(document.body, arg)
3341 content = document.body[beginPlain + 1 : endPlain]
3343 l = l - len(document.body[arg : endInset + 1])
3345 del document.body[arg : endInset + 1]
3346 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3348 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3349 endPlain = find_end_of_layout(document.body, beginPlain)
3350 endInset = find_end_of_inset(document.body, arg)
3351 content = document.body[beginPlain + 1 : endPlain]
3353 l = l - len(document.body[arg : endInset + 1])
3355 del document.body[arg : endInset + 1]
3356 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3358 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3359 endPlain = find_end_of_layout(document.body, beginPlain)
3360 endInset = find_end_of_inset(document.body, arg)
3361 content = document.body[beginPlain + 1 : endPlain]
3363 l = l - len(document.body[arg : endInset + 1])
3365 del document.body[arg : endInset + 1]
3368 document.body[i : i + 1] = subst
3376 supported_versions = ["2.1.0","2.1"]
3379 [415, [convert_undertilde]],
3381 [417, [convert_japanese_encodings]],
3384 [420, [convert_biblio_style]],
3385 [421, [convert_longtable_captions]],
3386 [422, [convert_use_packages]],
3387 [423, [convert_use_mathtools]],
3388 [424, [convert_cite_engine_type]],
3392 [428, [convert_cell_rotation]],
3393 [429, [convert_table_rotation]],
3394 [430, [convert_listoflistings]],
3395 [431, [convert_use_amssymb]],
3397 [433, [convert_armenian]],
3405 [441, [convert_mdnomath]],
3410 [446, [convert_latexargs]],
3411 [447, [convert_IEEEtran, convert_AASTeX, convert_AGUTeX, convert_IJMP, convert_SIGPLAN, convert_SIGGRAPH, convert_EuropeCV]],
3412 [448, [convert_literate]],
3415 [451, [convert_beamerargs, convert_againframe_args, convert_corollary_args, convert_quote_args]],
3416 [452, [convert_beamerblocks]],
3417 [453, [convert_use_stmaryrd]],
3418 [454, [convert_overprint]],
3420 [456, [convert_epigraph]],
3421 [457, [convert_use_stackrel]],
3422 [458, [convert_captioninsets, convert_captionlayouts]],
3427 [458, [revert_fragileframe, revert_newframes]],
3428 [457, [revert_captioninsets, revert_captionlayouts]],
3429 [456, [revert_use_stackrel]],
3430 [455, [revert_epigraph]],
3431 [454, [revert_frametitle]],
3432 [453, [revert_overprint]],
3433 [452, [revert_use_stmaryrd]],
3434 [451, [revert_beamerblocks]],
3435 [450, [revert_beamerargs, revert_beamerargs2, revert_beamerargs3, revert_beamerflex]],
3436 [449, [revert_garamondx, revert_garamondx_newtxmath]],
3437 [448, [revert_itemargs]],
3438 [447, [revert_literate]],
3439 [446, [revert_IEEEtran, revert_AASTeX, revert_AGUTeX, revert_IJMP, revert_SIGPLAN, revert_SIGGRAPH, revert_EuropeCV]],
3440 [445, [revert_latexargs]],
3441 [444, [revert_uop]],
3442 [443, [revert_biolinum]],
3444 [441, [revert_newtxmath]],
3445 [440, [revert_mdnomath]],
3446 [439, [revert_mathfonts]],
3447 [438, [revert_minionpro]],
3448 [437, [revert_ipadeco, revert_ipachar]],
3449 [436, [revert_texgyre]],
3450 [435, [revert_mathdesign]],
3451 [434, [revert_txtt]],
3452 [433, [revert_libertine]],
3453 [432, [revert_armenian]],
3454 [431, [revert_languages, revert_ancientgreek]],
3455 [430, [revert_use_amssymb]],
3456 [429, [revert_listoflistings]],
3457 [428, [revert_table_rotation]],
3458 [427, [revert_cell_rotation]],
3459 [426, [revert_tipa]],
3460 [425, [revert_verbatim]],
3461 [424, [revert_cancel]],
3462 [423, [revert_cite_engine_type]],
3463 [422, [revert_use_mathtools]],
3464 [421, [revert_use_packages]],
3465 [420, [revert_longtable_captions]],
3466 [419, [revert_biblio_style]],
3467 [418, [revert_australian]],
3468 [417, [revert_justification]],
3469 [416, [revert_japanese_encodings]],
3470 [415, [revert_negative_space, revert_math_spaces]],
3471 [414, [revert_undertilde]],
3472 [413, [revert_visible_space]]
3476 if __name__ == "__main__":