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"
964 preamble += "[lining]"
965 preamble += "{libertine-type1}"
966 add_to_preamble(document, [preamble])
967 document.header[i] = "\\font_roman default"
970 def revert_txtt(document):
971 " Revert native txtt font definition to LaTeX "
973 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
974 i = find_token(document.header, "\\font_typewriter txtt", 0)
976 preamble = "\\renewcommand{\\ttdefault}{txtt}"
977 add_to_preamble(document, [preamble])
978 document.header[i] = "\\font_typewriter default"
981 def revert_mathdesign(document):
982 " Revert native mathdesign font definition to LaTeX "
984 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
990 i = find_token(document.header, "\\font_roman", 0)
993 val = get_value(document.header, "\\font_roman", i)
994 if val in mathdesign_dict.keys():
995 preamble = "\\usepackage[%s" % mathdesign_dict[val]
997 j = find_token(document.header, "\\font_osf true", 0)
1000 document.header[j] = "\\font_osf false"
1001 l = find_token(document.header, "\\font_sc true", 0)
1004 document.header[l] = "\\font_sc false"
1006 preamble += ",expert"
1007 preamble += "]{mathdesign}"
1008 add_to_preamble(document, [preamble])
1009 document.header[i] = "\\font_roman default"
1012 def revert_texgyre(document):
1013 " Revert native TeXGyre font definition to LaTeX "
1015 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1016 texgyre_fonts = ["tgadventor", "tgbonum", "tgchorus", "tgcursor", \
1017 "tgheros", "tgpagella", "tgschola", "tgtermes"]
1018 i = find_token(document.header, "\\font_roman", 0)
1020 val = get_value(document.header, "\\font_roman", i)
1021 if val in texgyre_fonts:
1022 preamble = "\\usepackage{%s}" % val
1023 add_to_preamble(document, [preamble])
1024 document.header[i] = "\\font_roman default"
1025 i = find_token(document.header, "\\font_sans", 0)
1027 val = get_value(document.header, "\\font_sans", i)
1028 if val in texgyre_fonts:
1029 preamble = "\\usepackage{%s}" % val
1030 add_to_preamble(document, [preamble])
1031 document.header[i] = "\\font_sans default"
1032 i = find_token(document.header, "\\font_typewriter", 0)
1034 val = get_value(document.header, "\\font_typewriter", i)
1035 if val in texgyre_fonts:
1036 preamble = "\\usepackage{%s}" % val
1037 add_to_preamble(document, [preamble])
1038 document.header[i] = "\\font_typewriter default"
1041 def revert_ipadeco(document):
1042 " Revert IPA decorations to ERT "
1045 i = find_token(document.body, "\\begin_inset IPADeco", i)
1048 end = find_end_of_inset(document.body, i)
1050 document.warning("Can't find end of inset at line " + str(i))
1053 line = document.body[i]
1054 rx = re.compile(r'\\begin_inset IPADeco (.*)$')
1056 decotype = m.group(1)
1057 if decotype != "toptiebar" and decotype != "bottomtiebar":
1058 document.warning("Invalid IPADeco type: " + decotype)
1061 blay = find_token(document.body, "\\begin_layout Plain Layout", i, end)
1063 document.warning("Can't find layout for inset at line " + str(i))
1066 bend = find_end_of_layout(document.body, blay)
1068 document.warning("Malformed LyX document: Could not find end of IPADeco inset's layout.")
1071 substi = ["\\begin_inset ERT", "status collapsed", "",
1072 "\\begin_layout Plain Layout", "", "", "\\backslash",
1073 decotype + "{", "\\end_layout", "", "\\end_inset"]
1074 substj = ["\\size default", "", "\\begin_inset ERT", "status collapsed", "",
1075 "\\begin_layout Plain Layout", "", "}", "\\end_layout", "", "\\end_inset"]
1076 # do the later one first so as not to mess up the numbering
1077 document.body[bend:end + 1] = substj
1078 document.body[i:blay + 1] = substi
1079 i = end + len(substi) + len(substj) - (end - bend) - (blay - i) - 2
1080 add_to_preamble(document, "\\usepackage{tipa}")
1083 def revert_ipachar(document):
1084 ' Revert \\IPAChar to ERT '
1087 while i < len(document.body):
1088 m = re.match(r'(.*)\\IPAChar \\(\w+\{\w+\})(.*)', document.body[i])
1092 ipachar = m.group(2)
1095 '\\begin_inset ERT',
1096 'status collapsed', '',
1097 '\\begin_layout Standard',
1098 '', '', '\\backslash',
1103 document.body[i: i+1] = subst
1108 add_to_preamble(document, "\\usepackage{tone}")
1111 def revert_minionpro(document):
1112 " Revert native MinionPro font definition to LaTeX "
1114 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1115 i = find_token(document.header, "\\font_roman minionpro", 0)
1118 j = find_token(document.header, "\\font_osf true", 0)
1121 preamble = "\\usepackage"
1123 document.header[j] = "\\font_osf false"
1126 preamble += "{MinionPro}"
1127 add_to_preamble(document, [preamble])
1128 document.header[i] = "\\font_roman default"
1131 def revert_mathfonts(document):
1132 " Revert native math font definitions to LaTeX "
1134 i = find_token(document.header, "\\font_math", 0)
1137 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1138 val = get_value(document.header, "\\font_math", i)
1139 if val == "eulervm":
1140 add_to_preamble(document, "\\usepackage{eulervm}")
1141 elif val == "default":
1143 "lmodern": "\\renewcommand{\\rmdefault}{lmr}",
1144 "minionpro": "\\usepackage[onlytext,lf]{MinionPro}",
1145 "minionpro-osf": "\\usepackage[onlytext]{MinionPro}",
1146 "palatino": "\\renewcommand{\\rmdefault}{ppl}",
1147 "palatino-osf": "\\renewcommand{\\rmdefault}{pplj}",
1148 "times": "\\renewcommand{\\rmdefault}{ptm}",
1149 "utopia": "\\renewcommand{\\rmdefault}{futs}",
1150 "utopia-osf": "\\renewcommand{\\rmdefault}{futj}",
1152 j = find_token(document.header, "\\font_roman", 0)
1154 rm = get_value(document.header, "\\font_roman", j)
1155 k = find_token(document.header, "\\font_osf true", 0)
1158 if rm in mathfont_dict.keys():
1159 add_to_preamble(document, mathfont_dict[rm])
1160 document.header[j] = "\\font_roman default"
1162 document.header[k] = "\\font_osf false"
1163 del document.header[i]
1166 def revert_mdnomath(document):
1167 " Revert mathdesign and fourier without math "
1169 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1171 "md-charter": "mdbch",
1172 "md-utopia": "mdput",
1173 "md-garamond": "mdugm"
1175 i = find_token(document.header, "\\font_roman", 0)
1178 val = get_value(document.header, "\\font_roman", i)
1179 if val in mathdesign_dict.keys():
1180 j = find_token(document.header, "\\font_math", 0)
1182 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1183 mval = get_value(document.header, "\\font_math", j)
1184 if mval == "default":
1185 document.header[i] = "\\font_roman default"
1186 add_to_preamble(document, "\\renewcommand{\\rmdefault}{%s}" % mathdesign_dict[val])
1188 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1191 def convert_mdnomath(document):
1192 " Change mathdesign font name "
1194 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1196 "mdbch": "md-charter",
1197 "mdput": "md-utopia",
1198 "mdugm": "md-garamond"
1200 i = find_token(document.header, "\\font_roman", 0)
1203 val = get_value(document.header, "\\font_roman", i)
1204 if val in mathdesign_dict.keys():
1205 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1208 def revert_newtxmath(document):
1209 " Revert native newtxmath definitions to LaTeX "
1211 i = find_token(document.header, "\\font_math", 0)
1214 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1215 val = get_value(document.header, "\\font_math", i)
1217 "libertine-ntxm": "\\usepackage[libertine]{newtxmath}",
1218 "minion-ntxm": "\\usepackage[minion]{newtxmath}",
1219 "newtxmath": "\\usepackage{newtxmath}",
1221 if val in mathfont_dict.keys():
1222 add_to_preamble(document, mathfont_dict[val])
1223 document.header[i] = "\\font_math auto"
1226 def revert_biolinum(document):
1227 " Revert native biolinum font definition to LaTeX "
1229 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1230 i = find_token(document.header, "\\font_sans biolinum", 0)
1233 j = find_token(document.header, "\\font_osf true", 0)
1236 preamble = "\\usepackage"
1239 preamble += "{biolinum-type1}"
1240 add_to_preamble(document, [preamble])
1241 document.header[i] = "\\font_sans default"
1244 def revert_uop(document):
1245 " Revert native URW Classico (Optima) font definition to LaTeX "
1247 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1248 i = find_token(document.header, "\\font_sans uop", 0)
1250 preamble = "\\renewcommand{\\sfdefault}{uop}"
1251 add_to_preamble(document, [preamble])
1252 document.header[i] = "\\font_sans default"
1255 def convert_latexargs(document):
1256 " Convert InsetArgument to new syntax "
1258 if find_token(document.body, "\\begin_inset Argument", 0) == -1:
1262 # A list of layouts (document classes) with only optional or no arguments.
1263 # These can be safely converted to the new syntax
1264 # (I took the liberty to add some of my personal layouts/modules here; JSP)
1265 safe_layouts = ["aa", "aapaper", "aastex", "achemso", "acmsiggraph", "AEA",
1266 "agu-dtd", "agums", "agutex", "amsart", "amsbook", "apa",
1267 "arab-article", "armenian-article", "article-beamer", "article",
1268 "beamer", "book", "broadway", "chess", "cl2emult", "ctex-article",
1269 "ctex-book", "ctex-report", "dinbrief", "docbook-book", "docbook-chapter",
1270 "docbook", "docbook-section", "doublecol-new", "dtk", "ectaart", "egs",
1271 "elsarticle", "elsart", "entcs", "europecv", "extarticle", "extbook",
1272 "extletter", "extreport", "foils", "frletter", "g-brief2", "g-brief",
1273 "heb-article", "heb-letter", "hollywood", "IEEEtran", "ijmpc", "ijmpd",
1274 "iopart", "isprs", "jarticle", "jasatex", "jbook", "jgrga", "jreport",
1275 "jsarticle", "jsbeamer", "jsbook", "jss", "kluwer", "latex8", "letter", "lettre",
1276 "literate-article", "literate-book", "literate-report", "llncs", "ltugboat",
1277 "memoir", "moderncv", "mwart", "mwbk", "mwrep", "paper", "powerdot",
1278 "recipebook", "report", "revtex4", "revtex", "scrartcl", "scrarticle-beamer",
1279 "scrbook", "scrlettr", "scrlttr2", "scrreprt", "seminar", "siamltex",
1280 "sigplanconf", "simplecv", "singlecol", "singlecol-new", "slides", "spie",
1281 "svglobal3", "svglobal", "svjog", "svmono", "svmult", "svprobth", "tarticle",
1282 "tbook", "treport", "tufte-book", "tufte-handout"]
1283 # A list of "safe" modules, same as above
1284 safe_modules = ["biblatex", "beameraddons", "beamersession", "braille", "customHeadersFooters",
1285 "endnotes", "enumitem", "eqs-within-sections", "figs-within-sections", "fix-cm",
1286 "fixltx2e", "foottoend", "hanging", "jscharstyles", "knitr", "lilypond",
1287 "linguistics", "linguisticx", "logicalmkup", "minimalistic", "nomindex", "noweb",
1288 "pdfcomment", "sweave", "tabs-within-sections", "theorems-ams-bytype",
1289 "theorems-ams-extended-bytype", "theorems-ams-extended", "theorems-ams", "theorems-bytype",
1290 "theorems-chap-bytype", "theorems-chap", "theorems-named", "theorems-sec-bytype",
1291 "theorems-sec", "theorems-starred", "theorems-std", "todonotes"]
1292 # Modules we need to take care of
1293 caveat_modules = ["initials"]
1294 # information about the relevant styles in caveat_modules (number of opt and req args)
1295 # use this if we get more caveat_modules. For now, use hard coding (see below).
1296 # initials = [{'Layout' : 'Initial', 'opt' : 1, 'req' : 1}]
1298 # Is this a known safe layout?
1299 safe_layout = document.textclass in safe_layouts
1301 document.warning("Lyx2lyx knows nothing about textclass '%s'. "
1302 "Please check if short title insets have been converted correctly."
1303 % document.textclass)
1304 # Do we use unsafe or unknown modules
1305 mods = document.get_module_list()
1306 unknown_modules = False
1307 used_caveat_modules = list()
1309 if mod in safe_modules:
1311 if mod in caveat_modules:
1312 used_caveat_modules.append(mod)
1314 unknown_modules = True
1315 document.warning("Lyx2lyx knows nothing about module '%s'. "
1316 "Please check if short title insets have been converted correctly."
1321 i = find_token(document.body, "\\begin_inset Argument", i)
1325 if not safe_layout or unknown_modules:
1326 # We cannot do more here since we have no access to this layout.
1327 # InsetArgument itself will do the real work
1328 # (see InsetArgument::updateBuffer())
1329 document.body[i] = "\\begin_inset Argument 999"
1333 # Find containing paragraph layout
1334 parent = get_containing_layout(document.body, i)
1336 document.warning("Malformed lyx document: Can't find parent paragraph layout")
1343 if len(used_caveat_modules) > 0:
1344 # We know for now that this must be the initials module with the Initial layout
1345 # If we get more such modules, we need some automating.
1346 if parent[0] == "Initial":
1347 # Layout has 1 opt and 1 req arg.
1348 # Count the actual arguments
1350 for p in range(parbeg, parend):
1351 if document.body[p] == "\\begin_inset Argument":
1356 # Collect all arguments in this paragraph
1358 for p in range(parbeg, parend):
1359 if document.body[p] == "\\begin_inset Argument":
1361 if allowed_opts != -1:
1362 # We have less arguments than opt + required.
1363 # required must take precedence.
1364 if argnr > allowed_opts and argnr < first_req:
1366 document.body[p] = "\\begin_inset Argument %d" % argnr
1370 def revert_latexargs(document):
1371 " Revert InsetArgument to old syntax "
1374 rx = re.compile(r'^\\begin_inset Argument (\d+)$')
1377 # Search for Argument insets
1378 i = find_token(document.body, "\\begin_inset Argument", i)
1381 m = rx.match(document.body[i])
1383 # No ID: inset already reverted
1386 # Find containing paragraph layout
1387 parent = get_containing_layout(document.body, i)
1389 document.warning("Malformed lyx document: Can't find parent paragraph layout")
1394 realparbeg = parent[3]
1395 # Collect all arguments in this paragraph
1397 for p in range(parbeg, parend):
1398 m = rx.match(document.body[p])
1400 val = int(m.group(1))
1401 j = find_end_of_inset(document.body, p)
1402 # Revert to old syntax
1403 document.body[p] = "\\begin_inset Argument"
1405 document.warning("Malformed lyx document: Can't find end of Argument inset")
1408 args[val] = document.body[p : j + 1]
1410 realparend = realparend - len(document.body[p : j + 1])
1411 # Remove arg inset at this position
1412 del document.body[p : j + 1]
1415 # Now sort the arg insets
1417 for f in sorted(args):
1420 # Insert the sorted arg insets at paragraph begin
1421 document.body[realparbeg : realparbeg] = subst
1423 i = realparbeg + 1 + len(subst)
1426 def revert_Argument_to_TeX_brace(document, line, endline, n, nmax, environment, opt):
1428 Reverts an InsetArgument to TeX-code
1430 revert_Argument_to_TeX_brace(document, LineOfBegin, LineOfEnd, StartArgument, EndArgument, isEnvironment, isOpt)
1431 LineOfBegin is the line of the \begin_layout or \begin_inset statement
1432 LineOfEnd is the line of the \end_layout or \end_inset statement, if "0" is given, the end of the file is used instead
1433 StartArgument is the number of the first argument that needs to be converted
1434 EndArgument is the number of the last argument that needs to be converted or the last defined one
1435 isEnvironment must be true, if the layout is for a LaTeX environment
1436 isOpt must be true, if the argument is an optional one
1440 while lineArg != -1 and n < nmax + 1:
1441 lineArg = find_token(document.body, "\\begin_inset Argument " + str(n), line)
1442 if lineArg > endline and endline != 0:
1445 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", lineArg)
1446 # we have to assure that no other inset is in the Argument
1447 beginInset = find_token(document.body, "\\begin_inset", beginPlain)
1448 endInset = find_token(document.body, "\\end_inset", beginPlain)
1451 while beginInset < endInset and beginInset != -1:
1452 beginInset = find_token(document.body, "\\begin_inset", k)
1453 endInset = find_token(document.body, "\\end_inset", l)
1456 if environment == False:
1458 document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("}{")
1459 del(document.body[lineArg : beginPlain + 1])
1462 document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("]")
1463 document.body[lineArg : beginPlain + 1] = put_cmd_in_ert("[")
1466 document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("}")
1467 document.body[lineArg : beginPlain + 1] = put_cmd_in_ert("{")
1473 def convert_TeX_brace_to_Argument(document, line, n, nmax, inset, environment):
1475 Converts TeX code for mandatory arguments to an InsetArgument
1476 The conversion of TeX code for optional arguments must be done with another routine
1477 !!! Be careful if the braces are different in your case as expected here:
1478 - "}{" separates mandatory arguments of commands
1479 - "}" + "{" separates mandatory arguments of commands
1480 - "}" + " " + "{" separates mandatory arguments of commands
1481 - { and } surround a mandatory argument of an environment
1483 convert_TeX_brace_to_Argument(document, LineOfBeginLayout/Inset, StartArgument, EndArgument, isInset, isEnvironment)
1484 LineOfBeginLayout/Inset is the line of the \begin_layout or \begin_inset statement
1485 StartArgument is the number of the first ERT that needs to be converted
1486 EndArgument is the number of the last ERT that needs to be converted
1487 isInset must be true, if braces inside an InsetLayout needs to be converted
1488 isEnvironment must be true, if the layout is for a LaTeX environment
1490 Todo: this routine can currently handle only one mandatory argument of environments
1495 while lineERT != -1 and n < nmax + 1:
1496 lineERT = find_token(document.body, "\\begin_inset ERT", lineERT)
1497 if environment == False and lineERT != -1:
1498 bracePair = find_token(document.body, "}{", lineERT)
1499 # assure that the "}{" is in this ERT
1500 if bracePair == lineERT + 5:
1501 end = find_token(document.body, "\\end_inset", bracePair)
1502 document.body[lineERT : end + 1] = ["\\end_layout", "", "\\end_inset"]
1504 # in the case that n > 1 we have optional arguments before
1505 # therefore detect them if any
1507 # first check if there is an argument
1508 lineArg = find_token(document.body, "\\begin_inset Argument", line)
1509 if lineArg < lineERT and lineArg != -1:
1510 # we have an argument, so now search backwards for its end
1511 # we must now assure that we don't find other insets like e.g. a newline
1512 endInsetArg = lineERT
1513 endLayoutArg = endInsetArg
1514 while endInsetArg != endLayoutArg + 2 and endInsetArg != -1:
1515 endInsetArg = endInsetArg - 1
1516 endLayoutArg = endInsetArg
1517 endInsetArg = find_token_backwards(document.body, "\\end_inset", endInsetArg)
1518 endLayoutArg = find_token_backwards(document.body, "\\end_layout", endLayoutArg)
1519 line = endInsetArg + 1
1521 document.body[line + 1 : line + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1523 document.body[line + 4 : line + 4] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1525 document.body[endn : endn] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1529 # now check the case that we have "}" + "{" in two ERTs
1531 endBrace = find_token(document.body, "}", lineERT)
1532 if endBrace == lineERT + 5:
1533 beginBrace = find_token(document.body, "{", endBrace)
1534 # assure that the ERTs are consecutive (11 or 12 depending if there is a space between the ERTs or not)
1535 if beginBrace == endBrace + 11 or beginBrace == endBrace + 12:
1536 end = find_token(document.body, "\\end_inset", beginBrace)
1537 document.body[lineERT : end + 1] = ["\\end_layout", "", "\\end_inset"]
1539 # in the case that n > 1 we have optional arguments before
1540 # therefore detect them if any
1542 # first check if there is an argument
1543 lineArg = find_token(document.body, "\\begin_inset Argument", line)
1544 if lineArg < lineERT and lineArg != -1:
1545 # we have an argument, so now search backwards for its end
1546 # we must now assure that we don't find other insets like e.g. a newline
1547 endInsetArg = lineERT
1548 endLayoutArg = endInsetArg
1549 while endInsetArg != endLayoutArg + 2 and endInsetArg != -1:
1550 endInsetArg = endInsetArg - 1
1551 endLayoutArg = endInsetArg
1552 endInsetArg = find_token_backwards(document.body, "\\end_inset", endInsetArg)
1553 endLayoutArg = find_token_backwards(document.body, "\\end_layout", endLayoutArg)
1554 line = endInsetArg + 1
1556 document.body[line + 1 : line + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1558 document.body[line + 4 : line + 4] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1560 document.body[endn : endn] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1563 # set the line where the next argument will be inserted
1564 if beginBrace == endBrace + 11:
1569 lineERT = lineERT + 1
1570 if environment == True and lineERT != -1:
1571 opening = find_token(document.body, "{", lineERT)
1572 if opening == lineERT + 5: # assure that the "{" is in this ERT
1573 end = find_token(document.body, "\\end_inset", opening)
1574 document.body[lineERT : end + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1576 lineERT2 = find_token(document.body, "\\begin_inset ERT", lineERT)
1577 closing = find_token(document.body, "}", lineERT2)
1578 if closing == lineERT2 + 5: # assure that the "}" is in this ERT
1579 end2 = find_token(document.body, "\\end_inset", closing)
1580 document.body[lineERT2 : end2 + 1] = ["\\end_layout", "", "\\end_inset"]
1582 lineERT = lineERT + 1
1585 def revert_IEEEtran(document):
1587 Reverts InsetArgument of
1590 Biography without photo
1593 if document.textclass == "IEEEtran":
1600 i = find_token(document.body, "\\begin_layout Page headings", i)
1602 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1605 i2 = find_token(document.body, "\\begin_inset Flex Paragraph Start", i2)
1607 revert_Argument_to_TeX_brace(document, i2, 0, 1, 1, False, False)
1610 j = find_token(document.body, "\\begin_layout Biography without photo", j)
1612 revert_Argument_to_TeX_brace(document, j, 0, 1, 1, True, False)
1615 k = find_token(document.body, "\\begin_layout Biography", k)
1616 kA = find_token(document.body, "\\begin_layout Biography without photo", k)
1617 if k == kA and k != -1:
1621 # start with the second argument, therefore 2
1622 revert_Argument_to_TeX_brace(document, k, 0, 2, 2, True, False)
1624 if i == -1 and i2 == -1 and j == -1 and k == -1:
1628 def revert_IEEEtran_2(document):
1630 Reverts Flex Paragraph Start to TeX-code
1632 if document.textclass == "IEEEtran":
1636 begin = find_token(document.body, "\\begin_inset Flex Paragraph Start", begin)
1638 end1 = find_end_of_inset(document.body, begin)
1639 document.body[end1 - 2 : end1 + 1] = put_cmd_in_ert("}")
1640 document.body[begin : begin + 4] = put_cmd_in_ert("\\IEEEPARstart{")
1646 def convert_IEEEtran(document):
1651 Biography without photo
1654 if document.textclass == "IEEEtran":
1660 i = find_token(document.body, "\\begin_layout Page headings", i)
1662 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1665 j = find_token(document.body, "\\begin_layout Biography without photo", j)
1667 convert_TeX_brace_to_Argument(document, j, 1, 1, False, True)
1670 # assure that we don't handle Biography Biography without photo
1671 k = find_token(document.body, "\\begin_layout Biography", k)
1672 kA = find_token(document.body, "\\begin_layout Biography without photo", k - 1)
1673 if k == kA and k != -1:
1677 # the argument we want to convert is the second one
1678 convert_TeX_brace_to_Argument(document, k, 2, 2, False, True)
1680 if i == -1 and j == -1 and k == -1:
1684 def revert_AASTeX(document):
1685 " Reverts InsetArgument of Altaffilation to TeX-code "
1686 if document.textclass == "aastex":
1690 i = find_token(document.body, "\\begin_layout Altaffilation", i)
1692 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1698 def convert_AASTeX(document):
1699 " Converts ERT of Altaffilation to InsetArgument "
1700 if document.textclass == "aastex":
1704 i = find_token(document.body, "\\begin_layout Altaffilation", i)
1706 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1712 def revert_AGUTeX(document):
1713 " Reverts InsetArgument of Author affiliation to TeX-code "
1714 if document.textclass == "agutex":
1718 i = find_token(document.body, "\\begin_layout Author affiliation", i)
1720 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1726 def convert_AGUTeX(document):
1727 " Converts ERT of Author affiliation to InsetArgument "
1728 if document.textclass == "agutex":
1732 i = find_token(document.body, "\\begin_layout Author affiliation", i)
1734 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1740 def revert_IJMP(document):
1741 " Reverts InsetArgument of MarkBoth to TeX-code "
1742 if document.textclass == "ijmpc" or document.textclass == "ijmpd":
1746 i = find_token(document.body, "\\begin_layout MarkBoth", i)
1748 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1754 def convert_IJMP(document):
1755 " Converts ERT of MarkBoth to InsetArgument "
1756 if document.textclass == "ijmpc" or document.textclass == "ijmpd":
1760 i = find_token(document.body, "\\begin_layout MarkBoth", i)
1762 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1768 def revert_SIGPLAN(document):
1769 " Reverts InsetArguments of SIGPLAN to TeX-code "
1770 if document.textclass == "sigplanconf":
1775 i = find_token(document.body, "\\begin_layout Conference", i)
1777 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1780 j = find_token(document.body, "\\begin_layout Author", j)
1782 revert_Argument_to_TeX_brace(document, j, 0, 1, 2, False, False)
1784 if i == -1 and j == -1:
1788 def convert_SIGPLAN(document):
1789 " Converts ERT of SIGPLAN to InsetArgument "
1790 if document.textclass == "sigplanconf":
1795 i = find_token(document.body, "\\begin_layout Conference", i)
1797 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1800 j = find_token(document.body, "\\begin_layout Author", j)
1802 convert_TeX_brace_to_Argument(document, j, 1, 2, False, False)
1804 if i == -1 and j == -1:
1808 def revert_SIGGRAPH(document):
1809 " Reverts InsetArgument of Flex CRcat to TeX-code "
1810 if document.textclass == "acmsiggraph":
1814 i = find_token(document.body, "\\begin_inset Flex CRcat", i)
1816 revert_Argument_to_TeX_brace(document, i, 0, 1, 3, False, False)
1822 def convert_SIGGRAPH(document):
1823 " Converts ERT of Flex CRcat to InsetArgument "
1824 if document.textclass == "acmsiggraph":
1828 i = find_token(document.body, "\\begin_inset Flex CRcat", i)
1830 convert_TeX_brace_to_Argument(document, i, 1, 3, True, False)
1836 def revert_EuropeCV(document):
1837 " Reverts InsetArguments of europeCV to TeX-code "
1838 if document.textclass == "europecv":
1845 i = find_token(document.body, "\\begin_layout Item", i)
1847 revert_Argument_to_TeX_brace(document, i, 0, 2, 2, False, False)
1850 j = find_token(document.body, "\\begin_layout BulletedItem", j)
1852 revert_Argument_to_TeX_brace(document, j, 0, 2, 2, False, False)
1855 k = find_token(document.body, "\\begin_layout Language", k)
1857 revert_Argument_to_TeX_brace(document, k, 0, 2, 6, False, False)
1860 m = find_token(document.body, "\\begin_layout LastLanguage", m)
1862 revert_Argument_to_TeX_brace(document, m, 0, 2, 6, False, False)
1864 if i == -1 and j == -1 and k == -1 and m == -1:
1868 def convert_EuropeCV(document):
1869 " Converts ERT of europeCV to InsetArgument "
1870 if document.textclass == "europecv":
1877 i = find_token(document.body, "\\begin_layout Item", i)
1879 convert_TeX_brace_to_Argument(document, i, 2, 2, False, False)
1882 j = find_token(document.body, "\\begin_layout BulletedItem", j)
1884 convert_TeX_brace_to_Argument(document, j, 2, 2, False, False)
1887 k = find_token(document.body, "\\begin_layout Language", k)
1889 convert_TeX_brace_to_Argument(document, k, 2, 6, False, False)
1892 m = find_token(document.body, "\\begin_layout LastLanguage", m)
1894 convert_TeX_brace_to_Argument(document, m, 2, 6, False, False)
1896 if i == -1 and j == -1 and k == -1 and m == -1:
1900 def revert_ModernCV(document):
1901 " Reverts InsetArguments of modernCV to TeX-code "
1902 if document.textclass == "moderncv":
1909 j = find_token(document.body, "\\begin_layout Entry", j)
1911 revert_Argument_to_TeX_brace(document, j, 0, 1, 5, False, False)
1914 k = find_token(document.body, "\\begin_layout Item", k)
1916 revert_Argument_to_TeX_brace(document, k, 0, 1, 1, False, False)
1919 m = find_token(document.body, "\\begin_layout ItemWithComment", m)
1921 revert_Argument_to_TeX_brace(document, m, 0, 1, 2, False, False)
1922 document.body[m] = document.body[m].replace("\\begin_layout ItemWithComment", "\\begin_layout Language")
1925 o = find_token(document.body, "\\begin_layout DoubleItem", o)
1927 revert_Argument_to_TeX_brace(document, o, 0, 1, 3, False, False)
1928 document.body[o] = document.body[o].replace("\\begin_layout DoubleItem", "\\begin_layout Computer")
1930 if j == -1 and k == -1 and m == -1 and o == -1:
1934 def revert_ModernCV_2(document):
1935 " Reverts the Flex:Column inset of modernCV to TeX-code "
1936 if document.textclass == "moderncv":
1941 flex = find_token(document.body, "\\begin_inset Flex Column", flex)
1943 flexEnd = find_end_of_inset(document.body, flex)
1944 wasOpt = revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, False, True)
1945 revert_Argument_to_TeX_brace(document, flex, 0, 2, 2, False, False)
1946 flexEnd = find_end_of_inset(document.body, flex)
1948 document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\cvcolumn")
1950 document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\cvcolumn{")
1951 document.body[flexEnd + 4 : flexEnd + 7] = put_cmd_in_ert("}")
1957 def revert_ModernCV_3(document):
1958 " Reverts the Column style of modernCV to TeX-code "
1959 if document.textclass == "moderncv":
1960 # revert the layouts
1961 revert_ModernCV(document)
1963 # get the position of the end of the last column inset
1964 LastFlexEnd = revert_ModernCV_2(document)
1967 p = find_token(document.body, "\\begin_layout Columns", p)
1969 pEnd = find_end_of_layout(document.body, p)
1970 document.body[p] = document.body[p].replace("\\begin_layout Columns", "\\begin_layout Standard")
1971 if LastFlexEnd != -1:
1972 document.body[p + 1 : p + 1] = put_cmd_in_ert("\\begin{cvcolumns}")
1973 document.body[LastFlexEnd + 24 : LastFlexEnd + 24] = put_cmd_in_ert("\\end{cvcolumns}")
1979 def convert_ModernCV(document):
1980 " Converts ERT of modernCV to InsetArgument "
1981 if document.textclass == "moderncv":
1989 i = find_token(document.body, "\\begin_layout DoubleItem", i)
1991 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1992 document.body[o] = document.body[o].replace("\\begin_layout DoubleItem", "\\begin_layout DoubleListItem")
1995 j = find_token(document.body, "\\begin_layout Entry", j)
1997 convert_TeX_brace_to_Argument(document, j, 1, 5, False, False)
2000 k = find_token(document.body, "\\begin_layout Item", k)
2002 convert_TeX_brace_to_Argument(document, k, 1, 1, False, False)
2005 m = find_token(document.body, "\\begin_layout Language", m)
2007 convert_TeX_brace_to_Argument(document, m, 1, 2, False, False)
2009 if i == -1 and j == -1 and k == -1 and m == -1:
2013 def revert_Initials(document):
2014 " Reverts InsetArgument of Initial to TeX-code "
2018 i = find_token(document.body, "\\begin_layout Initial", i)
2020 # first arg (optional) and second arg (first mandatory) are supported in LyX 2.0.x
2021 revert_Argument_to_TeX_brace(document, i, 0, 3, 3, False, False)
2027 def convert_Initials(document):
2028 " Converts ERT of Initial to InsetArgument "
2032 i = find_token(document.body, "\\begin_layout Initial", i)
2034 convert_TeX_brace_to_Argument(document, i, 3, 3, False, False)
2040 def revert_literate(document):
2041 " Revert Literate document to old format "
2042 if del_token(document.header, "noweb", 0):
2043 document.textclass = "literate-" + document.textclass
2046 i = find_token(document.body, "\\begin_layout Chunk", i)
2049 document.body[i] = "\\begin_layout Scrap"
2053 def convert_literate(document):
2054 " Convert Literate document to new format"
2055 i = find_token(document.header, "\\textclass", 0)
2056 if (i != -1) and "literate-" in document.header[i]:
2057 document.textclass = document.header[i].replace("\\textclass literate-", "")
2058 j = find_token(document.header, "\\begin_modules", 0)
2060 document.header.insert(j + 1, "noweb")
2062 document.header.insert(i + 1, "\\end_modules")
2063 document.header.insert(i + 1, "noweb")
2064 document.header.insert(i + 1, "\\begin_modules")
2067 i = find_token(document.body, "\\begin_layout Scrap", i)
2070 document.body[i] = "\\begin_layout Chunk"
2074 def revert_itemargs(document):
2075 " Reverts \\item arguments to TeX-code "
2078 i = find_token(document.body, "\\begin_inset Argument item:", i)
2081 j = find_end_of_inset(document.body, i)
2082 # Find containing paragraph layout
2083 parent = get_containing_layout(document.body, i)
2085 document.warning("Malformed lyx document: Can't find parent paragraph layout")
2089 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2090 endPlain = find_end_of_layout(document.body, beginPlain)
2091 content = document.body[beginPlain + 1 : endPlain]
2092 del document.body[i:j+1]
2093 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2094 document.body[parbeg : parbeg] = subst
2098 def revert_garamondx_newtxmath(document):
2099 " Revert native garamond newtxmath definition to LaTeX "
2101 i = find_token(document.header, "\\font_math", 0)
2104 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
2105 val = get_value(document.header, "\\font_math", i)
2106 if val == "garamondx-ntxm":
2107 add_to_preamble(document, "\\usepackage[garamondx]{newtxmath}")
2108 document.header[i] = "\\font_math auto"
2111 def revert_garamondx(document):
2112 " Revert native garamond font definition to LaTeX "
2114 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
2115 i = find_token(document.header, "\\font_roman garamondx", 0)
2118 j = find_token(document.header, "\\font_osf true", 0)
2121 preamble = "\\usepackage"
2123 preamble += "[osfI]"
2124 preamble += "{garamondx}"
2125 add_to_preamble(document, [preamble])
2126 document.header[i] = "\\font_roman default"
2129 def convert_beamerargs(document):
2130 " Converts beamer arguments to new layout "
2132 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2133 if document.textclass not in beamer_classes:
2136 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
2137 list_layouts = ["Itemize", "Enumerate", "Description"]
2138 rx = re.compile(r'^\\begin_inset Argument (\d+)$')
2142 i = find_token(document.body, "\\begin_inset Argument", i)
2145 # Find containing paragraph layout
2146 parent = get_containing_layout(document.body, i)
2148 document.warning("Malformed lyx document: Can't find parent paragraph layout")
2153 layoutname = parent[0]
2154 for p in range(parbeg, parend):
2155 if layoutname in shifted_layouts:
2156 m = rx.match(document.body[p])
2158 argnr = int(m.group(1))
2160 document.body[p] = "\\begin_inset Argument %d" % argnr
2161 if layoutname == "AgainFrame":
2162 m = rx.match(document.body[p])
2164 document.body[p] = "\\begin_inset Argument 3"
2165 if document.body[p + 4] == "\\begin_inset ERT":
2166 if document.body[p + 9].startswith("<"):
2167 # This is an overlay specification
2169 document.body[p + 9] = document.body[p + 9][1:]
2170 if document.body[p + 9].endswith(">"):
2172 document.body[p + 9] = document.body[p + 9][:-1]
2174 document.body[p] = "\\begin_inset Argument 2"
2175 if layoutname in list_layouts:
2176 m = rx.match(document.body[p])
2178 if m.group(1) == "1":
2179 if document.body[p + 4] == "\\begin_inset ERT":
2180 if document.body[p + 9].startswith("<"):
2181 # This is an overlay specification
2183 document.body[p + 9] = document.body[p + 9][1:]
2184 if document.body[p + 9].endswith(">"):
2186 document.body[p + 9] = document.body[p + 9][:-1]
2187 elif layoutname != "Itemize":
2189 document.body[p] = "\\begin_inset Argument 2"
2193 def convert_againframe_args(document):
2194 " Converts beamer AgainFrame to new layout "
2196 # FIXME: This currently only works if the arguments are in one single ERT
2198 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2199 if document.textclass not in beamer_classes:
2204 i = find_token(document.body, "\\begin_layout AgainFrame", i)
2207 parent = get_containing_layout(document.body, i)
2209 document.warning("Wrong parent layout!")
2213 if document.body[parbeg] == "\\begin_inset ERT":
2214 ertcont = parbeg + 5
2215 if document.body[ertcont].startswith("[<"):
2216 # This is a default overlay specification
2218 document.body[ertcont] = document.body[ertcont][2:]
2219 if document.body[ertcont].endswith(">]"):
2221 document.body[ertcont] = document.body[ertcont][:-2]
2222 elif document.body[ertcont].endswith("]"):
2224 tok = document.body[ertcont].find('>][')
2226 subst = [document.body[ertcont][:tok],
2227 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2228 'status collapsed', '', '\\begin_layout Plain Layout',
2229 document.body[ertcont][tok + 3:-1]]
2230 document.body[ertcont : ertcont + 1] = subst
2231 # Convert to ArgInset
2232 document.body[parbeg] = "\\begin_inset Argument 2"
2235 elif document.body[ertcont].startswith("<"):
2236 # This is an overlay specification
2238 document.body[ertcont] = document.body[ertcont][1:]
2239 if document.body[ertcont].endswith(">"):
2241 document.body[ertcont] = document.body[ertcont][:-1]
2242 # Convert to ArgInset
2243 document.body[parbeg] = "\\begin_inset Argument 1"
2244 elif document.body[ertcont].endswith(">]"):
2246 tok = document.body[ertcont].find('>[<')
2248 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2249 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2250 'status collapsed', '', '\\begin_layout Plain Layout',
2251 document.body[ertcont][tok + 3:-2]]
2252 # Convert to ArgInset
2253 document.body[parbeg] = "\\begin_inset Argument 1"
2254 elif document.body[ertcont].endswith("]"):
2256 tok = document.body[ertcont].find('>[<')
2259 tokk = document.body[ertcont].find('>][')
2261 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2262 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2263 'status collapsed', '', '\\begin_layout Plain Layout',
2264 document.body[ertcont][tok + 3:tokk],
2265 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2266 'status collapsed', '', '\\begin_layout Plain Layout',
2267 document.body[ertcont][tokk + 3:-1]]
2269 tokk = document.body[ertcont].find('>[')
2271 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tokk],
2272 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2273 'status collapsed', '', '\\begin_layout Plain Layout',
2274 document.body[ertcont][tokk + 2:-1]]
2275 # Convert to ArgInset
2276 document.body[parbeg] = "\\begin_inset Argument 1"
2279 elif document.body[ertcont].startswith("["):
2280 # This is an ERT option
2282 document.body[ertcont] = document.body[ertcont][1:]
2283 if document.body[ertcont].endswith("]"):
2285 document.body[ertcont] = document.body[ertcont][:-1]
2286 # Convert to ArgInset
2287 document.body[parbeg] = "\\begin_inset Argument 3"
2293 def convert_corollary_args(document):
2294 " Converts beamer corrolary-style ERT arguments native InsetArgs "
2296 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2297 if document.textclass not in beamer_classes:
2300 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2301 for lay in corollary_layouts:
2304 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2307 parent = get_containing_layout(document.body, i)
2309 document.warning("Wrong parent layout!")
2313 if document.body[parbeg] == "\\begin_inset ERT":
2314 ertcont = parbeg + 5
2315 if document.body[ertcont].startswith("<"):
2316 # This is an overlay specification
2318 document.body[ertcont] = document.body[ertcont][1:]
2319 if document.body[ertcont].endswith(">"):
2321 document.body[ertcont] = document.body[ertcont][:-1]
2322 elif document.body[ertcont].endswith("]"):
2324 tok = document.body[ertcont].find('>[')
2326 subst = [document.body[ertcont][:tok],
2327 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2328 'status collapsed', '', '\\begin_layout Plain Layout',
2329 document.body[ertcont][tok + 2:-1]]
2330 document.body[ertcont : ertcont + 1] = subst
2331 # Convert to ArgInset
2332 document.body[parbeg] = "\\begin_inset Argument 1"
2335 elif document.body[ertcont].startswith("["):
2336 # This is an ERT option
2338 document.body[ertcont] = document.body[ertcont][1:]
2339 if document.body[ertcont].endswith("]"):
2341 document.body[ertcont] = document.body[ertcont][:-1]
2342 # Convert to ArgInset
2343 document.body[parbeg] = "\\begin_inset Argument 2"
2350 def convert_quote_args(document):
2351 " Converts beamer quote style ERT args to native InsetArgs "
2353 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2354 if document.textclass not in beamer_classes:
2357 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2358 for lay in quote_layouts:
2361 i = find_token(document.body, "\\begin_layout " + lay, i)
2364 parent = get_containing_layout(document.body, i)
2366 document.warning("Wrong parent layout!")
2370 if document.body[parbeg] == "\\begin_inset ERT":
2371 if document.body[i + 6].startswith("<"):
2372 # This is an overlay specification
2374 document.body[i + 6] = document.body[i + 6][1:]
2375 if document.body[i + 6].endswith(">"):
2377 document.body[i + 6] = document.body[i + 6][:-1]
2378 # Convert to ArgInset
2379 document.body[i + 1] = "\\begin_inset Argument 1"
2383 def revert_beamerargs(document):
2384 " Reverts beamer arguments to old layout "
2386 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2387 if document.textclass not in beamer_classes:
2391 list_layouts = ["Itemize", "Enumerate", "Description"]
2392 headings = ["Part", "Section", "Section*", "Subsection", "Subsection*",
2393 "Subsubsection", "Subsubsection*", "FrameSubtitle", "NoteItem"]
2394 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2395 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2396 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2399 i = find_token(document.body, "\\begin_inset Argument", i)
2402 # Find containing paragraph layout
2403 parent = get_containing_layout(document.body, i)
2405 document.warning("Malformed lyx document: Can't find parent paragraph layout")
2410 realparbeg = parent[3]
2411 layoutname = parent[0]
2413 for p in range(parbeg, parend):
2417 if layoutname in headings:
2418 m = rx.match(document.body[p])
2422 # Find containing paragraph layout
2423 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2424 endPlain = find_end_of_layout(document.body, beginPlain)
2425 endInset = find_end_of_inset(document.body, p)
2426 argcontent = document.body[beginPlain + 1 : endPlain]
2428 realparend = realparend - len(document.body[p : endInset + 1])
2430 del document.body[p : endInset + 1]
2431 if layoutname == "FrameSubtitle":
2432 pre = put_cmd_in_ert("\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2433 elif layoutname == "NoteItem":
2434 pre = put_cmd_in_ert("\\note<") + argcontent + put_cmd_in_ert(">[item]")
2435 elif layoutname.endswith('*'):
2436 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower()[:-1] + "<") + argcontent + put_cmd_in_ert(">*")
2438 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2439 secarg = find_token(document.body, "\\begin_inset Argument 2", parbeg, parend)
2441 # Find containing paragraph layout
2442 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", secarg)
2443 endPlain = find_end_of_layout(document.body, beginPlain)
2444 endInset = find_end_of_inset(document.body, secarg)
2445 argcontent = document.body[beginPlain + 1 : endPlain]
2447 realparend = realparend - len(document.body[secarg : endInset + 1])
2448 del document.body[secarg : endInset + 1]
2449 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2450 pre += put_cmd_in_ert("{")
2451 document.body[parbeg] = "\\begin_layout Standard"
2452 document.body[realparbeg : realparbeg] = pre
2453 pe = find_end_of_layout(document.body, parbeg)
2454 post = put_cmd_in_ert("}")
2455 document.body[pe : pe] = post
2456 realparend += len(pre) + len(post)
2457 if layoutname == "AgainFrame":
2458 m = rx.match(document.body[p])
2462 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2463 endPlain = find_end_of_layout(document.body, beginPlain)
2464 endInset = find_end_of_inset(document.body, p)
2465 content = document.body[beginPlain + 1 : endPlain]
2467 realparend = realparend - len(document.body[p : endInset + 1])
2469 del document.body[p : endInset + 1]
2470 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2471 document.body[realparbeg : realparbeg] = subst
2472 if layoutname == "Overprint":
2473 m = rx.match(document.body[p])
2477 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2478 endPlain = find_end_of_layout(document.body, beginPlain)
2479 endInset = find_end_of_inset(document.body, p)
2480 content = document.body[beginPlain + 1 : endPlain]
2482 realparend = realparend - len(document.body[p : endInset + 1])
2484 del document.body[p : endInset + 1]
2485 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2486 document.body[realparbeg : realparbeg] = subst
2487 if layoutname == "OverlayArea":
2488 m = rx.match(document.body[p])
2492 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2493 endPlain = find_end_of_layout(document.body, beginPlain)
2494 endInset = find_end_of_inset(document.body, p)
2495 content = document.body[beginPlain + 1 : endPlain]
2497 realparend = realparend - len(document.body[p : endInset + 1])
2499 del document.body[p : endInset + 1]
2500 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2501 document.body[realparbeg : realparbeg] = subst
2502 if layoutname in list_layouts:
2503 m = rx.match(document.body[p])
2507 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2508 endPlain = find_end_of_layout(document.body, beginPlain)
2509 endInset = find_end_of_inset(document.body, p)
2510 content = document.body[beginPlain + 1 : endPlain]
2511 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2512 realparend = realparend + len(subst) - len(content)
2513 document.body[beginPlain + 1 : endPlain] = subst
2514 elif argnr == "item:1":
2515 j = find_end_of_inset(document.body, i)
2516 # Find containing paragraph layout
2517 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2518 endPlain = find_end_of_layout(document.body, beginPlain)
2519 content = document.body[beginPlain + 1 : endPlain]
2520 del document.body[i:j+1]
2521 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2522 document.body[realparbeg : realparbeg] = subst
2523 elif argnr == "item:2":
2524 j = find_end_of_inset(document.body, i)
2525 # Find containing paragraph layout
2526 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2527 endPlain = find_end_of_layout(document.body, beginPlain)
2528 content = document.body[beginPlain + 1 : endPlain]
2529 del document.body[i:j+1]
2530 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2531 document.body[realparbeg : realparbeg] = subst
2532 if layoutname in quote_layouts:
2533 m = rx.match(document.body[p])
2537 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2538 endPlain = find_end_of_layout(document.body, beginPlain)
2539 endInset = find_end_of_inset(document.body, p)
2540 content = document.body[beginPlain + 1 : endPlain]
2542 realparend = realparend - len(document.body[p : endInset + 1])
2544 del document.body[p : endInset + 1]
2545 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2546 document.body[realparbeg : realparbeg] = subst
2547 if layoutname in corollary_layouts:
2548 m = rx.match(document.body[p])
2552 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2553 endPlain = find_end_of_layout(document.body, beginPlain)
2554 endInset = find_end_of_inset(document.body, p)
2555 content = document.body[beginPlain + 1 : endPlain]
2557 realparend = realparend - len(document.body[p : endInset + 1])
2559 del document.body[p : endInset + 1]
2560 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2561 document.body[realparbeg : realparbeg] = subst
2566 def revert_beamerargs2(document):
2567 " Reverts beamer arguments to old layout, step 2 "
2569 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2570 if document.textclass not in beamer_classes:
2574 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
2575 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2576 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2579 i = find_token(document.body, "\\begin_inset Argument", i)
2582 # Find containing paragraph layout
2583 parent = get_containing_layout(document.body, i)
2585 document.warning("Malformed lyx document: Can't find parent paragraph layout")
2590 realparbeg = parent[3]
2591 layoutname = parent[0]
2593 for p in range(parbeg, parend):
2597 if layoutname in shifted_layouts:
2598 m = rx.match(document.body[p])
2602 document.body[p] = "\\begin_inset Argument 1"
2603 if layoutname in corollary_layouts:
2604 m = rx.match(document.body[p])
2608 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2609 endPlain = find_end_of_layout(document.body, beginPlain)
2610 endInset = find_end_of_inset(document.body, p)
2611 content = document.body[beginPlain + 1 : endPlain]
2613 realparend = realparend - len(document.body[p : endInset + 1])
2615 del document.body[p : endInset + 1]
2616 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2617 document.body[realparbeg : realparbeg] = subst
2618 if layoutname == "OverlayArea":
2619 m = rx.match(document.body[p])
2623 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2624 endPlain = find_end_of_layout(document.body, beginPlain)
2625 endInset = find_end_of_inset(document.body, p)
2626 content = document.body[beginPlain + 1 : endPlain]
2628 realparend = realparend - len(document.body[p : endInset + 1])
2630 del document.body[p : endInset + 1]
2631 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2632 document.body[realparbeg : realparbeg] = subst
2633 if layoutname == "AgainFrame":
2634 m = rx.match(document.body[p])
2638 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2639 endPlain = find_end_of_layout(document.body, beginPlain)
2640 endInset = find_end_of_inset(document.body, p)
2641 content = document.body[beginPlain + 1 : endPlain]
2643 realparend = realparend - len(document.body[p : endInset + 1])
2645 del document.body[p : endInset + 1]
2646 subst = put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
2647 document.body[realparbeg : realparbeg] = subst
2651 def revert_beamerargs3(document):
2652 " Reverts beamer arguments to old layout, step 3 "
2654 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2655 if document.textclass not in beamer_classes:
2658 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2661 i = find_token(document.body, "\\begin_inset Argument", i)
2664 # Find containing paragraph layout
2665 parent = get_containing_layout(document.body, i)
2667 document.warning("Malformed lyx document: Can't find parent paragraph layout")
2672 realparbeg = parent[3]
2673 layoutname = parent[0]
2675 for p in range(parbeg, parend):
2679 if layoutname == "AgainFrame":
2680 m = rx.match(document.body[p])
2684 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2685 endPlain = find_end_of_layout(document.body, beginPlain)
2686 endInset = find_end_of_inset(document.body, p)
2687 content = document.body[beginPlain + 1 : endPlain]
2689 realparend = realparend - len(document.body[p : endInset + 1])
2691 del document.body[p : endInset + 1]
2692 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2693 document.body[realparbeg : realparbeg] = subst
2697 def revert_beamerflex(document):
2698 " Reverts beamer Flex insets "
2700 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2701 if document.textclass not in beamer_classes:
2704 new_flexes = {"Bold" : "\\textbf", "Emphasize" : "\\emph", "Only" : "\\only",
2705 "Uncover" : "\\uncover", "Visible" : "\\visible",
2706 "Invisible" : "\\invisible", "Alternative" : "\\alt",
2707 "Beamer_Note" : "\\note"}
2708 old_flexes = {"Alert" : "\\alert", "Structure" : "\\structure"}
2709 rx = re.compile(r'^\\begin_inset Flex (.+)$')
2713 i = find_token(document.body, "\\begin_inset Flex", i)
2716 m = rx.match(document.body[i])
2718 flextype = m.group(1)
2719 z = find_end_of_inset(document.body, i)
2721 document.warning("Can't find end of Flex " + flextype + " inset.")
2724 if flextype in new_flexes:
2725 pre = put_cmd_in_ert(new_flexes[flextype])
2726 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2728 argend = find_end_of_inset(document.body, arg)
2730 document.warning("Can't find end of Argument!")
2733 # Find containing paragraph layout
2734 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2735 endPlain = find_end_of_layout(document.body, beginPlain)
2736 argcontent = document.body[beginPlain + 1 : endPlain]
2738 z = z - len(document.body[arg : argend + 1])
2740 del document.body[arg : argend + 1]
2741 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2742 arg = find_token(document.body, "\\begin_inset Argument 2", i, z)
2744 argend = find_end_of_inset(document.body, arg)
2746 document.warning("Can't find end of Argument!")
2749 # Find containing paragraph layout
2750 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2751 endPlain = find_end_of_layout(document.body, beginPlain)
2752 argcontent = document.body[beginPlain + 1 : endPlain]
2754 z = z - len(document.body[arg : argend + 1])
2756 del document.body[arg : argend + 1]
2757 if flextype == "Alternative":
2758 pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
2760 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2761 pre += put_cmd_in_ert("{")
2762 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2763 endPlain = find_end_of_layout(document.body, beginPlain)
2765 z = z - len(document.body[i : beginPlain + 1])
2767 document.body[i : beginPlain + 1] = pre
2768 post = put_cmd_in_ert("}")
2769 document.body[z - 2 : z + 1] = post
2770 elif flextype in old_flexes:
2771 pre = put_cmd_in_ert(old_flexes[flextype])
2772 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2776 argend = find_end_of_inset(document.body, arg)
2778 document.warning("Can't find end of Argument!")
2781 # Find containing paragraph layout
2782 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2783 endPlain = find_end_of_layout(document.body, beginPlain)
2784 argcontent = document.body[beginPlain + 1 : endPlain]
2786 z = z - len(document.body[arg : argend + 1])
2788 del document.body[arg : argend + 1]
2789 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2790 pre += put_cmd_in_ert("{")
2791 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2792 endPlain = find_end_of_layout(document.body, beginPlain)
2794 z = z - len(document.body[i : beginPlain + 1])
2796 document.body[i : beginPlain + 1] = pre
2797 post = put_cmd_in_ert("}")
2798 document.body[z - 2 : z + 1] = post
2803 def revert_beamerblocks(document):
2804 " Reverts beamer block arguments to ERT "
2806 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2807 if document.textclass not in beamer_classes:
2810 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2812 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2815 i = find_token(document.body, "\\begin_inset Argument", i)
2818 # Find containing paragraph layout
2819 parent = get_containing_layout(document.body, i)
2821 document.warning("Malformed lyx document: Can't find parent paragraph layout")
2826 realparbeg = parent[3]
2827 layoutname = parent[0]
2829 for p in range(parbeg, parend):
2833 if layoutname in blocks:
2834 m = rx.match(document.body[p])
2838 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2839 endPlain = find_end_of_layout(document.body, beginPlain)
2840 endInset = find_end_of_inset(document.body, p)
2841 content = document.body[beginPlain + 1 : endPlain]
2843 realparend = realparend - len(document.body[p : endInset + 1])
2845 del document.body[p : endInset + 1]
2846 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2847 document.body[realparbeg : realparbeg] = subst
2849 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2850 endPlain = find_end_of_layout(document.body, beginPlain)
2851 endInset = find_end_of_inset(document.body, p)
2852 content = document.body[beginPlain + 1 : endPlain]
2854 realparend = realparend - len(document.body[p : endInset + 1])
2856 del document.body[p : endInset + 1]
2857 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2858 document.body[realparbeg : realparbeg] = subst
2863 def convert_beamerblocks(document):
2864 " Converts beamer block ERT args to native InsetArgs "
2866 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2867 if document.textclass not in beamer_classes:
2870 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2874 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2877 parent = get_containing_layout(document.body, i)
2878 if parent == False or parent[1] != i:
2879 document.warning("Wrong parent layout!")
2885 if document.body[parbeg] == "\\begin_inset ERT":
2886 ertcont = parbeg + 5
2888 if document.body[ertcont].startswith("<"):
2889 # This is an overlay specification
2891 document.body[ertcont] = document.body[ertcont][1:]
2892 if document.body[ertcont].endswith(">"):
2894 document.body[ertcont] = document.body[ertcont][:-1]
2895 # Convert to ArgInset
2896 document.body[parbeg] = "\\begin_inset Argument 1"
2897 elif document.body[ertcont].endswith("}"):
2899 tok = document.body[ertcont].find('>{')
2901 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2902 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2903 'status collapsed', '', '\\begin_layout Plain Layout',
2904 document.body[ertcont][tok + 2:-1]]
2905 # Convert to ArgInset
2906 document.body[parbeg] = "\\begin_inset Argument 1"
2907 elif document.body[ertcont].startswith("{"):
2908 # This is the block title
2909 if document.body[ertcont].endswith("}"):
2910 # strip off the braces
2911 document.body[ertcont] = document.body[ertcont][1:-1]
2912 # Convert to ArgInset
2913 document.body[parbeg] = "\\begin_inset Argument 2"
2914 elif count_pars_in_inset(document.body, ertcont) > 1:
2915 # Multipar ERT. Skip this.
2918 convert_TeX_brace_to_Argument(document, i, 2, 2, False, True)
2921 j = find_end_of_layout(document.body, i)
2923 document.warning("end of layout not found!")
2924 k = find_token(document.body, "\\begin_inset Argument", i, j)
2926 document.warning("InsetArgument not found!")
2928 l = find_end_of_inset(document.body, k)
2929 m = find_token(document.body, "\\begin_inset ERT", l, j)
2937 def convert_overprint(document):
2938 " Convert old beamer overprint layouts to ERT "
2940 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2941 if document.textclass not in beamer_classes:
2946 i = find_token(document.body, "\\begin_layout Overprint", i)
2949 # Find end of sequence
2950 j = find_end_of_sequence(document.body, i)
2952 document.warning("Malformed lyx document. Cannot find end of Overprint sequence!")
2956 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
2958 if document.body[j] == "\\end_deeper":
2959 esubst = ["", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
2961 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
2962 endseq = endseq + len(esubst) - len(document.body[j : j])
2963 document.body[j : j] = esubst
2964 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
2966 argend = find_end_of_layout(document.body, argbeg)
2968 document.warning("Malformed lyx document. Cannot find end of Overprint argument!")
2971 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
2972 endPlain = find_end_of_layout(document.body, beginPlain)
2973 content = document.body[beginPlain + 1 : endPlain]
2975 endseq = endseq - len(document.body[argbeg : argend + 1])
2977 del document.body[argbeg : argend + 1]
2978 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2980 endseq = endseq - len(document.body[i : i])
2981 document.body[i : i] = subst + ["\\end_layout"]
2982 endseq += len(subst)
2984 for p in range(i, endseq):
2985 if document.body[p] == "\\begin_layout Overprint":
2986 document.body[p] = "\\begin_layout Standard"
2991 def revert_overprint(document):
2992 " Revert old beamer overprint layouts to ERT "
2994 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2995 if document.textclass not in beamer_classes:
3000 i = find_token(document.body, "\\begin_layout Overprint", i)
3003 # Find end of sequence
3004 j = find_end_of_sequence(document.body, i)
3006 document.warning("Malformed lyx document. Cannot find end of Overprint sequence!")
3010 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
3011 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}")
3012 endseq = endseq + len(esubst) - len(document.body[j : j])
3013 if document.body[j] == "\\end_deeper":
3014 document.body[j : j] = ["\\end_deeper", ""] + esubst
3016 document.body[j : j] = esubst
3019 if document.body[r] == "\\begin_deeper":
3020 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3022 document.body[r] = ""
3023 document.body[s] = ""
3027 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
3029 argend = find_end_of_inset(document.body, argbeg)
3031 document.warning("Malformed lyx document. Cannot find end of Overprint argument!")
3034 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3035 endPlain = find_end_of_layout(document.body, beginPlain)
3036 content = document.body[beginPlain + 1 : endPlain]
3038 endseq = endseq - len(document.body[argbeg : argend])
3040 del document.body[argbeg : argend + 1]
3041 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3043 endseq = endseq - len(document.body[i : i])
3044 document.body[i : i] = subst + ["\\end_layout"]
3045 endseq += len(subst)
3051 if document.body[p] == "\\begin_layout Overprint":
3052 q = find_end_of_layout(document.body, p)
3054 document.warning("Malformed lyx document. Cannot find end of Overprint layout!")
3057 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\onslide")
3058 argbeg = find_token(document.body, "\\begin_inset Argument item:1", p, q)
3060 argend = find_end_of_inset(document.body, argbeg)
3062 document.warning("Malformed lyx document. Cannot find end of Overprint item argument!")
3065 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3066 endPlain = find_end_of_layout(document.body, beginPlain)
3067 content = document.body[beginPlain + 1 : endPlain]
3069 endseq = endseq - len(document.body[argbeg : argend + 1])
3071 del document.body[argbeg : argend + 1]
3072 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3073 endseq = endseq - len(document.body[p : p + 1]) + len(subst)
3074 document.body[p : p + 1] = subst
3080 def revert_frametitle(document):
3081 " Reverts beamer frametitle layout to ERT "
3083 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3084 if document.textclass not in beamer_classes:
3087 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
3090 i = find_token(document.body, "\\begin_layout FrameTitle", i)
3093 j = find_end_of_layout(document.body, i)
3095 document.warning("Malformed lyx document: Can't find end of FrameTitle layout")
3099 document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
3100 endlay += len(put_cmd_in_ert("}"))
3101 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\frametitle")
3102 for p in range(i, j):
3105 m = rx.match(document.body[p])
3109 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3110 endPlain = find_end_of_layout(document.body, beginPlain)
3111 endInset = find_end_of_inset(document.body, p)
3112 content = document.body[beginPlain + 1 : endPlain]
3114 endlay = endlay - len(document.body[p : endInset + 1])
3116 del document.body[p : endInset + 1]
3117 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3119 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3120 endPlain = find_end_of_layout(document.body, beginPlain)
3121 endInset = find_end_of_inset(document.body, p)
3122 content = document.body[beginPlain + 1 : endPlain]
3124 endlay = endlay - len(document.body[p : endInset + 1])
3126 del document.body[p : endInset + 1]
3127 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3129 subst += put_cmd_in_ert("{")
3130 document.body[i : i + 1] = subst
3134 def convert_epigraph(document):
3135 " Converts memoir epigraph to new syntax "
3137 if document.textclass != "memoir":
3142 i = find_token(document.body, "\\begin_layout Epigraph", i)
3145 j = find_end_of_layout(document.body, i)
3147 document.warning("Malformed lyx document: Can't find end of Epigraph layout")
3152 ert = find_token(document.body, "\\begin_inset ERT", i, j)
3154 endInset = find_end_of_inset(document.body, ert)
3155 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", ert)
3156 endPlain = find_end_of_layout(document.body, beginPlain)
3157 ertcont = beginPlain + 2
3158 if document.body[ertcont] == "}{":
3160 # Convert to ArgInset
3161 endlay = endlay - 2 * len(document.body[j])
3162 begsubst = ['\\begin_inset Argument post:1', 'status collapsed', '',
3163 '\\begin_layout Plain Layout']
3164 endsubst = ['\\end_layout', '', '\\end_inset', '', document.body[j]]
3165 document.body[j : j + 1] = endsubst
3166 document.body[endInset + 1 : endInset + 1] = begsubst
3168 endlay += len(begsubst) + len(endsubst)
3169 endlay = endlay - len(document.body[ert : endInset + 1])
3170 del document.body[ert : endInset + 1]
3175 def revert_epigraph(document):
3176 " Reverts memoir epigraph argument to ERT "
3178 if document.textclass != "memoir":
3183 i = find_token(document.body, "\\begin_layout Epigraph", i)
3186 j = find_end_of_layout(document.body, i)
3188 document.warning("Malformed lyx document: Can't find end of Epigraph layout")
3193 p = find_token(document.body, "\\begin_layout Argument post:1", i, j)
3195 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3196 endPlain = find_end_of_layout(document.body, beginPlain)
3197 endInset = find_end_of_inset(document.body, p)
3198 content = document.body[beginPlain + 1 : endPlain]
3200 endlay = endlay - len(document.body[p : endInset + 1])
3202 del document.body[p : endInset + 1]
3203 subst += put_cmd_in_ert("}{") + content
3205 subst += put_cmd_in_ert("}{")
3207 document.body[j : j] = subst + document.body[j : j]
3211 def convert_captioninsets(document):
3212 " Converts caption insets to new syntax "
3216 i = find_token(document.body, "\\begin_inset Caption", i)
3219 document.body[i] = "\\begin_inset Caption Standard"
3224 def revert_captioninsets(document):
3225 " Reverts caption insets to old syntax "
3229 i = find_token(document.body, "\\begin_inset Caption Standard", i)
3232 document.body[i] = "\\begin_inset Caption"
3236 def convert_captionlayouts(document):
3237 " Convert caption layouts to caption insets. "
3240 "Captionabove": "Above",
3241 "Captionbelow": "Below",
3242 "FigCaption" : "FigCaption",
3243 "Table_Caption" : "Table",
3244 "CenteredCaption" : "Centered",
3245 "Bicaption" : "Bicaption",
3250 i = find_token(document.body, "\\begin_layout", i)
3253 val = get_value(document.body, "\\begin_layout", i)
3254 if val in caption_dict.keys():
3255 j = find_end_of_layout(document.body, i)
3257 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3260 document.body[j:j] = ["\\end_layout", "", "\\end_inset", "", ""]
3261 document.body[i:i+1] = ["\\begin_layout %s" % document.default_layout,
3262 "\\begin_inset Caption %s" % caption_dict[val], "",
3263 "\\begin_layout %s" % document.default_layout]
3267 def revert_captionlayouts(document):
3268 " Revert caption insets to caption layouts. "
3271 "Above" : "Captionabove",
3272 "Below" : "Captionbelow",
3273 "FigCaption" : "FigCaption",
3274 "Table" : "Table_Caption",
3275 "Centered" : "CenteredCaption",
3276 "Bicaption" : "Bicaption",
3280 rx = re.compile(r'^\\begin_inset Caption (\S+)$')
3282 i = find_token(document.body, "\\begin_inset Caption", i)
3286 m = rx.match(document.body[i])
3290 if val not in caption_dict.keys():
3294 # We either need to delete the previous \begin_layout line, or we
3295 # need to end the previous layout if this inset is not in the first
3296 # position of the paragraph.
3297 layout_before = find_token_backwards(document.body, "\\begin_layout", i)
3298 if layout_before == -1:
3299 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3301 layout_line = document.body[layout_before]
3302 del_layout_before = True
3303 l = layout_before + 1
3305 if document.body[l] != "":
3306 del_layout_before = False
3309 if del_layout_before:
3310 del document.body[layout_before:i]
3313 document.body[i:i] = ["\\end_layout", ""]
3316 # Find start of layout in the inset and end of inset
3317 j = find_token(document.body, "\\begin_layout", i)
3319 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3321 k = find_end_of_inset(document.body, i)
3323 document.warning("Malformed LyX document: Missing `\\end_inset'.")
3326 # We either need to delete the following \end_layout line, or we need
3327 # to restart the old layout if this inset is not at the paragraph end.
3328 layout_after = find_token(document.body, "\\end_layout", k)
3329 if layout_after == -1:
3330 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3332 del_layout_after = True
3334 while l < layout_after:
3335 if document.body[l] != "":
3336 del_layout_after = False
3339 if del_layout_after:
3340 del document.body[k+1:layout_after+1]
3342 document.body[k+1:k+1] = [layout_line, ""]
3344 # delete \begin_layout and \end_inset and replace \begin_inset with
3345 # "\begin_layout XXX". This works because we can only have one
3346 # paragraph in the caption inset: The old \end_layout will be recycled.
3347 del document.body[k]
3348 if document.body[k] == "":
3349 del document.body[k]
3350 del document.body[j]
3351 if document.body[j] == "":
3352 del document.body[j]
3353 document.body[i] = "\\begin_layout %s" % caption_dict[val]
3354 if document.body[i+1] == "":
3355 del document.body[i+1]
3359 def revert_fragileframe(document):
3360 " Reverts beamer FragileFrame layout to ERT "
3362 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3363 if document.textclass not in beamer_classes:
3368 i = find_token(document.body, "\\begin_layout FragileFrame", i)
3371 # Find end of sequence
3372 j = find_end_of_sequence(document.body, i)
3374 document.warning("Malformed lyx document. Cannot find end of FragileFrame sequence!")
3378 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{frame}")
3379 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{frame}")
3380 endseq = endseq + len(esubst) - len(document.body[j : j])
3381 if document.body[j] == "\\end_deeper":
3382 document.body[j : j] = ["\\end_deeper", ""] + esubst
3384 document.body[j : j] = esubst
3385 for q in range(i, j):
3386 if document.body[q] == "\\begin_layout FragileFrame":
3387 document.body[q] = "\\begin_layout %s" % document.default_layout
3390 if document.body[r] == "\\begin_deeper":
3391 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3393 document.body[r] = ""
3394 document.body[s] = ""
3398 for p in range(1, 5):
3399 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, j)
3402 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3403 endPlain = find_end_of_layout(document.body, beginPlain)
3404 endInset = find_end_of_inset(document.body, arg)
3405 content = document.body[beginPlain + 1 : endPlain]
3407 j = j - len(document.body[arg : endInset + 1])
3409 del document.body[arg : endInset + 1]
3410 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3412 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3413 endPlain = find_end_of_layout(document.body, beginPlain)
3414 endInset = find_end_of_inset(document.body, arg)
3415 content = document.body[beginPlain + 1 : endPlain]
3417 j = j - len(document.body[arg : endInset + 1])
3419 del document.body[arg : endInset + 1]
3420 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3422 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3423 endPlain = find_end_of_layout(document.body, beginPlain)
3424 endInset = find_end_of_inset(document.body, arg)
3425 content = document.body[beginPlain + 1 : endPlain]
3427 j = j - len(document.body[arg : endInset + 1])
3429 del document.body[arg : endInset + 1]
3430 subst += put_cmd_in_ert("[fragile,") + content + put_cmd_in_ert("]")
3432 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3433 endPlain = find_end_of_layout(document.body, beginPlain)
3434 endInset = find_end_of_inset(document.body, arg)
3435 content = document.body[beginPlain + 1 : endPlain]
3437 j = j - len(document.body[arg : endInset + 1])
3439 del document.body[arg : endInset + 1]
3440 subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
3442 subst += put_cmd_in_ert("[fragile]")
3444 document.body[i : i + 1] = subst
3448 def revert_newframes(document):
3449 " Reverts beamer Frame and PlainFrame layouts to old forms "
3451 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3452 if document.textclass not in beamer_classes:
3456 "Frame" : "BeginFrame",
3457 "PlainFrame" : "BeginPlainFrame",
3460 rx = re.compile(r'^\\begin_layout (\S+)$')
3463 i = find_token(document.body, "\\begin_layout", i)
3467 m = rx.match(document.body[i])
3471 if val not in frame_dict.keys():
3474 # Find end of sequence
3475 j = find_end_of_sequence(document.body, i)
3477 document.warning("Malformed lyx document. Cannot find end of Frame sequence!")
3481 subst = ["\\begin_layout %s" % frame_dict[val]]
3482 esubst = ["\\end_layout", "", "\\begin_layout EndFrame", "", "\\end_layout"]
3483 endseq = endseq + len(esubst) - len(document.body[j : j])
3484 if document.body[j] == "\\end_deeper":
3485 document.body[j : j] = ["\\end_deeper", ""] + esubst
3487 document.body[j : j] = esubst
3488 for q in range(i, j):
3489 if document.body[q] == "\\begin_layout %s" % val:
3490 document.body[q] = "\\begin_layout %s" % document.default_layout
3493 if document.body[r] == "\\begin_deeper":
3494 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3496 document.body[r] = ""
3497 document.body[s] = ""
3501 l = find_end_of_layout(document.body, i)
3502 for p in range(1, 5):
3503 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, l)
3506 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3507 endPlain = find_end_of_layout(document.body, beginPlain)
3508 endInset = find_end_of_inset(document.body, arg)
3509 content = document.body[beginPlain + 1 : endPlain]
3511 l = l - len(document.body[arg : endInset + 1])
3513 del document.body[arg : endInset + 1]
3514 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3516 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3517 endPlain = find_end_of_layout(document.body, beginPlain)
3518 endInset = find_end_of_inset(document.body, arg)
3519 content = document.body[beginPlain + 1 : endPlain]
3521 l = l - len(document.body[arg : endInset + 1])
3523 del document.body[arg : endInset + 1]
3524 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3526 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3527 endPlain = find_end_of_layout(document.body, beginPlain)
3528 endInset = find_end_of_inset(document.body, arg)
3529 content = document.body[beginPlain + 1 : endPlain]
3531 l = l - len(document.body[arg : endInset + 1])
3533 del document.body[arg : endInset + 1]
3534 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3536 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3537 endPlain = find_end_of_layout(document.body, beginPlain)
3538 endInset = find_end_of_inset(document.body, arg)
3539 content = document.body[beginPlain + 1 : endPlain]
3541 l = l - len(document.body[arg : endInset + 1])
3543 del document.body[arg : endInset + 1]
3546 document.body[i : i + 1] = subst
3550 def revert_IEEEtran_3(document):
3552 Reverts Flex Insets to TeX-code
3554 if document.textclass == "IEEEtran":
3560 h = find_token(document.body, "\\begin_inset Flex Author Mark", h)
3562 endh = find_end_of_inset(document.body, h)
3563 document.body[endh - 2 : endh + 1] = put_cmd_in_ert("}")
3564 document.body[h : h + 4] = put_cmd_in_ert("\\IEEEauthorrefmark{")
3567 i = find_token(document.body, "\\begin_inset Flex Author Name", i)
3569 endi = find_end_of_inset(document.body, i)
3570 document.body[endi - 2 : endi + 1] = put_cmd_in_ert("}")
3571 document.body[i : i + 4] = put_cmd_in_ert("\\IEEEauthorblockN{")
3574 j = find_token(document.body, "\\begin_inset Flex Author Affiliation", j)
3576 endj = find_end_of_inset(document.body, j)
3577 document.body[endj - 2 : endj + 1] = put_cmd_in_ert("}")
3578 document.body[j : j + 4] = put_cmd_in_ert("\\IEEEauthorblockA{")
3580 if i == -1 and j == -1 and h == -1:
3584 def revert_kurier_fonts(document):
3585 " Revert kurier font definition to LaTeX "
3587 i = find_token(document.header, "\\font_math", 0)
3589 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3590 val = get_value(document.header, "\\font_math", i)
3591 if val == "kurier-math":
3592 add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
3593 "\\usepackage[math]{kurier}\n" \
3594 "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
3595 document.header[i] = "\\font_math auto"
3597 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3598 kurier_fonts = ["kurier", "kurierc", "kurierl", "kurierlc"]
3599 k = find_token(document.header, "\\font_sans kurier", 0)
3601 sf = get_value(document.header, "\\font_sans", k)
3602 if sf in kurier_fonts:
3603 add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
3604 document.header[k] = "\\font_sans default"
3607 def revert_new_libertines(document):
3608 " Revert new libertine font definition to LaTeX "
3610 if find_token(document.header, "\\use_non_tex_fonts true", 0) != -1:
3613 i = find_token(document.header, "\\font_typewriter libertine-mono", 0)
3615 preamble = "\\usepackage"
3616 sc = find_token(document.header, "\\font_tt_scale", 0)
3618 scval = get_value(document.header, "\\font_tt_scale", sc)
3620 preamble += "[scale=%f]" % (float(scval) / 100)
3621 document.header[sc] = "\\font_tt_scale 100"
3622 preamble += "{libertineMono-type1}"
3623 add_to_preamble(document, [preamble])
3624 document.header[i] = "\\font_typewriter default"
3626 k = find_token(document.header, "\\font_sans biolinum", 0)
3628 preamble = "\\usepackage"
3630 j = find_token(document.header, "\\font_osf true", 0)
3635 sc = find_token(document.header, "\\font_sf_scale", 0)
3637 scval = get_value(document.header, "\\font_sf_scale", sc)
3639 options += ",scale=%f" % (float(scval) / 100)
3640 document.header[sc] = "\\font_sf_scale 100"
3642 preamble += "[" + options +"]"
3643 preamble += "{biolinum-type1}"
3644 add_to_preamble(document, [preamble])
3645 document.header[k] = "\\font_sans default"
3652 supported_versions = ["2.1.0","2.1"]
3655 [415, [convert_undertilde]],
3657 [417, [convert_japanese_encodings]],
3660 [420, [convert_biblio_style]],
3661 [421, [convert_longtable_captions]],
3662 [422, [convert_use_packages]],
3663 [423, [convert_use_mathtools]],
3664 [424, [convert_cite_engine_type]],
3668 [428, [convert_cell_rotation]],
3669 [429, [convert_table_rotation]],
3670 [430, [convert_listoflistings]],
3671 [431, [convert_use_amssymb]],
3673 [433, [convert_armenian]],
3681 [441, [convert_mdnomath]],
3686 [446, [convert_latexargs]],
3687 [447, [convert_IEEEtran, convert_AASTeX, convert_AGUTeX, convert_IJMP, convert_SIGPLAN, convert_SIGGRAPH, convert_EuropeCV, convert_Initials, convert_ModernCV]],
3688 [448, [convert_literate]],
3691 [451, [convert_beamerargs, convert_againframe_args, convert_corollary_args, convert_quote_args]],
3692 [452, [convert_beamerblocks]],
3693 [453, [convert_use_stmaryrd]],
3694 [454, [convert_overprint]],
3696 [456, [convert_epigraph]],
3697 [457, [convert_use_stackrel]],
3698 [458, [convert_captioninsets, convert_captionlayouts]],
3706 [461, [revert_new_libertines]],
3707 [460, [revert_kurier_fonts]],
3708 [459, [revert_IEEEtran_3]],
3709 [458, [revert_fragileframe, revert_newframes]],
3710 [457, [revert_captioninsets, revert_captionlayouts]],
3711 [456, [revert_use_stackrel]],
3712 [455, [revert_epigraph]],
3713 [454, [revert_frametitle]],
3714 [453, [revert_overprint]],
3715 [452, [revert_use_stmaryrd]],
3716 [451, [revert_beamerblocks]],
3717 [450, [revert_beamerargs, revert_beamerargs2, revert_beamerargs3, revert_beamerflex]],
3718 [449, [revert_garamondx, revert_garamondx_newtxmath]],
3719 [448, [revert_itemargs]],
3720 [447, [revert_literate]],
3721 [446, [revert_IEEEtran, revert_IEEEtran_2, revert_AASTeX, revert_AGUTeX, revert_IJMP, revert_SIGPLAN, revert_SIGGRAPH, revert_EuropeCV, revert_Initials, revert_ModernCV_3]],
3722 [445, [revert_latexargs]],
3723 [444, [revert_uop]],
3724 [443, [revert_biolinum]],
3726 [441, [revert_newtxmath]],
3727 [440, [revert_mdnomath]],
3728 [439, [revert_mathfonts]],
3729 [438, [revert_minionpro]],
3730 [437, [revert_ipadeco, revert_ipachar]],
3731 [436, [revert_texgyre]],
3732 [435, [revert_mathdesign]],
3733 [434, [revert_txtt]],
3734 [433, [revert_libertine]],
3735 [432, [revert_armenian]],
3736 [431, [revert_languages, revert_ancientgreek]],
3737 [430, [revert_use_amssymb]],
3738 [429, [revert_listoflistings]],
3739 [428, [revert_table_rotation]],
3740 [427, [revert_cell_rotation]],
3741 [426, [revert_tipa]],
3742 [425, [revert_verbatim]],
3743 [424, [revert_cancel]],
3744 [423, [revert_cite_engine_type]],
3745 [422, [revert_use_mathtools]],
3746 [421, [revert_use_packages]],
3747 [420, [revert_longtable_captions]],
3748 [419, [revert_biblio_style]],
3749 [418, [revert_australian]],
3750 [417, [revert_justification]],
3751 [416, [revert_japanese_encodings]],
3752 [415, [revert_negative_space, revert_math_spaces]],
3753 [414, [revert_undertilde]],
3754 [413, [revert_visible_space]]
3758 if __name__ == "__main__":