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 def revert_Argument_to_TeX_brace(document, line, endline, n, nmax, environment, opt):
58 Reverts an InsetArgument to TeX-code
60 revert_Argument_to_TeX_brace(document, LineOfBegin, LineOfEnd, StartArgument, EndArgument, isEnvironment, isOpt)
61 LineOfBegin is the line of the \begin_layout or \begin_inset statement
62 LineOfEnd is the line of the \end_layout or \end_inset statement, if "0" is given, the end of the file is used instead
63 StartArgument is the number of the first argument that needs to be converted
64 EndArgument is the number of the last argument that needs to be converted or the last defined one
65 isEnvironment must be true, if the layout is for a LaTeX environment
66 isOpt must be true, if the argument is an optional one
70 while lineArg != -1 and n < nmax + 1:
71 lineArg = find_token(document.body, "\\begin_inset Argument " + str(n), line)
72 if lineArg > endline and endline != 0:
75 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", lineArg)
76 # we have to assure that no other inset is in the Argument
77 beginInset = find_token(document.body, "\\begin_inset", beginPlain)
78 endInset = find_token(document.body, "\\end_inset", beginPlain)
81 while beginInset < endInset and beginInset != -1:
82 beginInset = find_token(document.body, "\\begin_inset", k)
83 endInset = find_token(document.body, "\\end_inset", l)
86 if environment == False:
88 document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("}{")
89 del(document.body[lineArg : beginPlain + 1])
92 document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("]")
93 document.body[lineArg : beginPlain + 1] = put_cmd_in_ert("[")
96 document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("}")
97 document.body[lineArg : beginPlain + 1] = put_cmd_in_ert("{")
103 def convert_TeX_brace_to_Argument(document, line, n, nmax, inset, environment, opt):
105 Converts TeX code for mandatory arguments to an InsetArgument
106 The conversion of TeX code for optional arguments must be done with another routine
107 !!! Be careful if the braces are different in your case as expected here:
108 - "}{" separates mandatory arguments of commands
109 - "}" + "{" separates mandatory arguments of commands
110 - "}" + " " + "{" separates mandatory arguments of commands
111 - { and } surround a mandatory argument of an environment
113 convert_TeX_brace_to_Argument(document, LineOfBeginLayout/Inset, StartArgument, EndArgument, isInset, isEnvironment, isOpt)
114 LineOfBeginLayout/Inset is the line of the \begin_layout or \begin_inset statement
115 StartArgument is the number of the first ERT that needs to be converted
116 EndArgument is the number of the last ERT that needs to be converted
117 isInset must be true, if braces inside an InsetLayout needs to be converted
118 isEnvironment must be true, if the layout is for a LaTeX environment
119 isOpt must be true, if the argument is an optional one
121 Todo: this routine can currently handle only one mandatory argument of environments
126 while lineERT != -1 and n < nmax + 1:
127 lineERT = find_token(document.body, "\\begin_inset ERT", lineERT)
128 if environment == False and lineERT != -1:
131 bracePair = find_token(document.body, "][", lineERT)
133 bracePair = find_token(document.body, "}{", lineERT)
134 # assure that the "}{" is in this ERT
135 if bracePair == lineERT + 5:
136 end = find_token(document.body, "\\end_inset", bracePair)
137 document.body[lineERT : end + 1] = ["\\end_layout", "", "\\end_inset"]
139 # in the case that n > 1 we have optional arguments before
140 # therefore detect them if any
142 # first check if there is an argument
143 lineArg = find_token(document.body, "\\begin_inset Argument", line)
144 if lineArg < lineERT and lineArg != -1:
145 # we have an argument, so now search backwards for its end
146 # we must now assure that we don't find other insets like e.g. a newline
147 endInsetArg = lineERT
148 endLayoutArg = endInsetArg
149 while endInsetArg != endLayoutArg + 2 and endInsetArg != -1:
150 endInsetArg = endInsetArg - 1
151 endLayoutArg = endInsetArg
152 endInsetArg = find_token_backwards(document.body, "\\end_inset", endInsetArg)
153 endLayoutArg = find_token_backwards(document.body, "\\end_layout", endLayoutArg)
154 line = endInsetArg + 1
156 document.body[line + 1 : line + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
158 document.body[line + 4 : line + 4] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
160 document.body[endn : endn] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
164 # now check the case that we have "}" + "{" in two ERTs
168 endBrace = find_token(document.body, "]", lineERT)
170 endBrace = find_token(document.body, "}", lineERT)
171 if endBrace == lineERT + 5:
174 beginBrace = find_token(document.body, "[", endBrace)
176 beginBrace = find_token(document.body, "{", endBrace)
177 # assure that the ERTs are consecutive (11 or 12 depending if there is a space between the ERTs or not)
178 if beginBrace == endBrace + 11 or beginBrace == endBrace + 12:
179 end = find_token(document.body, "\\end_inset", beginBrace)
180 document.body[lineERT : end + 1] = ["\\end_layout", "", "\\end_inset"]
182 # in the case that n > 1 we have optional arguments before
183 # therefore detect them if any
185 # first check if there is an argument
186 lineArg = find_token(document.body, "\\begin_inset Argument", line)
187 if lineArg < lineERT and lineArg != -1:
188 # we have an argument, so now search backwards for its end
189 # we must now assure that we don't find other insets like e.g. a newline
190 endInsetArg = lineERT
191 endLayoutArg = endInsetArg
192 while endInsetArg != endLayoutArg + 2 and endInsetArg != -1:
193 endInsetArg = endInsetArg - 1
194 endLayoutArg = endInsetArg
195 endInsetArg = find_token_backwards(document.body, "\\end_inset", endInsetArg)
196 endLayoutArg = find_token_backwards(document.body, "\\end_layout", endLayoutArg)
197 line = endInsetArg + 1
199 document.body[line + 1 : line + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
201 document.body[line + 4 : line + 4] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
203 document.body[endn : endn] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
206 # set the line where the next argument will be inserted
207 if beginBrace == endBrace + 11:
215 if environment == True and lineERT != -1:
218 opening = find_token(document.body, "[", lineERT)
220 opening = find_token(document.body, "{", lineERT)
221 if opening == lineERT + 5: # assure that the "{" is in this ERT
222 end = find_token(document.body, "\\end_inset", opening)
223 document.body[lineERT : end + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
225 lineERT2 = find_token(document.body, "\\begin_inset ERT", lineERT)
228 closing = find_token(document.body, "]", lineERT)
230 closing = find_token(document.body, "}", lineERT2)
231 if closing == lineERT2 + 5: # assure that the "}" is in this ERT
232 end2 = find_token(document.body, "\\end_inset", closing)
233 document.body[lineERT2 : end2 + 1] = ["\\end_layout", "", "\\end_inset"]
238 ###############################################################################
240 ### Conversion and reversion routines
242 ###############################################################################
244 def revert_visible_space(document):
245 "Revert InsetSpace visible into its ERT counterpart"
248 i = find_token(document.body, "\\begin_inset space \\textvisiblespace{}", i)
251 end = find_end_of_inset(document.body, i)
252 subst = put_cmd_in_ert("\\textvisiblespace{}")
253 document.body[i:end + 1] = subst
256 def convert_undertilde(document):
257 " Load undertilde automatically "
258 i = find_token(document.header, "\\use_mathdots" , 0)
260 i = find_token(document.header, "\\use_mhchem" , 0)
262 i = find_token(document.header, "\\use_esint" , 0)
264 document.warning("Malformed LyX document: Can't find \\use_mathdots.")
266 j = find_token(document.preamble, "\\usepackage{undertilde}", 0)
268 document.header.insert(i + 1, "\\use_undertilde 0")
270 document.header.insert(i + 1, "\\use_undertilde 2")
271 del document.preamble[j]
274 def revert_undertilde(document):
275 " Load undertilde if used in the document "
276 undertilde = find_token(document.header, "\\use_undertilde" , 0)
278 document.warning("No \\use_undertilde line. Assuming auto.")
280 val = get_value(document.header, "\\use_undertilde", undertilde)
281 del document.header[undertilde]
285 document.warning("Invalid \\use_undertilde value: " + val + ". Assuming auto.")
286 # probably usedots has not been changed, but be safe.
294 add_to_preamble(document, ["\\usepackage{undertilde}"])
297 # so we are in the auto case. we want to load undertilde if \utilde is used.
300 i = find_token(document.body, '\\begin_inset Formula', i)
303 j = find_end_of_inset(document.body, i)
305 document.warning("Malformed LyX document: Can't find end of Formula inset at line " + str(i))
308 code = "\n".join(document.body[i:j])
309 if code.find("\\utilde") != -1:
310 add_to_preamble(document, ["\\@ifundefined{utilde}{\\usepackage{undertilde}}"])
315 def revert_negative_space(document):
316 "Revert InsetSpace negmedspace and negthickspace into its TeX-code counterpart"
321 i = find_token(document.body, "\\begin_inset space \\negmedspace{}", i)
323 j = find_token(document.body, "\\begin_inset space \\negthickspace{}", j)
325 # load amsmath in the preamble if not already loaded if we are at the end of checking
327 i = find_token(document.header, "\\use_amsmath 2", 0)
329 add_to_preamble(document, ["\\@ifundefined{negthickspace}{\\usepackage{amsmath}}"])
333 end = find_end_of_inset(document.body, i)
334 subst = put_cmd_in_ert("\\negmedspace{}")
335 document.body[i:end + 1] = subst
336 j = find_token(document.body, "\\begin_inset space \\negthickspace{}", j)
339 end = find_end_of_inset(document.body, j)
340 subst = put_cmd_in_ert("\\negthickspace{}")
341 document.body[j:end + 1] = subst
345 def revert_math_spaces(document):
346 "Revert formulas with protected custom space and protected hfills to TeX-code"
349 i = find_token(document.body, "\\begin_inset Formula", i)
352 j = document.body[i].find("\\hspace*")
354 end = find_end_of_inset(document.body, i)
355 subst = put_cmd_in_ert(document.body[i][21:])
356 document.body[i:end + 1] = subst
360 def convert_japanese_encodings(document):
361 " Rename the japanese encodings to names understood by platex "
363 "EUC-JP-pLaTeX": "euc",
365 "SJIS-pLaTeX": "sjis"
367 i = find_token(document.header, "\\inputencoding" , 0)
370 val = get_value(document.header, "\\inputencoding", i)
371 if val in jap_enc_dict.keys():
372 document.header[i] = "\\inputencoding %s" % jap_enc_dict[val]
375 def revert_japanese_encodings(document):
376 " Revert the japanese encodings name changes "
378 "euc": "EUC-JP-pLaTeX",
380 "sjis": "SJIS-pLaTeX"
382 i = find_token(document.header, "\\inputencoding" , 0)
385 val = get_value(document.header, "\\inputencoding", i)
386 if val in jap_enc_dict.keys():
387 document.header[i] = "\\inputencoding %s" % jap_enc_dict[val]
390 def convert_justification(document):
391 " Add the \\justification buffer param"
392 i = find_token(document.header, "\\use_indices" , 0)
394 document.warning("Malformed LyX document: Missing \\use_indices.")
396 document.header.insert(i + 1, "\\justification true")
399 def revert_justification(document):
400 " Revert the \\justification buffer param"
401 if not del_token(document.header, '\\justification', 0):
402 document.warning("Malformed LyX document: Missing \\justification.")
405 def revert_australian(document):
406 "Set English language variants Australian and Newzealand to English"
408 if document.language == "australian" or document.language == "newzealand":
409 document.language = "english"
410 i = find_token(document.header, "\\language", 0)
412 document.header[i] = "\\language english"
415 j = find_token(document.body, "\\lang australian", j)
417 j = find_token(document.body, "\\lang newzealand", 0)
421 document.body[j] = document.body[j].replace("\\lang newzealand", "\\lang english")
423 document.body[j] = document.body[j].replace("\\lang australian", "\\lang english")
427 def convert_biblio_style(document):
428 "Add a sensible default for \\biblio_style based on the citation engine."
429 i = find_token(document.header, "\\cite_engine", 0)
431 engine = get_value(document.header, "\\cite_engine", i).split("_")[0]
432 style = {"basic": "plain", "natbib": "plainnat", "jurabib": "jurabib"}
433 document.header.insert(i + 1, "\\biblio_style " + style[engine])
436 def revert_biblio_style(document):
437 "BibTeX insets with default option use the style defined by \\biblio_style."
438 i = find_token(document.header, "\\biblio_style" , 0)
440 document.warning("No \\biblio_style line. Nothing to do.")
443 default_style = get_value(document.header, "\\biblio_style", i)
444 del document.header[i]
446 # We are looking for bibtex insets having the default option
449 i = find_token(document.body, "\\begin_inset CommandInset bibtex", i)
452 j = find_end_of_inset(document.body, i)
454 document.warning("Malformed LyX document: Can't find end of bibtex inset at line " + str(i))
457 k = find_token(document.body, "options", i, j)
459 options = get_quoted_value(document.body, "options", k)
460 if "default" in options.split(","):
461 document.body[k] = 'options "%s"' \
462 % options.replace("default", default_style)
466 def handle_longtable_captions(document, forward):
469 begin_table = find_token(document.body, '<lyxtabular version=', begin_table)
470 if begin_table == -1:
472 end_table = find_end_of(document.body, begin_table, '<lyxtabular', '</lyxtabular>')
474 document.warning("Malformed LyX document: Could not find end of table.")
477 fline = find_token(document.body, "<features", begin_table, end_table)
479 document.warning("Can't find features for inset at line " + str(begin_table))
482 p = document.body[fline].find("islongtable")
487 numrows = get_option_value(document.body[begin_table], "rows")
489 numrows = int(numrows)
491 document.warning(document.body[begin_table])
492 document.warning("Unable to determine rows!")
493 begin_table = end_table
495 begin_row = begin_table
496 for row in range(numrows):
497 begin_row = find_token(document.body, '<row', begin_row, end_table)
499 document.warning("Can't find row " + str(row + 1))
501 end_row = find_end_of(document.body, begin_row, '<row', '</row>')
503 document.warning("Can't find end of row " + str(row + 1))
506 if (get_option_value(document.body[begin_row], 'caption') == 'true' and
507 get_option_value(document.body[begin_row], 'endfirsthead') != 'true' and
508 get_option_value(document.body[begin_row], 'endhead') != 'true' and
509 get_option_value(document.body[begin_row], 'endfoot') != 'true' and
510 get_option_value(document.body[begin_row], 'endlastfoot') != 'true'):
511 document.body[begin_row] = set_option_value(document.body[begin_row], 'caption', 'true", endfirsthead="true')
512 elif get_option_value(document.body[begin_row], 'caption') == 'true':
513 if get_option_value(document.body[begin_row], 'endfirsthead') == 'true':
514 document.body[begin_row] = set_option_value(document.body[begin_row], 'endfirsthead', 'false')
515 if get_option_value(document.body[begin_row], 'endhead') == 'true':
516 document.body[begin_row] = set_option_value(document.body[begin_row], 'endhead', 'false')
517 if get_option_value(document.body[begin_row], 'endfoot') == 'true':
518 document.body[begin_row] = set_option_value(document.body[begin_row], 'endfoot', 'false')
519 if get_option_value(document.body[begin_row], 'endlastfoot') == 'true':
520 document.body[begin_row] = set_option_value(document.body[begin_row], 'endlastfoot', 'false')
522 # since there could be a tabular inside this one, we
523 # cannot jump to end.
527 def convert_longtable_captions(document):
528 "Add a firsthead flag to caption rows"
529 handle_longtable_captions(document, True)
532 def revert_longtable_captions(document):
533 "remove head/foot flag from caption rows"
534 handle_longtable_captions(document, False)
537 def convert_use_packages(document):
538 "use_xxx yyy => use_package xxx yyy"
539 packages = ["amsmath", "esint", "mathdots", "mhchem", "undertilde"]
541 i = find_token(document.header, "\\use_%s" % p, 0)
543 value = get_value(document.header, "\\use_%s" % p, i)
544 document.header[i] = "\\use_package %s %s" % (p, value)
547 def revert_use_packages(document):
548 "use_package xxx yyy => use_xxx yyy"
549 packages = ["amsmath", "esint", "mhchem", "mathdots", "undertilde"]
550 # the order is arbitrary for the use_package version, and not all packages need to be given.
551 # Ensure a complete list and correct order (important for older LyX versions and especially lyx2lyx)
552 # first loop: find line with first package
555 regexp = re.compile(r'(\\use_package\s+%s)' % p)
556 i = find_re(document.header, regexp, 0)
557 if i != -1 and (j < 0 or i < j):
559 # second loop: replace or insert packages in front of all existing ones
561 regexp = re.compile(r'(\\use_package\s+%s)' % p)
562 i = find_re(document.header, regexp, 0)
564 value = get_value(document.header, "\\use_package %s" % p, i).split()[1]
565 del document.header[i]
566 document.header.insert(j, "\\use_%s %s" % (p, value))
568 document.header.insert(j, "\\use_%s 1" % p)
572 def convert_use_package(document, pkg):
573 i = find_token(document.header, "\\use_package", 0)
575 document.warning("Malformed LyX document: Can't find \\use_package.")
577 j = find_token(document.preamble, "\\usepackage{" + pkg + "}", 0)
579 document.header.insert(i + 1, "\\use_package " + pkg + " 0")
581 document.header.insert(i + 1, "\\use_package " + pkg + " 2")
582 del document.preamble[j]
585 def revert_use_package(document, pkg, commands, oldauto):
586 # oldauto defines how the version we are reverting to behaves:
587 # if it is true, the old version uses the package automatically.
588 # if it is false, the old version never uses the package.
589 regexp = re.compile(r'(\\use_package\s+%s)' % pkg)
590 i = find_re(document.header, regexp, 0)
591 value = "1" # default is auto
593 value = get_value(document.header, "\\use_package" , i).split()[1]
594 del document.header[i]
595 if value == "2": # on
596 add_to_preamble(document, ["\\usepackage{" + pkg + "}"])
597 elif value == "1" and not oldauto: # auto
600 i = find_token(document.body, '\\begin_inset Formula', i)
603 j = find_end_of_inset(document.body, i)
605 document.warning("Malformed LyX document: Can't find end of Formula inset at line " + str(i))
608 code = "\n".join(document.body[i:j])
610 if code.find("\\%s" % c) != -1:
611 add_to_preamble(document, ["\\usepackage{" + pkg + "}"])
616 def convert_use_mathtools(document):
617 "insert use_package mathtools"
618 convert_use_package(document, "mathtools")
621 def revert_use_mathtools(document):
622 "remove use_package mathtools"
623 commands = ["mathclap", "mathllap", "mathrlap", \
624 "lgathered", "rgathered", "vcentcolon", "dblcolon", \
625 "coloneqq", "Coloneqq", "coloneq", "Coloneq", "eqqcolon", \
626 "Eqqcolon", "eqcolon", "Eqcolon", "colonapprox", \
627 "Colonapprox", "colonsim", "Colonsim"]
628 revert_use_package(document, "mathtools", commands, False)
631 def convert_use_stmaryrd(document):
632 "insert use_package stmaryrd"
633 convert_use_package(document, "stmaryrd")
636 def revert_use_stmaryrd(document):
637 "remove use_package stmaryrd"
638 # commands provided by stmaryrd.sty but LyX uses other packages:
639 # boxdot lightning, bigtriangledown, bigtriangleup
640 commands = ["shortleftarrow", "shortrightarrow", "shortuparrow", \
641 "shortdownarrow", "Yup", "Ydown", "Yleft", "Yright", \
642 "varcurlyvee", "varcurlywedge", "minuso", "baro", \
643 "sslash", "bbslash", "moo", "varotimes", "varoast", \
644 "varobar", "varodot", "varoslash", "varobslash", \
645 "varocircle", "varoplus", "varominus", "boxast", \
646 "boxbar", "boxslash", "boxbslash", "boxcircle", \
647 "boxbox", "boxempty", "merge", "vartimes", \
648 "fatsemi", "sswarrow", "ssearrow", "curlywedgeuparrow", \
649 "curlywedgedownarrow", "fatslash", "fatbslash", "lbag", \
650 "rbag", "varbigcirc", "leftrightarroweq", \
651 "curlyveedownarrow", "curlyveeuparrow", "nnwarrow", \
652 "nnearrow", "leftslice", "rightslice", "varolessthan", \
653 "varogreaterthan", "varovee", "varowedge", "talloblong", \
654 "interleave", "obar", "obslash", "olessthan", \
655 "ogreaterthan", "ovee", "owedge", "oblong", "inplus", \
656 "niplus", "nplus", "subsetplus", "supsetplus", \
657 "subsetpluseq", "supsetpluseq", "Lbag", "Rbag", \
658 "llbracket", "rrbracket", "llparenthesis", \
659 "rrparenthesis", "binampersand", "bindnasrepma", \
660 "trianglelefteqslant", "trianglerighteqslant", \
661 "ntrianglelefteqslant", "ntrianglerighteqslant", \
662 "llfloor", "rrfloor", "llceil", "rrceil", "arrownot", \
663 "Arrownot", "Mapstochar", "mapsfromchar", "Mapsfromchar", \
664 "leftrightarrowtriangle", "leftarrowtriangle", \
665 "rightarrowtriangle", \
666 "bigcurlyvee", "bigcurlywedge", "bigsqcap", "bigbox", \
667 "bigparallel", "biginterleave", "bignplus", \
668 "varcopyright", "longarrownot", "Longarrownot", \
669 "Mapsto", "mapsfrom", "Mapsfrom" "Longmapsto", \
670 "longmapsfrom", "Longmapsfrom"]
671 revert_use_package(document, "stmaryrd", commands, False)
675 def convert_use_stackrel(document):
676 "insert use_package stackrel"
677 convert_use_package(document, "stackrel")
680 def revert_use_stackrel(document):
681 "remove use_package stackrel"
682 commands = ["stackrel"]
683 revert_use_package(document, "stackrel", commands, False)
686 def convert_cite_engine_type(document):
687 "Determine the \\cite_engine_type from the citation engine."
688 i = find_token(document.header, "\\cite_engine", 0)
691 engine = get_value(document.header, "\\cite_engine", i)
693 engine, type = engine.split("_")
695 type = {"basic": "numerical", "jurabib": "authoryear"}[engine]
696 document.header[i] = "\\cite_engine " + engine
697 document.header.insert(i + 1, "\\cite_engine_type " + type)
700 def revert_cite_engine_type(document):
701 "Natbib had the type appended with an underscore."
702 engine_type = "numerical"
703 i = find_token(document.header, "\\cite_engine_type" , 0)
705 document.warning("No \\cite_engine_type line. Assuming numerical.")
707 engine_type = get_value(document.header, "\\cite_engine_type", i)
708 del document.header[i]
710 # We are looking for the natbib citation engine
711 i = find_token(document.header, "\\cite_engine natbib", 0)
714 document.header[i] = "\\cite_engine natbib_" + engine_type
717 def convert_cite_engine_type_default(document):
718 "Convert \\cite_engine_type to default for the basic citation engine."
719 i = find_token(document.header, "\\cite_engine basic", 0)
722 i = find_token(document.header, "\\cite_engine_type" , 0)
725 document.header[i] = "\\cite_engine_type default"
728 def revert_cite_engine_type_default(document):
729 """Revert \\cite_engine_type default.
731 Revert to numerical for the basic cite engine, otherwise to authoryear."""
732 engine_type = "authoryear"
733 i = find_token(document.header, "\\cite_engine_type default" , 0)
736 j = find_token(document.header, "\\cite_engine basic", 0)
738 engine_type = "numerical"
739 document.header[i] = "\\cite_engine_type " + engine_type
742 # this is the same, as revert_use_cancel() except for the default
743 def revert_cancel(document):
744 "add cancel to the preamble if necessary"
745 commands = ["cancelto", "cancel", "bcancel", "xcancel"]
746 revert_use_package(document, "cancel", commands, False)
749 def revert_verbatim(document):
750 " Revert verbatim einvironments completely to TeX-code. "
753 subst_end = ['\end_layout', '', '\\begin_layout Plain Layout',
755 '\\begin_layout Plain Layout', '', '',
758 '\\end_layout', '', '\\end_inset',
759 '', '', '\\end_layout']
760 subst_begin = ['\\begin_layout Standard', '\\noindent',
761 '\\begin_inset ERT', 'status open', '',
762 '\\begin_layout Plain Layout', '', '', '\\backslash',
764 '\\end_layout', '', '\\begin_layout Plain Layout', '']
767 i = find_token(document.body, "\\begin_layout Verbatim", i)
770 j = find_end_of_layout(document.body, i)
772 document.warning("Malformed LyX document: Can't find end of Verbatim layout")
775 # delete all line breaks insets (there are no other insets)
778 n = find_token(document.body, "\\begin_inset Newline newline", l, j)
780 n = find_token(document.body, "\\begin_inset Newline linebreak", l, j)
783 m = find_end_of_inset(document.body, n)
784 del(document.body[m:m+1])
785 document.body[n:n+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
787 # we deleted a line, so the end of the inset moved forward.
789 # consecutive verbatim environments need to be connected
790 k = find_token(document.body, "\\begin_layout Verbatim", j)
791 if k == j + 2 and consecutive == False:
793 document.body[j:j+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
794 document.body[i:i+1] = subst_begin
796 if k == j + 2 and consecutive == True:
797 document.body[j:j+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
798 del(document.body[i:i+1])
800 if k != j + 2 and consecutive == True:
801 document.body[j:j+1] = subst_end
802 # the next paragraph must not be indented
803 document.body[j+19:j+19] = ['\\noindent']
804 del(document.body[i:i+1])
808 document.body[j:j+1] = subst_end
809 # the next paragraph must not be indented
810 document.body[j+19:j+19] = ['\\noindent']
811 document.body[i:i+1] = subst_begin
814 def revert_tipa(document):
815 " Revert native TIPA insets to mathed or ERT. "
818 i = find_token(document.body, "\\begin_inset IPA", i)
821 j = find_end_of_inset(document.body, i)
823 document.warning("Malformed LyX document: Can't find end of IPA inset")
827 n = find_token(document.body, "\\begin_layout", i, j)
829 document.warning("Malformed LyX document: IPA inset has no embedded layout")
832 m = find_end_of_layout(document.body, n)
834 document.warning("Malformed LyX document: Can't find end of embedded layout")
837 content = document.body[n+1:m]
838 p = find_token(document.body, "\\begin_layout", m, j)
839 if p != -1 or len(content) > 1:
841 content = document.body[i+1:j]
843 # IPA insets with multiple pars need to be wrapped by \begin{IPA}...\end{IPA}
844 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}")
845 add_to_preamble(document, ["\\usepackage{tipa,tipx}"])
847 # single-par IPA insets can be reverted to mathed
848 document.body[i:j+1] = ["\\begin_inset Formula $\\text{\\textipa{" + content[0] + "}}$", "\\end_inset"]
852 def revert_cell_rotation(document):
853 "Revert cell rotations to TeX-code"
855 load_rotating = False
859 # first, let's find out if we need to do anything
860 i = find_token(document.body, '<cell ', i)
863 j = document.body[i].find('rotate="')
865 k = document.body[i].find('"', j + 8)
866 value = document.body[i][j + 8 : k]
868 rgx = re.compile(r' rotate="[^"]+?"')
869 # remove rotate option
870 document.body[i] = rgx.sub('', document.body[i])
872 rgx = re.compile(r' rotate="[^"]+?"')
873 document.body[i] = rgx.sub('rotate="true"', document.body[i])
875 rgx = re.compile(r' rotate="[^"]+?"')
877 # remove rotate option
878 document.body[i] = rgx.sub('', document.body[i])
880 document.body[i + 5 : i + 5] = \
881 put_cmd_in_ert("\\end{turn}")
882 document.body[i + 4 : i + 4] = \
883 put_cmd_in_ert("\\begin{turn}{" + value + "}")
889 add_to_preamble(document, ["\\@ifundefined{turnbox}{\usepackage{rotating}}{}"])
892 def convert_cell_rotation(document):
893 'Convert cell rotation statements from "true" to "90"'
897 # first, let's find out if we need to do anything
898 i = find_token(document.body, '<cell ', i)
901 j = document.body[i].find('rotate="true"')
903 rgx = re.compile(r'rotate="[^"]+?"')
904 # convert "true" to "90"
905 document.body[i] = rgx.sub('rotate="90"', document.body[i])
910 def revert_table_rotation(document):
911 "Revert table rotations to TeX-code"
913 load_rotating = False
917 # first, let's find out if we need to do anything
918 i = find_token(document.body, '<features ', i)
921 j = document.body[i].find('rotate="')
923 end_table = find_token(document.body, '</lyxtabular>', j)
924 k = document.body[i].find('"', j + 8)
925 value = document.body[i][j + 8 : k]
927 rgx = re.compile(r' rotate="[^"]+?"')
928 # remove rotate option
929 document.body[i] = rgx.sub('', document.body[i])
931 rgx = re.compile(r'rotate="[^"]+?"')
932 document.body[i] = rgx.sub('rotate="true"', document.body[i])
934 rgx = re.compile(r' rotate="[^"]+?"')
936 # remove rotate option
937 document.body[i] = rgx.sub('', document.body[i])
939 document.body[end_table + 3 : end_table + 3] = \
940 put_cmd_in_ert("\\end{turn}")
941 document.body[i - 2 : i - 2] = \
942 put_cmd_in_ert("\\begin{turn}{" + value + "}")
948 add_to_preamble(document, ["\\@ifundefined{turnbox}{\usepackage{rotating}}{}"])
951 def convert_table_rotation(document):
952 'Convert table rotation statements from "true" to "90"'
956 # first, let's find out if we need to do anything
957 i = find_token(document.body, '<features ', i)
960 j = document.body[i].find('rotate="true"')
962 rgx = re.compile(r'rotate="[^"]+?"')
963 # convert "true" to "90"
964 document.body[i] = rgx.sub('rotate="90"', document.body[i])
969 def convert_listoflistings(document):
970 'Convert ERT \lstlistoflistings to TOC lstlistoflistings inset'
971 # We can support roundtrip because the command is so simple
974 i = find_token(document.body, "\\begin_inset ERT", i)
977 j = find_end_of_inset(document.body, i)
979 document.warning("Malformed LyX document: Can't find end of ERT inset")
982 ert = get_ert(document.body, i)
983 if ert == "\\lstlistoflistings{}":
984 document.body[i:j] = ["\\begin_inset CommandInset toc", "LatexCommand lstlistoflistings", ""]
990 def revert_listoflistings(document):
991 'Convert TOC lstlistoflistings inset to ERT lstlistoflistings'
994 i = find_token(document.body, "\\begin_inset CommandInset toc", i)
997 if document.body[i+1] == "LatexCommand lstlistoflistings":
998 j = find_end_of_inset(document.body, i)
1000 document.warning("Malformed LyX document: Can't find end of TOC inset")
1003 subst = put_cmd_in_ert("\\lstlistoflistings{}")
1004 document.body[i:j+1] = subst
1005 add_to_preamble(document, ["\\usepackage{listings}"])
1009 def convert_use_amssymb(document):
1010 "insert use_package amssymb"
1011 regexp = re.compile(r'(\\use_package\s+amsmath)')
1012 i = find_re(document.header, regexp, 0)
1014 document.warning("Malformed LyX document: Can't find \\use_package amsmath.")
1016 value = get_value(document.header, "\\use_package" , i).split()[1]
1019 useamsmath = int(value)
1021 document.warning("Invalid \\use_package amsmath: " + value + ". Assuming auto.")
1023 j = find_token(document.preamble, "\\usepackage{amssymb}", 0)
1025 document.header.insert(i + 1, "\\use_package amssymb %d" % useamsmath)
1027 document.header.insert(i + 1, "\\use_package amssymb 2")
1028 del document.preamble[j]
1031 def revert_use_amssymb(document):
1032 "remove use_package amssymb"
1033 regexp1 = re.compile(r'(\\use_package\s+amsmath)')
1034 regexp2 = re.compile(r'(\\use_package\s+amssymb)')
1035 i = find_re(document.header, regexp1, 0)
1036 j = find_re(document.header, regexp2, 0)
1037 value1 = "1" # default is auto
1038 value2 = "1" # default is auto
1040 value1 = get_value(document.header, "\\use_package" , i).split()[1]
1042 value2 = get_value(document.header, "\\use_package" , j).split()[1]
1043 del document.header[j]
1044 if value1 != value2 and value2 == "2": # on
1045 add_to_preamble(document, ["\\usepackage{amssymb}"])
1048 def convert_use_cancel(document):
1049 "insert use_package cancel"
1050 convert_use_package(document, "cancel")
1053 def revert_use_cancel(document):
1054 "remove use_package cancel"
1055 commands = ["cancel", "bcancel", "xcancel", "cancelto"]
1056 revert_use_package(document, "cancel", commands, True)
1059 def revert_ancientgreek(document):
1060 "Set the document language for ancientgreek to greek"
1062 if document.language == "ancientgreek":
1063 document.language = "greek"
1064 i = find_token(document.header, "\\language", 0)
1066 document.header[i] = "\\language greek"
1069 j = find_token(document.body, "\\lang ancientgreek", j)
1073 document.body[j] = document.body[j].replace("\\lang ancientgreek", "\\lang greek")
1077 def revert_languages(document):
1078 "Set the document language for new supported languages to English"
1081 "coptic", "divehi", "hindi", "kurmanji", "lao", "marathi", "occitan", "sanskrit",
1082 "syriac", "tamil", "telugu", "urdu"
1084 for n in range(len(languages)):
1085 if document.language == languages[n]:
1086 document.language = "english"
1087 i = find_token(document.header, "\\language", 0)
1089 document.header[i] = "\\language english"
1091 while j < len(document.body):
1092 j = find_token(document.body, "\\lang " + languages[n], j)
1094 document.body[j] = document.body[j].replace("\\lang " + languages[n], "\\lang english")
1097 j = len(document.body)
1100 def convert_armenian(document):
1101 "Use polyglossia and thus non-TeX fonts for Armenian"
1103 if document.language == "armenian":
1104 i = find_token(document.header, "\\use_non_tex_fonts", 0)
1106 document.header[i] = "\\use_non_tex_fonts true"
1109 def revert_armenian(document):
1110 "Use ArmTeX and thus TeX fonts for Armenian"
1112 if document.language == "armenian":
1113 i = find_token(document.header, "\\use_non_tex_fonts", 0)
1115 document.header[i] = "\\use_non_tex_fonts false"
1118 def revert_libertine(document):
1119 " Revert native libertine font definition to LaTeX "
1121 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1122 i = find_token(document.header, "\\font_roman libertine", 0)
1125 j = find_token(document.header, "\\font_osf true", 0)
1128 preamble = "\\usepackage"
1130 document.header[j] = "\\font_osf false"
1133 preamble += "[lining]"
1134 preamble += "{libertine-type1}"
1135 add_to_preamble(document, [preamble])
1136 document.header[i] = "\\font_roman default"
1139 def revert_txtt(document):
1140 " Revert native txtt font definition to LaTeX "
1142 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1143 i = find_token(document.header, "\\font_typewriter txtt", 0)
1145 preamble = "\\renewcommand{\\ttdefault}{txtt}"
1146 add_to_preamble(document, [preamble])
1147 document.header[i] = "\\font_typewriter default"
1150 def revert_mathdesign(document):
1151 " Revert native mathdesign font definition to LaTeX "
1153 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1159 i = find_token(document.header, "\\font_roman", 0)
1162 val = get_value(document.header, "\\font_roman", i)
1163 if val in mathdesign_dict.keys():
1164 preamble = "\\usepackage[%s" % mathdesign_dict[val]
1166 j = find_token(document.header, "\\font_osf true", 0)
1169 document.header[j] = "\\font_osf false"
1170 l = find_token(document.header, "\\font_sc true", 0)
1173 document.header[l] = "\\font_sc false"
1175 preamble += ",expert"
1176 preamble += "]{mathdesign}"
1177 add_to_preamble(document, [preamble])
1178 document.header[i] = "\\font_roman default"
1181 def revert_texgyre(document):
1182 " Revert native TeXGyre font definition to LaTeX "
1184 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1185 texgyre_fonts = ["tgadventor", "tgbonum", "tgchorus", "tgcursor", \
1186 "tgheros", "tgpagella", "tgschola", "tgtermes"]
1187 i = find_token(document.header, "\\font_roman", 0)
1189 val = get_value(document.header, "\\font_roman", i)
1190 if val in texgyre_fonts:
1191 preamble = "\\usepackage{%s}" % val
1192 add_to_preamble(document, [preamble])
1193 document.header[i] = "\\font_roman default"
1194 i = find_token(document.header, "\\font_sans", 0)
1196 val = get_value(document.header, "\\font_sans", i)
1197 if val in texgyre_fonts:
1198 preamble = "\\usepackage{%s}" % val
1199 add_to_preamble(document, [preamble])
1200 document.header[i] = "\\font_sans default"
1201 i = find_token(document.header, "\\font_typewriter", 0)
1203 val = get_value(document.header, "\\font_typewriter", i)
1204 if val in texgyre_fonts:
1205 preamble = "\\usepackage{%s}" % val
1206 add_to_preamble(document, [preamble])
1207 document.header[i] = "\\font_typewriter default"
1210 def revert_ipadeco(document):
1211 " Revert IPA decorations to ERT "
1214 i = find_token(document.body, "\\begin_inset IPADeco", i)
1217 end = find_end_of_inset(document.body, i)
1219 document.warning("Can't find end of inset at line " + str(i))
1222 line = document.body[i]
1223 rx = re.compile(r'\\begin_inset IPADeco (.*)$')
1225 decotype = m.group(1)
1226 if decotype != "toptiebar" and decotype != "bottomtiebar":
1227 document.warning("Invalid IPADeco type: " + decotype)
1230 blay = find_token(document.body, "\\begin_layout Plain Layout", i, end)
1232 document.warning("Can't find layout for inset at line " + str(i))
1235 bend = find_end_of_layout(document.body, blay)
1237 document.warning("Malformed LyX document: Could not find end of IPADeco inset's layout.")
1240 substi = ["\\begin_inset ERT", "status collapsed", "",
1241 "\\begin_layout Plain Layout", "", "", "\\backslash",
1242 decotype + "{", "\\end_layout", "", "\\end_inset"]
1243 substj = ["\\size default", "", "\\begin_inset ERT", "status collapsed", "",
1244 "\\begin_layout Plain Layout", "", "}", "\\end_layout", "", "\\end_inset"]
1245 # do the later one first so as not to mess up the numbering
1246 document.body[bend:end + 1] = substj
1247 document.body[i:blay + 1] = substi
1248 i = end + len(substi) + len(substj) - (end - bend) - (blay - i) - 2
1249 add_to_preamble(document, "\\usepackage{tipa}")
1252 def revert_ipachar(document):
1253 ' Revert \\IPAChar to ERT '
1256 while i < len(document.body):
1257 m = re.match(r'(.*)\\IPAChar \\(\w+\{\w+\})(.*)', document.body[i])
1261 ipachar = m.group(2)
1264 '\\begin_inset ERT',
1265 'status collapsed', '',
1266 '\\begin_layout Standard',
1267 '', '', '\\backslash',
1272 document.body[i: i+1] = subst
1277 add_to_preamble(document, "\\usepackage{tone}")
1280 def revert_minionpro(document):
1281 " Revert native MinionPro font definition to LaTeX "
1283 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1284 i = find_token(document.header, "\\font_roman minionpro", 0)
1287 j = find_token(document.header, "\\font_osf true", 0)
1290 preamble = "\\usepackage"
1292 document.header[j] = "\\font_osf false"
1295 preamble += "{MinionPro}"
1296 add_to_preamble(document, [preamble])
1297 document.header[i] = "\\font_roman default"
1300 def revert_mathfonts(document):
1301 " Revert native math font definitions to LaTeX "
1303 i = find_token(document.header, "\\font_math", 0)
1306 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1307 val = get_value(document.header, "\\font_math", i)
1308 if val == "eulervm":
1309 add_to_preamble(document, "\\usepackage{eulervm}")
1310 elif val == "default":
1312 "lmodern": "\\renewcommand{\\rmdefault}{lmr}",
1313 "minionpro": "\\usepackage[onlytext,lf]{MinionPro}",
1314 "minionpro-osf": "\\usepackage[onlytext]{MinionPro}",
1315 "palatino": "\\renewcommand{\\rmdefault}{ppl}",
1316 "palatino-osf": "\\renewcommand{\\rmdefault}{pplj}",
1317 "times": "\\renewcommand{\\rmdefault}{ptm}",
1318 "utopia": "\\renewcommand{\\rmdefault}{futs}",
1319 "utopia-osf": "\\renewcommand{\\rmdefault}{futj}",
1321 j = find_token(document.header, "\\font_roman", 0)
1323 rm = get_value(document.header, "\\font_roman", j)
1324 k = find_token(document.header, "\\font_osf true", 0)
1327 if rm in mathfont_dict.keys():
1328 add_to_preamble(document, mathfont_dict[rm])
1329 document.header[j] = "\\font_roman default"
1331 document.header[k] = "\\font_osf false"
1332 del document.header[i]
1335 def revert_mdnomath(document):
1336 " Revert mathdesign and fourier without math "
1338 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1340 "md-charter": "mdbch",
1341 "md-utopia": "mdput",
1342 "md-garamond": "mdugm"
1344 i = find_token(document.header, "\\font_roman", 0)
1347 val = get_value(document.header, "\\font_roman", i)
1348 if val in mathdesign_dict.keys():
1349 j = find_token(document.header, "\\font_math", 0)
1351 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1352 mval = get_value(document.header, "\\font_math", j)
1353 if mval == "default":
1354 document.header[i] = "\\font_roman default"
1355 add_to_preamble(document, "\\renewcommand{\\rmdefault}{%s}" % mathdesign_dict[val])
1357 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1360 def convert_mdnomath(document):
1361 " Change mathdesign font name "
1363 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1365 "mdbch": "md-charter",
1366 "mdput": "md-utopia",
1367 "mdugm": "md-garamond"
1369 i = find_token(document.header, "\\font_roman", 0)
1372 val = get_value(document.header, "\\font_roman", i)
1373 if val in mathdesign_dict.keys():
1374 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1377 def revert_newtxmath(document):
1378 " Revert native newtxmath definitions to LaTeX "
1380 i = find_token(document.header, "\\font_math", 0)
1383 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1384 val = get_value(document.header, "\\font_math", i)
1386 "libertine-ntxm": "\\usepackage[libertine]{newtxmath}",
1387 "minion-ntxm": "\\usepackage[minion]{newtxmath}",
1388 "newtxmath": "\\usepackage{newtxmath}",
1390 if val in mathfont_dict.keys():
1391 add_to_preamble(document, mathfont_dict[val])
1392 document.header[i] = "\\font_math auto"
1395 def revert_biolinum(document):
1396 " Revert native biolinum font definition to LaTeX "
1398 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1399 i = find_token(document.header, "\\font_sans biolinum", 0)
1402 j = find_token(document.header, "\\font_osf true", 0)
1405 preamble = "\\usepackage"
1408 preamble += "{biolinum-type1}"
1409 add_to_preamble(document, [preamble])
1410 document.header[i] = "\\font_sans default"
1413 def revert_uop(document):
1414 " Revert native URW Classico (Optima) font definition to LaTeX "
1416 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1417 i = find_token(document.header, "\\font_sans uop", 0)
1419 preamble = "\\renewcommand{\\sfdefault}{uop}"
1420 add_to_preamble(document, [preamble])
1421 document.header[i] = "\\font_sans default"
1424 def convert_latexargs(document):
1425 " Convert InsetArgument to new syntax "
1427 if find_token(document.body, "\\begin_inset Argument", 0) == -1:
1431 # A list of layouts (document classes) with only optional or no arguments.
1432 # These can be safely converted to the new syntax
1433 # (I took the liberty to add some of my personal layouts/modules here; JSP)
1434 safe_layouts = ["aa", "aapaper", "aastex", "achemso", "acmsiggraph", "AEA",
1435 "agu-dtd", "agums", "agutex", "amsart", "amsbook", "apa",
1436 "arab-article", "armenian-article", "article-beamer", "article",
1437 "beamer", "book", "broadway", "chess", "cl2emult", "ctex-article",
1438 "ctex-book", "ctex-report", "dinbrief", "docbook-book", "docbook-chapter",
1439 "docbook", "docbook-section", "doublecol-new", "dtk", "ectaart", "egs",
1440 "elsarticle", "elsart", "entcs", "europecv", "extarticle", "extbook",
1441 "extletter", "extreport", "foils", "frletter", "g-brief2", "g-brief",
1442 "heb-article", "heb-letter", "hollywood", "IEEEtran", "ijmpc", "ijmpd",
1443 "iopart", "isprs", "jarticle", "jasatex", "jbook", "jgrga", "jreport",
1444 "jsarticle", "jsbeamer", "jsbook", "jss", "kluwer", "latex8", "letter", "lettre",
1445 "literate-article", "literate-book", "literate-report", "llncs", "ltugboat",
1446 "memoir", "moderncv", "mwart", "mwbk", "mwrep", "paper", "powerdot",
1447 "recipebook", "report", "revtex4", "revtex", "scrartcl", "scrarticle-beamer",
1448 "scrbook", "scrlettr", "scrlttr2", "scrreprt", "seminar", "siamltex",
1449 "sigplanconf", "simplecv", "singlecol", "singlecol-new", "slides", "spie",
1450 "svglobal3", "svglobal", "svjog", "svmono", "svmult", "svprobth", "tarticle",
1451 "tbook", "treport", "tufte-book", "tufte-handout"]
1452 # A list of "safe" modules, same as above
1453 safe_modules = ["biblatex", "beameraddons", "beamersession", "braille", "customHeadersFooters",
1454 "endnotes", "enumitem", "eqs-within-sections", "figs-within-sections", "fix-cm",
1455 "fixltx2e", "foottoend", "hanging", "jscharstyles", "knitr", "lilypond",
1456 "linguistics", "linguisticx", "logicalmkup", "minimalistic", "nomindex", "noweb",
1457 "pdfcomment", "sweave", "tabs-within-sections", "theorems-ams-bytype",
1458 "theorems-ams-extended-bytype", "theorems-ams-extended", "theorems-ams", "theorems-bytype",
1459 "theorems-chap-bytype", "theorems-chap", "theorems-named", "theorems-sec-bytype",
1460 "theorems-sec", "theorems-starred", "theorems-std", "todonotes"]
1461 # Modules we need to take care of
1462 caveat_modules = ["initials"]
1463 # information about the relevant styles in caveat_modules (number of opt and req args)
1464 # use this if we get more caveat_modules. For now, use hard coding (see below).
1465 # initials = [{'Layout' : 'Initial', 'opt' : 1, 'req' : 1}]
1467 # Is this a known safe layout?
1468 safe_layout = document.textclass in safe_layouts
1470 document.warning("Lyx2lyx knows nothing about textclass '%s'. "
1471 "Please check if short title insets have been converted correctly."
1472 % document.textclass)
1473 # Do we use unsafe or unknown modules
1474 mods = document.get_module_list()
1475 unknown_modules = False
1476 used_caveat_modules = list()
1478 if mod in safe_modules:
1480 if mod in caveat_modules:
1481 used_caveat_modules.append(mod)
1483 unknown_modules = True
1484 document.warning("Lyx2lyx knows nothing about module '%s'. "
1485 "Please check if short title insets have been converted correctly."
1490 i = find_token(document.body, "\\begin_inset Argument", i)
1494 if not safe_layout or unknown_modules:
1495 # We cannot do more here since we have no access to this layout.
1496 # InsetArgument itself will do the real work
1497 # (see InsetArgument::updateBuffer())
1498 document.body[i] = "\\begin_inset Argument 999"
1502 # Find containing paragraph layout
1503 parent = get_containing_layout(document.body, i)
1505 document.warning("Malformed LyX document: Can't find parent paragraph layout")
1512 if len(used_caveat_modules) > 0:
1513 # We know for now that this must be the initials module with the Initial layout
1514 # If we get more such modules, we need some automating.
1515 if parent[0] == "Initial":
1516 # Layout has 1 opt and 1 req arg.
1517 # Count the actual arguments
1519 for p in range(parbeg, parend):
1520 if document.body[p] == "\\begin_inset Argument":
1525 # Collect all arguments in this paragraph
1527 for p in range(parbeg, parend):
1528 if document.body[p] == "\\begin_inset Argument":
1530 if allowed_opts != -1:
1531 # We have less arguments than opt + required.
1532 # required must take precedence.
1533 if argnr > allowed_opts and argnr < first_req:
1535 document.body[p] = "\\begin_inset Argument %d" % argnr
1539 def revert_latexargs(document):
1540 " Revert InsetArgument to old syntax "
1543 rx = re.compile(r'^\\begin_inset Argument (\d+)$')
1546 # Search for Argument insets
1547 i = find_token(document.body, "\\begin_inset Argument", i)
1550 m = rx.match(document.body[i])
1552 # No ID: inset already reverted
1555 # Find containing paragraph layout
1556 parent = get_containing_layout(document.body, i)
1558 document.warning("Malformed LyX document: Can't find parent paragraph layout")
1563 # Do not set realparbeg to parent[3], since this does not work if we
1564 # have another inset (e.g. label or index) before the first argument
1565 # inset (this is the case in the user guide of LyX 2.0.8)
1567 # Collect all arguments in this paragraph
1569 for p in range(parbeg, parend):
1570 m = rx.match(document.body[p])
1573 # This is the first argument inset
1575 val = int(m.group(1))
1576 j = find_end_of_inset(document.body, p)
1577 # Revert to old syntax
1578 document.body[p] = "\\begin_inset Argument"
1580 document.warning("Malformed LyX document: Can't find end of Argument inset")
1583 args[val] = document.body[p : j + 1]
1585 realparend = realparend - len(document.body[p : j + 1])
1586 # Remove arg inset at this position
1587 del document.body[p : j + 1]
1591 # No argument inset found
1592 realparbeg = parent[3]
1593 # Now sort the arg insets
1595 for f in sorted(args):
1598 # Insert the sorted arg insets at paragraph begin
1599 document.body[realparbeg : realparbeg] = subst
1601 i = realparbeg + 1 + len(subst)
1604 def revert_IEEEtran(document):
1606 Reverts InsetArgument of
1609 Biography without photo
1612 if document.textclass == "IEEEtran":
1619 i = find_token(document.body, "\\begin_layout Page headings", i)
1621 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1624 i2 = find_token(document.body, "\\begin_inset Flex Paragraph Start", i2)
1626 revert_Argument_to_TeX_brace(document, i2, 0, 1, 1, False, False)
1629 j = find_token(document.body, "\\begin_layout Biography without photo", j)
1631 revert_Argument_to_TeX_brace(document, j, 0, 1, 1, True, False)
1634 k = find_token(document.body, "\\begin_layout Biography", k)
1635 kA = find_token(document.body, "\\begin_layout Biography without photo", k)
1636 if k == kA and k != -1:
1640 # start with the second argument, therefore 2
1641 revert_Argument_to_TeX_brace(document, k, 0, 2, 2, True, False)
1643 if i == -1 and i2 == -1 and j == -1 and k == -1:
1647 def revert_IEEEtran_2(document):
1649 Reverts Flex Paragraph Start to TeX-code
1651 if document.textclass == "IEEEtran":
1654 begin = find_token(document.body, "\\begin_inset Flex Paragraph Start", begin)
1657 end1 = find_end_of_inset(document.body, begin)
1658 document.body[end1 - 2 : end1 + 1] = put_cmd_in_ert("}")
1659 document.body[begin : begin + 4] = put_cmd_in_ert("\\IEEEPARstart{")
1663 def convert_IEEEtran(document):
1668 Biography without photo
1671 if document.textclass == "IEEEtran":
1677 i = find_token(document.body, "\\begin_layout Page headings", i)
1679 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
1682 j = find_token(document.body, "\\begin_layout Biography without photo", j)
1684 convert_TeX_brace_to_Argument(document, j, 1, 1, False, True, False)
1687 # assure that we don't handle Biography Biography without photo
1688 k = find_token(document.body, "\\begin_layout Biography", k)
1689 kA = find_token(document.body, "\\begin_layout Biography without photo", k - 1)
1690 if k == kA and k != -1:
1694 # the argument we want to convert is the second one
1695 convert_TeX_brace_to_Argument(document, k, 2, 2, False, True, False)
1697 if i == -1 and j == -1 and k == -1:
1701 def revert_AASTeX(document):
1702 " Reverts InsetArgument of Altaffilation to TeX-code "
1703 if document.textclass == "aastex":
1706 i = find_token(document.body, "\\begin_layout Altaffilation", i)
1709 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1713 def convert_AASTeX(document):
1714 " Converts ERT of Altaffilation to InsetArgument "
1715 if document.textclass == "aastex":
1718 i = find_token(document.body, "\\begin_layout Altaffilation", i)
1721 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
1725 def revert_AGUTeX(document):
1726 " Reverts InsetArgument of Author affiliation to TeX-code "
1727 if document.textclass == "agutex":
1730 i = find_token(document.body, "\\begin_layout Author affiliation", i)
1733 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1737 def convert_AGUTeX(document):
1738 " Converts ERT of Author affiliation to InsetArgument "
1739 if document.textclass == "agutex":
1742 i = find_token(document.body, "\\begin_layout Author affiliation", i)
1745 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
1749 def revert_IJMP(document):
1750 " Reverts InsetArgument of MarkBoth to TeX-code "
1751 if document.textclass == "ijmpc" or document.textclass == "ijmpd":
1754 i = find_token(document.body, "\\begin_layout MarkBoth", i)
1757 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1761 def convert_IJMP(document):
1762 " Converts ERT of MarkBoth to InsetArgument "
1763 if document.textclass == "ijmpc" or document.textclass == "ijmpd":
1766 i = find_token(document.body, "\\begin_layout MarkBoth", i)
1769 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
1773 def revert_SIGPLAN(document):
1774 " Reverts InsetArguments of SIGPLAN to TeX-code "
1775 if document.textclass == "sigplanconf":
1780 i = find_token(document.body, "\\begin_layout Conference", i)
1782 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1785 j = find_token(document.body, "\\begin_layout Author", j)
1787 revert_Argument_to_TeX_brace(document, j, 0, 1, 2, False, False)
1789 if i == -1 and j == -1:
1793 def convert_SIGPLAN(document):
1794 " Converts ERT of SIGPLAN to InsetArgument "
1795 if document.textclass == "sigplanconf":
1800 i = find_token(document.body, "\\begin_layout Conference", i)
1802 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
1805 j = find_token(document.body, "\\begin_layout Author", j)
1807 convert_TeX_brace_to_Argument(document, j, 1, 2, False, False, False)
1809 if i == -1 and j == -1:
1813 def revert_SIGGRAPH(document):
1814 " Reverts InsetArgument of Flex CRcat to TeX-code "
1815 if document.textclass == "acmsiggraph":
1818 i = find_token(document.body, "\\begin_inset Flex CRcat", i)
1821 revert_Argument_to_TeX_brace(document, i, 0, 1, 3, False, False)
1825 def convert_SIGGRAPH(document):
1826 " Converts ERT of Flex CRcat to InsetArgument "
1827 if document.textclass == "acmsiggraph":
1830 i = find_token(document.body, "\\begin_inset Flex CRcat", i)
1833 convert_TeX_brace_to_Argument(document, i, 1, 3, True, False, False)
1837 def revert_EuropeCV(document):
1838 " Reverts InsetArguments of europeCV to TeX-code "
1839 if document.textclass == "europecv":
1846 i = find_token(document.body, "\\begin_layout Item", i)
1848 revert_Argument_to_TeX_brace(document, i, 0, 2, 2, False, False)
1851 j = find_token(document.body, "\\begin_layout BulletedItem", j)
1853 revert_Argument_to_TeX_brace(document, j, 0, 2, 2, False, False)
1856 k = find_token(document.body, "\\begin_layout Language", k)
1858 revert_Argument_to_TeX_brace(document, k, 0, 2, 6, False, False)
1861 m = find_token(document.body, "\\begin_layout LastLanguage", m)
1863 revert_Argument_to_TeX_brace(document, m, 0, 2, 6, False, False)
1865 if i == -1 and j == -1 and k == -1 and m == -1:
1869 def convert_EuropeCV(document):
1870 " Converts ERT of europeCV to InsetArgument "
1871 if document.textclass == "europecv":
1878 i = find_token(document.body, "\\begin_layout Item", i)
1880 convert_TeX_brace_to_Argument(document, i, 2, 2, False, False, False)
1883 j = find_token(document.body, "\\begin_layout BulletedItem", j)
1885 convert_TeX_brace_to_Argument(document, j, 2, 2, False, False, False)
1888 k = find_token(document.body, "\\begin_layout Language", k)
1890 convert_TeX_brace_to_Argument(document, k, 2, 6, False, False, False)
1893 m = find_token(document.body, "\\begin_layout LastLanguage", m)
1895 convert_TeX_brace_to_Argument(document, m, 2, 6, False, False, False)
1897 if i == -1 and j == -1 and k == -1 and m == -1:
1901 def revert_ModernCV(document):
1902 " Reverts InsetArguments of modernCV to TeX-code "
1903 if document.textclass == "moderncv":
1911 j = find_token(document.body, "\\begin_layout Entry", j)
1913 revert_Argument_to_TeX_brace(document, j, 0, 1, 5, False, False)
1916 k = find_token(document.body, "\\begin_layout Item", k)
1918 revert_Argument_to_TeX_brace(document, k, 0, 1, 1, False, False)
1921 m = find_token(document.body, "\\begin_layout ItemWithComment", m)
1923 revert_Argument_to_TeX_brace(document, m, 0, 1, 2, False, False)
1924 document.body[m] = document.body[m].replace("\\begin_layout ItemWithComment", "\\begin_layout Language")
1927 o = find_token(document.body, "\\begin_layout DoubleItem", o)
1929 revert_Argument_to_TeX_brace(document, o, 0, 1, 3, False, False)
1930 document.body[o] = document.body[o].replace("\\begin_layout DoubleItem", "\\begin_layout Computer")
1933 p = find_token(document.body, "\\begin_layout Social", p)
1935 revert_Argument_to_TeX_brace(document, p, 0, 1, 1, False, True)
1937 if j == -1 and k == -1 and m == -1 and o == -1 and p == -1:
1941 def revert_ModernCV_2(document):
1942 " Reverts the Flex:Column inset of modernCV to TeX-code "
1943 if document.textclass == "moderncv":
1947 flex = find_token(document.body, "\\begin_inset Flex Column", flex)
1950 flexEnd = find_end_of_inset(document.body, flex)
1951 wasOpt = revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, False, True)
1952 revert_Argument_to_TeX_brace(document, flex, 0, 2, 2, False, False)
1953 flexEnd = find_end_of_inset(document.body, flex)
1955 document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\cvcolumn")
1957 document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\cvcolumn{")
1958 document.body[flexEnd + 4 : flexEnd + 7] = put_cmd_in_ert("}")
1962 def revert_ModernCV_3(document):
1963 " Reverts the Column style of modernCV to TeX-code "
1964 if document.textclass == "moderncv":
1965 # revert the layouts
1966 revert_ModernCV(document)
1968 # get the position of the end of the last column inset
1969 LastFlexEnd = revert_ModernCV_2(document)
1971 p = find_token(document.body, "\\begin_layout Columns", p)
1974 pEnd = find_end_of_layout(document.body, p)
1975 document.body[p] = document.body[p].replace("\\begin_layout Columns", "\\begin_layout Standard")
1976 if LastFlexEnd != -1:
1977 document.body[p + 1 : p + 1] = put_cmd_in_ert("\\begin{cvcolumns}")
1978 document.body[LastFlexEnd + 24 : LastFlexEnd + 24] = put_cmd_in_ert("\\end{cvcolumns}")
1982 def revert_ModernCV_4(document):
1983 " Reverts the style Social to TeX-code "
1984 if document.textclass == "moderncv":
1985 # revert the layouts
1986 revert_ModernCV(document)
1989 p = find_token(document.body, "\\begin_layout Social", p)
1992 pEnd = find_end_of_layout(document.body, p)
1993 document.body[p] = document.body[p].replace("\\begin_layout Social", "\\begin_layout Standard")
1994 document.body[p + 1 : p + 1] = put_cmd_in_ert("\\social")
1995 hasOpt = find_token(document.body, "[", p + 9)
1997 document.body[p + 30 : p + 30] = put_cmd_in_ert("{")
1998 document.body[p + 41 : p + 41] = put_cmd_in_ert("}")
2000 document.body[p + 11 : p + 11] = put_cmd_in_ert("{")
2001 document.body[p + 21 : p + 21] = put_cmd_in_ert("}")
2005 def convert_ModernCV(document):
2006 " Converts ERT of modernCV to InsetArgument "
2007 if document.textclass == "moderncv":
2015 i = find_token(document.body, "\\begin_layout DoubleItem", i)
2017 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
2018 document.body[o] = document.body[o].replace("\\begin_layout DoubleItem", "\\begin_layout DoubleListItem")
2021 j = find_token(document.body, "\\begin_layout Entry", j)
2023 convert_TeX_brace_to_Argument(document, j, 1, 5, False, False, False)
2026 k = find_token(document.body, "\\begin_layout Item", k)
2028 convert_TeX_brace_to_Argument(document, k, 1, 1, False, False, False)
2031 m = find_token(document.body, "\\begin_layout Language", m)
2033 convert_TeX_brace_to_Argument(document, m, 1, 2, False, False, False)
2035 if i == -1 and j == -1 and k == -1 and m == -1:
2039 def revert_Initials(document):
2040 " Reverts InsetArgument of Initial to TeX-code "
2043 i = find_token(document.body, "\\begin_layout Initial", i)
2046 # first arg (optional) and second arg (first mandatory) are supported in LyX 2.0.x
2047 revert_Argument_to_TeX_brace(document, i, 0, 3, 3, False, False)
2051 def convert_Initials(document):
2052 " Converts ERT of Initial to InsetArgument "
2055 i = find_token(document.body, "\\begin_layout Initial", i)
2058 convert_TeX_brace_to_Argument(document, i, 3, 3, False, False, False)
2062 def revert_literate(document):
2063 " Revert Literate document to old format "
2064 if del_token(document.header, "noweb", 0):
2065 document.textclass = "literate-" + document.textclass
2068 i = find_token(document.body, "\\begin_layout Chunk", i)
2071 document.body[i] = "\\begin_layout Scrap"
2075 def convert_literate(document):
2076 " Convert Literate document to new format"
2077 i = find_token(document.header, "\\textclass", 0)
2078 if (i != -1) and "literate-" in document.header[i]:
2079 document.textclass = document.header[i].replace("\\textclass literate-", "")
2080 j = find_token(document.header, "\\begin_modules", 0)
2082 document.header.insert(j + 1, "noweb")
2084 document.header.insert(i + 1, "\\end_modules")
2085 document.header.insert(i + 1, "noweb")
2086 document.header.insert(i + 1, "\\begin_modules")
2089 i = find_token(document.body, "\\begin_layout Scrap", i)
2092 document.body[i] = "\\begin_layout Chunk"
2096 def revert_itemargs(document):
2097 " Reverts \\item arguments to TeX-code "
2100 i = find_token(document.body, "\\begin_inset Argument item:", i)
2103 j = find_end_of_inset(document.body, i)
2104 # Find containing paragraph layout
2105 parent = get_containing_layout(document.body, i)
2107 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2111 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2112 endPlain = find_end_of_layout(document.body, beginPlain)
2113 content = document.body[beginPlain + 1 : endPlain]
2114 del document.body[i:j+1]
2115 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2116 document.body[parbeg : parbeg] = subst
2120 def revert_garamondx_newtxmath(document):
2121 " Revert native garamond newtxmath definition to LaTeX "
2123 i = find_token(document.header, "\\font_math", 0)
2126 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
2127 val = get_value(document.header, "\\font_math", i)
2128 if val == "garamondx-ntxm":
2129 add_to_preamble(document, "\\usepackage[garamondx]{newtxmath}")
2130 document.header[i] = "\\font_math auto"
2133 def revert_garamondx(document):
2134 " Revert native garamond font definition to LaTeX "
2136 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
2137 i = find_token(document.header, "\\font_roman garamondx", 0)
2140 j = find_token(document.header, "\\font_osf true", 0)
2143 preamble = "\\usepackage"
2145 preamble += "[osfI]"
2146 preamble += "{garamondx}"
2147 add_to_preamble(document, [preamble])
2148 document.header[i] = "\\font_roman default"
2151 def convert_beamerargs(document):
2152 " Converts beamer arguments to new layout "
2154 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2155 if document.textclass not in beamer_classes:
2158 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
2159 list_layouts = ["Itemize", "Enumerate", "Description"]
2160 rx = re.compile(r'^\\begin_inset Argument (\d+)$')
2164 i = find_token(document.body, "\\begin_inset Argument", i)
2167 # Find containing paragraph layout
2168 parent = get_containing_layout(document.body, i)
2170 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2175 layoutname = parent[0]
2176 for p in range(parbeg, parend):
2177 if layoutname in shifted_layouts:
2178 m = rx.match(document.body[p])
2180 argnr = int(m.group(1))
2182 document.body[p] = "\\begin_inset Argument %d" % argnr
2183 if layoutname == "AgainFrame":
2184 m = rx.match(document.body[p])
2186 document.body[p] = "\\begin_inset Argument 3"
2187 if document.body[p + 4] == "\\begin_inset ERT":
2188 if document.body[p + 9].startswith("<"):
2189 # This is an overlay specification
2191 document.body[p + 9] = document.body[p + 9][1:]
2192 if document.body[p + 9].endswith(">"):
2194 document.body[p + 9] = document.body[p + 9][:-1]
2196 document.body[p] = "\\begin_inset Argument 2"
2197 if layoutname in list_layouts:
2198 m = rx.match(document.body[p])
2200 if m.group(1) == "1":
2201 if document.body[p + 4] == "\\begin_inset ERT":
2202 if document.body[p + 9].startswith("<"):
2203 # This is an overlay specification
2205 document.body[p + 9] = document.body[p + 9][1:]
2206 if document.body[p + 9].endswith(">"):
2208 document.body[p + 9] = document.body[p + 9][:-1]
2209 elif document.body[p + 4].startswith("<"):
2210 # This is an overlay specification (without ERT)
2212 document.body[p + 4] = document.body[p + 4][1:]
2213 if document.body[p + 4].endswith(">"):
2215 document.body[p + 4] = document.body[p + 4][:-1]
2216 elif layoutname != "Itemize":
2218 document.body[p] = "\\begin_inset Argument 2"
2223 # Helper function for the frame conversion routines
2225 # FIXME: This method currently requires the arguments to be either
2226 # * In one (whole) ERT each: <ERT>[<arg1>]</ERT><ERT><arg2></ERT><ERT>[arg3]</ERT>
2227 # * Altogether in one whole ERT: <ERT>[<arg1>]<arg2>[arg3]</ERT>
2228 # If individual arguments mix ERT and non-ERT or are splitted
2229 # over several ERTs, the parsing fails.
2230 def convert_beamerframeargs(document, i, parbeg):
2233 if document.body[parbeg] != "\\begin_inset ERT":
2235 ertend = find_end_of_inset(document.body, parbeg)
2237 document.warning("Malformed LyX document: missing ERT \\end_inset")
2239 ertcont = parbeg + 5
2240 if document.body[ertcont].startswith("[<"):
2241 # This is a default overlay specification
2243 document.body[ertcont] = document.body[ertcont][2:]
2244 if document.body[ertcont].endswith(">]"):
2246 document.body[ertcont] = document.body[ertcont][:-2]
2247 elif document.body[ertcont].endswith("]"):
2249 tok = document.body[ertcont].find('>][')
2251 subst = [document.body[ertcont][:tok],
2252 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2253 'status collapsed', '', '\\begin_layout Plain Layout',
2254 document.body[ertcont][tok + 3:-1]]
2255 document.body[ertcont : ertcont + 1] = subst
2257 # Convert to ArgInset
2258 document.body[parbeg] = "\\begin_inset Argument 2"
2259 elif document.body[ertcont].startswith("<"):
2260 # This is an overlay specification
2262 document.body[ertcont] = document.body[ertcont][1:]
2263 if document.body[ertcont].endswith(">"):
2265 document.body[ertcont] = document.body[ertcont][:-1]
2266 # Convert to ArgInset
2267 document.body[parbeg] = "\\begin_inset Argument 1"
2268 elif document.body[ertcont].endswith(">]"):
2270 tok = document.body[ertcont].find('>[<')
2272 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2273 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2274 'status collapsed', '', '\\begin_layout Plain Layout',
2275 document.body[ertcont][tok + 3:-2]]
2276 # Convert to ArgInset
2277 document.body[parbeg] = "\\begin_inset Argument 1"
2279 elif document.body[ertcont].endswith("]"):
2281 tok = document.body[ertcont].find('>[<')
2284 tokk = document.body[ertcont].find('>][')
2286 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2287 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2288 'status collapsed', '', '\\begin_layout Plain Layout',
2289 document.body[ertcont][tok + 3:tokk],
2290 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2291 'status collapsed', '', '\\begin_layout Plain Layout',
2292 document.body[ertcont][tokk + 3:-1]]
2295 tokk = document.body[ertcont].find('>[')
2297 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tokk],
2298 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2299 'status collapsed', '', '\\begin_layout Plain Layout',
2300 document.body[ertcont][tokk + 2:-1]]
2302 # Convert to ArgInset
2303 document.body[parbeg] = "\\begin_inset Argument 1"
2304 elif document.body[ertcont].startswith("["):
2305 # This is an ERT option
2307 document.body[ertcont] = document.body[ertcont][1:]
2308 if document.body[ertcont].endswith("]"):
2310 document.body[ertcont] = document.body[ertcont][:-1]
2311 # Convert to ArgInset
2312 document.body[parbeg] = "\\begin_inset Argument 3"
2318 def convert_againframe_args(document):
2319 " Converts beamer AgainFrame to new layout "
2321 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2322 if document.textclass not in beamer_classes:
2327 i = find_token(document.body, "\\begin_layout AgainFrame", i)
2330 parent = get_containing_layout(document.body, i)
2332 document.warning("Wrong parent layout!")
2336 # Convert ERT arguments
2337 # FIXME: See restrictions in convert_beamerframeargs method
2338 ertend = convert_beamerframeargs(document, i, parbeg)
2344 def convert_corollary_args(document):
2345 " Converts beamer corrolary-style ERT arguments native InsetArgs "
2347 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2348 if document.textclass not in beamer_classes:
2351 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2352 for lay in corollary_layouts:
2355 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2358 parent = get_containing_layout(document.body, i)
2360 document.warning("Wrong parent layout!")
2364 if document.body[parbeg] == "\\begin_inset ERT":
2365 ertcont = parbeg + 5
2366 if document.body[ertcont].startswith("<"):
2367 # This is an overlay specification
2369 document.body[ertcont] = document.body[ertcont][1:]
2370 if document.body[ertcont].endswith(">"):
2372 document.body[ertcont] = document.body[ertcont][:-1]
2373 elif document.body[ertcont].endswith("]"):
2375 tok = document.body[ertcont].find('>[')
2377 subst = [document.body[ertcont][:tok],
2378 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2379 'status collapsed', '', '\\begin_layout Plain Layout',
2380 document.body[ertcont][tok + 2:-1]]
2381 document.body[ertcont : ertcont + 1] = subst
2382 # Convert to ArgInset
2383 document.body[parbeg] = "\\begin_inset Argument 1"
2386 elif document.body[ertcont].startswith("["):
2387 if document.body[ertcont].endswith("]"):
2388 # This is an ERT option
2390 document.body[ertcont] = document.body[ertcont][1:]
2392 document.body[ertcont] = document.body[ertcont][:-1]
2393 # Convert to ArgInset
2394 document.body[parbeg] = "\\begin_inset Argument 2"
2396 convert_TeX_brace_to_Argument(document, i, 2, 2, False, True, True)
2403 def convert_quote_args(document):
2404 " Converts beamer quote style ERT args to native InsetArgs "
2406 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2407 if document.textclass not in beamer_classes:
2410 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2411 for lay in quote_layouts:
2414 i = find_token(document.body, "\\begin_layout " + lay, i)
2417 parent = get_containing_layout(document.body, i)
2419 document.warning("Wrong parent layout!")
2423 if document.body[parbeg] == "\\begin_inset ERT":
2424 if document.body[i + 6].startswith("<"):
2425 # This is an overlay specification
2427 document.body[i + 6] = document.body[i + 6][1:]
2428 if document.body[i + 6].endswith(">"):
2430 document.body[i + 6] = document.body[i + 6][:-1]
2431 # Convert to ArgInset
2432 document.body[i + 1] = "\\begin_inset Argument 1"
2436 def revert_beamerargs(document):
2437 " Reverts beamer arguments to old layout "
2439 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2440 if document.textclass not in beamer_classes:
2444 list_layouts = ["Itemize", "Enumerate", "Description"]
2445 headings = ["Part", "Section", "Section*", "Subsection", "Subsection*",
2446 "Subsubsection", "Subsubsection*", "FrameSubtitle", "NoteItem"]
2447 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2448 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2449 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2452 i = find_token(document.body, "\\begin_inset Argument", i)
2455 # Find containing paragraph layout
2456 parent = get_containing_layout(document.body, i)
2458 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2463 realparbeg = parent[3]
2464 layoutname = parent[0]
2466 for p in range(parbeg, parend):
2470 if layoutname in headings:
2471 m = rx.match(document.body[p])
2475 # Find containing paragraph layout
2476 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2477 endPlain = find_end_of_layout(document.body, beginPlain)
2478 endInset = find_end_of_inset(document.body, p)
2479 argcontent = document.body[beginPlain + 1 : endPlain]
2481 realparend = realparend - len(document.body[p : endInset + 1])
2483 del document.body[p : endInset + 1]
2484 if layoutname == "FrameSubtitle":
2485 pre = put_cmd_in_ert("\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2486 elif layoutname == "NoteItem":
2487 pre = put_cmd_in_ert("\\note<") + argcontent + put_cmd_in_ert(">[item]")
2488 elif layoutname.endswith('*'):
2489 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower()[:-1] + "<") + argcontent + put_cmd_in_ert(">*")
2491 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2492 secarg = find_token(document.body, "\\begin_inset Argument 2", parbeg, parend)
2494 # Find containing paragraph layout
2495 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", secarg)
2496 endPlain = find_end_of_layout(document.body, beginPlain)
2497 endInset = find_end_of_inset(document.body, secarg)
2498 argcontent = document.body[beginPlain + 1 : endPlain]
2500 realparend = realparend - len(document.body[secarg : endInset + 1])
2501 del document.body[secarg : endInset + 1]
2502 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2503 pre += put_cmd_in_ert("{")
2504 document.body[parbeg] = "\\begin_layout Standard"
2505 document.body[realparbeg : realparbeg] = pre
2506 pe = find_end_of_layout(document.body, parbeg)
2507 post = put_cmd_in_ert("}")
2508 document.body[pe : pe] = post
2509 realparend += len(pre) + len(post)
2510 if layoutname == "AgainFrame":
2511 m = rx.match(document.body[p])
2515 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2516 endPlain = find_end_of_layout(document.body, beginPlain)
2517 endInset = find_end_of_inset(document.body, p)
2518 content = document.body[beginPlain + 1 : endPlain]
2520 realparend = realparend - len(document.body[p : endInset + 1])
2522 del document.body[p : endInset + 1]
2523 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2524 document.body[realparbeg : realparbeg] = subst
2525 if layoutname == "Overprint":
2526 m = rx.match(document.body[p])
2530 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2531 endPlain = find_end_of_layout(document.body, beginPlain)
2532 endInset = find_end_of_inset(document.body, p)
2533 content = document.body[beginPlain + 1 : endPlain]
2535 realparend = realparend - len(document.body[p : endInset + 1])
2537 del document.body[p : endInset + 1]
2538 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2539 document.body[realparbeg : realparbeg] = subst
2540 if layoutname == "OverlayArea":
2541 m = rx.match(document.body[p])
2545 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2546 endPlain = find_end_of_layout(document.body, beginPlain)
2547 endInset = find_end_of_inset(document.body, p)
2548 content = document.body[beginPlain + 1 : endPlain]
2550 realparend = realparend - len(document.body[p : endInset + 1])
2552 del document.body[p : endInset + 1]
2553 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2554 document.body[realparbeg : realparbeg] = subst
2555 if layoutname in list_layouts:
2556 m = rx.match(document.body[p])
2560 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2561 endPlain = find_end_of_layout(document.body, beginPlain)
2562 endInset = find_end_of_inset(document.body, p)
2563 content = document.body[beginPlain + 1 : endPlain]
2564 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2565 realparend = realparend + len(subst) - len(content)
2566 document.body[beginPlain + 1 : endPlain] = subst
2567 elif argnr == "item:1":
2568 j = find_end_of_inset(document.body, i)
2569 # Find containing paragraph layout
2570 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2571 endPlain = find_end_of_layout(document.body, beginPlain)
2572 content = document.body[beginPlain + 1 : endPlain]
2573 del document.body[i:j+1]
2574 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2575 document.body[realparbeg : realparbeg] = subst
2576 elif argnr == "item:2":
2577 j = find_end_of_inset(document.body, i)
2578 # Find containing paragraph layout
2579 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2580 endPlain = find_end_of_layout(document.body, beginPlain)
2581 content = document.body[beginPlain + 1 : endPlain]
2582 del document.body[i:j+1]
2583 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2584 document.body[realparbeg : realparbeg] = subst
2585 if layoutname in quote_layouts:
2586 m = rx.match(document.body[p])
2590 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2591 endPlain = find_end_of_layout(document.body, beginPlain)
2592 endInset = find_end_of_inset(document.body, p)
2593 content = document.body[beginPlain + 1 : endPlain]
2595 realparend = realparend - len(document.body[p : endInset + 1])
2597 del document.body[p : endInset + 1]
2598 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2599 document.body[realparbeg : realparbeg] = subst
2600 if layoutname in corollary_layouts:
2601 m = rx.match(document.body[p])
2605 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2606 endPlain = find_end_of_layout(document.body, beginPlain)
2607 endInset = find_end_of_inset(document.body, p)
2608 content = document.body[beginPlain + 1 : endPlain]
2610 realparend = realparend - len(document.body[p : endInset + 1])
2612 del document.body[p : endInset + 1]
2613 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2614 document.body[realparbeg : realparbeg] = subst
2619 def revert_beamerargs2(document):
2620 " Reverts beamer arguments to old layout, step 2 "
2622 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2623 if document.textclass not in beamer_classes:
2627 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
2628 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2629 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2632 i = find_token(document.body, "\\begin_inset Argument", i)
2635 # Find containing paragraph layout
2636 parent = get_containing_layout(document.body, i)
2638 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2643 realparbeg = parent[3]
2644 layoutname = parent[0]
2646 for p in range(parbeg, parend):
2650 if layoutname in shifted_layouts:
2651 m = rx.match(document.body[p])
2655 document.body[p] = "\\begin_inset Argument 1"
2656 if layoutname in corollary_layouts:
2657 m = rx.match(document.body[p])
2661 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2662 endPlain = find_end_of_layout(document.body, beginPlain)
2663 endInset = find_end_of_inset(document.body, p)
2664 content = document.body[beginPlain + 1 : endPlain]
2666 realparend = realparend - len(document.body[p : endInset + 1])
2668 del document.body[p : endInset + 1]
2669 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2670 document.body[realparbeg : realparbeg] = subst
2671 if layoutname == "OverlayArea":
2672 m = rx.match(document.body[p])
2676 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2677 endPlain = find_end_of_layout(document.body, beginPlain)
2678 endInset = find_end_of_inset(document.body, p)
2679 content = document.body[beginPlain + 1 : endPlain]
2681 realparend = realparend - len(document.body[p : endInset + 1])
2683 del document.body[p : endInset + 1]
2684 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2685 document.body[realparbeg : realparbeg] = subst
2686 if layoutname == "AgainFrame":
2687 m = rx.match(document.body[p])
2691 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2692 endPlain = find_end_of_layout(document.body, beginPlain)
2693 endInset = find_end_of_inset(document.body, p)
2694 content = document.body[beginPlain + 1 : endPlain]
2696 realparend = realparend - len(document.body[p : endInset + 1])
2698 del document.body[p : endInset + 1]
2699 subst = put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
2700 document.body[realparbeg : realparbeg] = subst
2704 def revert_beamerargs3(document):
2705 " Reverts beamer arguments to old layout, step 3 "
2707 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2708 if document.textclass not in beamer_classes:
2711 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2714 i = find_token(document.body, "\\begin_inset Argument", i)
2717 # Find containing paragraph layout
2718 parent = get_containing_layout(document.body, i)
2720 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2725 realparbeg = parent[3]
2726 layoutname = parent[0]
2728 for p in range(parbeg, parend):
2732 if layoutname == "AgainFrame":
2733 m = rx.match(document.body[p])
2737 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2738 endPlain = find_end_of_layout(document.body, beginPlain)
2739 endInset = find_end_of_inset(document.body, p)
2740 content = document.body[beginPlain + 1 : endPlain]
2742 realparend = realparend - len(document.body[p : endInset + 1])
2744 del document.body[p : endInset + 1]
2745 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2746 document.body[realparbeg : realparbeg] = subst
2750 def revert_beamerflex(document):
2751 " Reverts beamer Flex insets "
2753 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2754 if document.textclass not in beamer_classes:
2757 new_flexes = {"Bold" : "\\textbf", "Emphasize" : "\\emph", "Only" : "\\only",
2758 "Uncover" : "\\uncover", "Visible" : "\\visible",
2759 "Invisible" : "\\invisible", "Alternative" : "\\alt",
2760 "Beamer_Note" : "\\note"}
2761 old_flexes = {"Alert" : "\\alert", "Structure" : "\\structure"}
2762 rx = re.compile(r'^\\begin_inset Flex (.+)$')
2766 i = find_token(document.body, "\\begin_inset Flex", i)
2769 m = rx.match(document.body[i])
2771 flextype = m.group(1)
2772 z = find_end_of_inset(document.body, i)
2774 document.warning("Can't find end of Flex " + flextype + " inset.")
2777 if flextype in new_flexes:
2778 pre = put_cmd_in_ert(new_flexes[flextype])
2779 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2781 argend = find_end_of_inset(document.body, arg)
2783 document.warning("Can't find end of Argument!")
2786 # Find containing paragraph layout
2787 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2788 endPlain = find_end_of_layout(document.body, beginPlain)
2789 argcontent = document.body[beginPlain + 1 : endPlain]
2791 z = z - len(document.body[arg : argend + 1])
2793 del document.body[arg : argend + 1]
2794 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2795 arg = find_token(document.body, "\\begin_inset Argument 2", i, z)
2797 argend = find_end_of_inset(document.body, arg)
2799 document.warning("Can't find end of Argument!")
2802 # Find containing paragraph layout
2803 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2804 endPlain = find_end_of_layout(document.body, beginPlain)
2805 argcontent = document.body[beginPlain + 1 : endPlain]
2807 z = z - len(document.body[arg : argend + 1])
2809 del document.body[arg : argend + 1]
2810 if flextype == "Alternative":
2811 pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
2813 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2814 pre += put_cmd_in_ert("{")
2815 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2816 endPlain = find_end_of_layout(document.body, beginPlain)
2818 z = z - len(document.body[i : beginPlain + 1])
2820 document.body[i : beginPlain + 1] = pre
2821 post = put_cmd_in_ert("}")
2822 document.body[z - 2 : z + 1] = post
2823 elif flextype in old_flexes:
2824 pre = put_cmd_in_ert(old_flexes[flextype])
2825 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2829 argend = find_end_of_inset(document.body, arg)
2831 document.warning("Can't find end of Argument!")
2834 # Find containing paragraph layout
2835 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2836 endPlain = find_end_of_layout(document.body, beginPlain)
2837 argcontent = document.body[beginPlain + 1 : endPlain]
2839 z = z - len(document.body[arg : argend + 1])
2841 del document.body[arg : argend + 1]
2842 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2843 pre += put_cmd_in_ert("{")
2844 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2845 endPlain = find_end_of_layout(document.body, beginPlain)
2847 z = z - len(document.body[i : beginPlain + 1])
2849 document.body[i : beginPlain + 1] = pre
2850 post = put_cmd_in_ert("}")
2851 document.body[z - 2 : z + 1] = post
2856 def revert_beamerblocks(document):
2857 " Reverts beamer block arguments to ERT "
2859 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2860 if document.textclass not in beamer_classes:
2863 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2865 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2868 i = find_token(document.body, "\\begin_inset Argument", i)
2871 # Find containing paragraph layout
2872 parent = get_containing_layout(document.body, i)
2874 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2879 realparbeg = parent[3]
2880 layoutname = parent[0]
2882 for p in range(parbeg, parend):
2886 if layoutname in blocks:
2887 m = rx.match(document.body[p])
2891 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2892 endPlain = find_end_of_layout(document.body, beginPlain)
2893 endInset = find_end_of_inset(document.body, p)
2894 content = document.body[beginPlain + 1 : endPlain]
2896 realparend = realparend - len(document.body[p : endInset + 1])
2898 del document.body[p : endInset + 1]
2899 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2900 document.body[realparbeg : realparbeg] = subst
2902 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2903 endPlain = find_end_of_layout(document.body, beginPlain)
2904 endInset = find_end_of_inset(document.body, p)
2905 content = document.body[beginPlain + 1 : endPlain]
2907 realparend = realparend - len(document.body[p : endInset + 1])
2909 del document.body[p : endInset + 1]
2910 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2911 document.body[realparbeg : realparbeg] = subst
2916 def convert_beamerblocks(document):
2917 " Converts beamer block ERT args to native InsetArgs "
2919 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2920 if document.textclass not in beamer_classes:
2923 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2927 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2930 parent = get_containing_layout(document.body, i)
2931 if parent == False or parent[1] != i:
2932 document.warning("Wrong parent layout!")
2939 if document.body[parbeg] == "\\begin_inset ERT":
2940 ertcontfirstline = parbeg + 5
2941 ertcontlastline = parend - 6
2943 if document.body[ertcontfirstline].startswith("<"):
2944 # This is an overlay specification
2946 document.body[ertcontfirstline] = document.body[ertcontfirstline][1:]
2947 if document.body[ertcontlastline].endswith(">"):
2949 document.body[ertcontlastline] = document.body[ertcontlastline][:-1]
2950 # Convert to ArgInset
2951 document.body[parbeg] = "\\begin_inset Argument 1"
2952 elif document.body[ertcontlastline].endswith("}"):
2954 document.body[ertcontlastline] = document.body[ertcontlastline][:-1]
2956 ertcontdivline = ertcontfirstline
2957 tok = document.body[ertcontdivline].find('>{')
2959 regexp = re.compile(r'.*>\{', re.IGNORECASE)
2960 ertcontdivline = find_re(document.body, regexp, ertcontfirstline, ertcontlastline)
2961 tok = document.body[ertcontdivline].find('>{')
2963 if ertcontfirstline < ertcontlastline:
2964 # Multiline ERT. Might contain TeX code. Embrace in ERT.
2965 document.body[ertcontlastline : ertcontlastline + 1] = [
2966 document.body[ertcontlastline], '\\end_layout', '', '\\end_inset']
2967 document.body[ertcontdivline : ertcontdivline + 1] = [document.body[ertcontdivline][:tok],
2968 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2969 'status collapsed', '', '\\begin_layout Plain Layout',
2970 '\\begin_inset ERT', '', 'status open' '', '\\begin_layout Plain Layout',
2971 document.body[ertcontdivline][tok + 2:]]
2973 document.body[ertcontdivline : ertcontdivline + 1] = [document.body[ertcontdivline][:tok],
2974 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2975 'status collapsed', '', '\\begin_layout Plain Layout',
2976 document.body[ertcontdivline][tok + 2:]]
2977 # Convert to ArgInset
2978 document.body[parbeg] = "\\begin_inset Argument 1"
2979 elif document.body[ertcontfirstline].startswith("{"):
2980 # This is the block title
2981 if document.body[ertcontlastline].endswith("}"):
2982 # strip off the braces
2983 document.body[ertcontfirstline] = document.body[ertcontfirstline][1:]
2984 document.body[ertcontlastline] = document.body[ertcontlastline][:-1]
2985 if ertcontfirstline < ertcontlastline:
2986 # Multiline ERT. Might contain TeX code. Embrace in ERT.
2987 document.body[parend : parend + 1] = [
2988 document.body[parend], '\\end_layout', '', '\\end_inset']
2989 document.body[parbeg : parbeg + 1] = ['\\begin_inset Argument 2',
2990 'status collapsed', '', '\\begin_layout Plain Layout',
2991 '\\begin_inset ERT', '']
2993 # Convert to ArgInset
2994 document.body[parbeg] = "\\begin_inset Argument 2"
2995 elif count_pars_in_inset(document.body, ertcontfirstline) > 1:
2996 # Multipar ERT. Skip this.
2999 convert_TeX_brace_to_Argument(document, i, 2, 2, False, True, False)
3002 j = find_end_of_layout(document.body, i)
3004 document.warning("end of layout not found!")
3005 k = find_token(document.body, "\\begin_inset Argument", i, j)
3007 document.warning("InsetArgument not found!")
3009 l = find_end_of_inset(document.body, k)
3010 m = find_token(document.body, "\\begin_inset ERT", l, j)
3013 ertcontfirstline = m + 5
3018 def convert_overprint(document):
3019 " Convert old beamer overprint layouts to ERT "
3021 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3022 if document.textclass not in beamer_classes:
3027 i = find_token(document.body, "\\begin_layout Overprint", i)
3030 # Find end of sequence
3031 j = find_end_of_sequence(document.body, i)
3033 document.warning("Malformed LyX document. Cannot find end of Overprint sequence!")
3037 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
3039 if document.body[j] == "\\end_deeper":
3040 esubst = ["", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
3042 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
3043 endseq = endseq + len(esubst) - len(document.body[j : j])
3044 document.body[j : j] = esubst
3045 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
3047 argend = find_end_of_layout(document.body, argbeg)
3049 document.warning("Malformed LyX document. Cannot find end of Overprint argument!")
3052 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3053 endPlain = find_end_of_layout(document.body, beginPlain)
3054 content = document.body[beginPlain + 1 : endPlain]
3056 endseq = endseq - len(document.body[argbeg : argend + 1])
3058 del document.body[argbeg : argend + 1]
3059 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3061 endseq = endseq - len(document.body[i : i])
3062 document.body[i : i] = subst + ["\\end_layout"]
3063 endseq += len(subst)
3065 for p in range(i, endseq):
3066 if document.body[p] == "\\begin_layout Overprint":
3067 document.body[p] = "\\begin_layout Standard"
3072 def revert_overprint(document):
3073 " Revert old beamer overprint layouts to ERT "
3075 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3076 if document.textclass not in beamer_classes:
3081 i = find_token(document.body, "\\begin_layout Overprint", i)
3084 # Find end of sequence
3085 j = find_end_of_sequence(document.body, i)
3087 document.warning("Malformed LyX document. Cannot find end of Overprint sequence!")
3091 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
3092 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}")
3093 endseq = endseq + len(esubst) - len(document.body[j : j])
3094 if document.body[j] == "\\end_deeper":
3095 document.body[j : j] = ["\\end_deeper", ""] + esubst
3097 document.body[j : j] = esubst
3100 if document.body[r] == "\\begin_deeper":
3101 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3103 document.body[r] = ""
3104 document.body[s] = ""
3108 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
3110 argend = find_end_of_inset(document.body, argbeg)
3112 document.warning("Malformed LyX document. Cannot find end of Overprint argument!")
3115 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3116 endPlain = find_end_of_layout(document.body, beginPlain)
3117 content = document.body[beginPlain + 1 : endPlain]
3119 endseq = endseq - len(document.body[argbeg : argend])
3121 del document.body[argbeg : argend + 1]
3122 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3124 endseq = endseq - len(document.body[i : i])
3125 document.body[i : i] = subst + ["\\end_layout"]
3126 endseq += len(subst)
3132 if document.body[p] == "\\begin_layout Overprint":
3133 q = find_end_of_layout(document.body, p)
3135 document.warning("Malformed LyX document. Cannot find end of Overprint layout!")
3138 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\onslide")
3139 argbeg = find_token(document.body, "\\begin_inset Argument item:1", p, q)
3141 argend = find_end_of_inset(document.body, argbeg)
3143 document.warning("Malformed LyX document. Cannot find end of Overprint item argument!")
3146 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3147 endPlain = find_end_of_layout(document.body, beginPlain)
3148 content = document.body[beginPlain + 1 : endPlain]
3150 endseq = endseq - len(document.body[argbeg : argend + 1])
3152 del document.body[argbeg : argend + 1]
3153 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3154 endseq = endseq - len(document.body[p : p + 1]) + len(subst)
3155 document.body[p : p + 1] = subst
3161 def revert_frametitle(document):
3162 " Reverts beamer frametitle layout to ERT "
3164 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3165 if document.textclass not in beamer_classes:
3168 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
3171 i = find_token(document.body, "\\begin_layout FrameTitle", i)
3174 j = find_end_of_layout(document.body, i)
3176 document.warning("Malformed LyX document: Can't find end of FrameTitle layout")
3180 document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
3181 endlay += len(put_cmd_in_ert("}"))
3182 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\frametitle")
3183 for p in range(i, j):
3186 m = rx.match(document.body[p])
3190 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3191 endPlain = find_end_of_layout(document.body, beginPlain)
3192 endInset = find_end_of_inset(document.body, p)
3193 content = document.body[beginPlain + 1 : endPlain]
3195 endlay = endlay - len(document.body[p : endInset + 1])
3197 del document.body[p : endInset + 1]
3198 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3200 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3201 endPlain = find_end_of_layout(document.body, beginPlain)
3202 endInset = find_end_of_inset(document.body, p)
3203 content = document.body[beginPlain + 1 : endPlain]
3205 endlay = endlay - len(document.body[p : endInset + 1])
3207 del document.body[p : endInset + 1]
3208 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3210 subst += put_cmd_in_ert("{")
3211 document.body[i : i + 1] = subst
3215 def convert_epigraph(document):
3216 " Converts memoir epigraph to new syntax "
3218 if document.textclass != "memoir":
3223 i = find_token(document.body, "\\begin_layout Epigraph", i)
3226 j = find_end_of_layout(document.body, i)
3228 document.warning("Malformed LyX document: Can't find end of Epigraph layout")
3233 ert = find_token(document.body, "\\begin_inset ERT", i, j)
3235 endInset = find_end_of_inset(document.body, ert)
3236 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", ert)
3237 endPlain = find_end_of_layout(document.body, beginPlain)
3238 ertcont = beginPlain + 2
3239 if document.body[ertcont] == "}{":
3241 # Convert to ArgInset
3242 endlay = endlay - 2 * len(document.body[j])
3243 begsubst = ['\\begin_inset Argument post:1', 'status collapsed', '',
3244 '\\begin_layout Plain Layout']
3245 endsubst = ['\\end_layout', '', '\\end_inset', '', document.body[j]]
3246 document.body[j : j + 1] = endsubst
3247 document.body[endInset + 1 : endInset + 1] = begsubst
3249 endlay += len(begsubst) + len(endsubst)
3250 endlay = endlay - len(document.body[ert : endInset + 1])
3251 del document.body[ert : endInset + 1]
3256 def revert_epigraph(document):
3257 " Reverts memoir epigraph argument to ERT "
3259 if document.textclass != "memoir":
3264 i = find_token(document.body, "\\begin_layout Epigraph", i)
3267 j = find_end_of_layout(document.body, i)
3269 document.warning("Malformed LyX document: Can't find end of Epigraph layout")
3274 p = find_token(document.body, "\\begin_layout Argument post:1", i, j)
3276 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3277 endPlain = find_end_of_layout(document.body, beginPlain)
3278 endInset = find_end_of_inset(document.body, p)
3279 content = document.body[beginPlain + 1 : endPlain]
3281 endlay = endlay - len(document.body[p : endInset + 1])
3283 del document.body[p : endInset + 1]
3284 subst += put_cmd_in_ert("}{") + content
3286 subst += put_cmd_in_ert("}{")
3288 document.body[j : j] = subst + document.body[j : j]
3292 def convert_captioninsets(document):
3293 " Converts caption insets to new syntax "
3297 i = find_token(document.body, "\\begin_inset Caption", i)
3300 document.body[i] = "\\begin_inset Caption Standard"
3304 def revert_captioninsets(document):
3305 " Reverts caption insets to old syntax "
3309 i = find_token(document.body, "\\begin_inset Caption Standard", i)
3312 document.body[i] = "\\begin_inset Caption"
3316 def convert_captionlayouts(document):
3317 " Convert caption layouts to caption insets. "
3320 "Captionabove": "Above",
3321 "Captionbelow": "Below",
3322 "FigCaption" : "FigCaption",
3323 "Table_Caption" : "Table",
3324 "CenteredCaption" : "Centered",
3325 "Bicaption" : "Bicaption",
3330 i = find_token(document.body, "\\begin_layout", i)
3333 val = get_value(document.body, "\\begin_layout", i)
3334 if val in caption_dict.keys():
3335 j = find_end_of_layout(document.body, i)
3337 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3340 document.body[j:j] = ["\\end_layout", "", "\\end_inset", "", ""]
3341 document.body[i:i+1] = ["\\begin_layout %s" % document.default_layout,
3342 "\\begin_inset Caption %s" % caption_dict[val], "",
3343 "\\begin_layout %s" % document.default_layout]
3347 def revert_captionlayouts(document):
3348 " Revert caption insets to caption layouts. "
3351 "Above" : "Captionabove",
3352 "Below" : "Captionbelow",
3353 "FigCaption" : "FigCaption",
3354 "Table" : "Table_Caption",
3355 "Centered" : "CenteredCaption",
3356 "Bicaption" : "Bicaption",
3360 rx = re.compile(r'^\\begin_inset Caption (\S+)$')
3362 i = find_token(document.body, "\\begin_inset Caption", i)
3366 m = rx.match(document.body[i])
3370 if val not in caption_dict.keys():
3374 # We either need to delete the previous \begin_layout line, or we
3375 # need to end the previous layout if this inset is not in the first
3376 # position of the paragraph.
3377 layout_before = find_token_backwards(document.body, "\\begin_layout", i)
3378 if layout_before == -1:
3379 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3381 layout_line = document.body[layout_before]
3382 del_layout_before = True
3383 l = layout_before + 1
3385 if document.body[l] != "":
3386 del_layout_before = False
3389 if del_layout_before:
3390 del document.body[layout_before:i]
3393 document.body[i:i] = ["\\end_layout", ""]
3396 # Find start of layout in the inset and end of inset
3397 j = find_token(document.body, "\\begin_layout", i)
3399 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3401 k = find_end_of_inset(document.body, i)
3403 document.warning("Malformed LyX document: Missing `\\end_inset'.")
3406 # We either need to delete the following \end_layout line, or we need
3407 # to restart the old layout if this inset is not at the paragraph end.
3408 layout_after = find_token(document.body, "\\end_layout", k)
3409 if layout_after == -1:
3410 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3412 del_layout_after = True
3414 while l < layout_after:
3415 if document.body[l] != "":
3416 del_layout_after = False
3419 if del_layout_after:
3420 del document.body[k+1:layout_after+1]
3422 document.body[k+1:k+1] = [layout_line, ""]
3424 # delete \begin_layout and \end_inset and replace \begin_inset with
3425 # "\begin_layout XXX". This works because we can only have one
3426 # paragraph in the caption inset: The old \end_layout will be recycled.
3427 del document.body[k]
3428 if document.body[k] == "":
3429 del document.body[k]
3430 del document.body[j]
3431 if document.body[j] == "":
3432 del document.body[j]
3433 document.body[i] = "\\begin_layout %s" % caption_dict[val]
3434 if document.body[i+1] == "":
3435 del document.body[i+1]
3439 def revert_fragileframe(document):
3440 " Reverts beamer FragileFrame layout to ERT "
3442 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3443 if document.textclass not in beamer_classes:
3448 i = find_token(document.body, "\\begin_layout FragileFrame", i)
3451 # Find end of sequence
3452 j = find_end_of_sequence(document.body, i)
3454 document.warning("Malformed LyX document. Cannot find end of FragileFrame sequence!")
3458 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{frame}")
3459 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{frame}")
3460 endseq = endseq + len(esubst) - len(document.body[j : j])
3461 if document.body[j] == "\\end_deeper":
3462 document.body[j : j] = ["\\end_deeper", ""] + esubst
3464 document.body[j : j] = esubst
3465 for q in range(i, j):
3466 if document.body[q] == "\\begin_layout FragileFrame":
3467 document.body[q] = "\\begin_layout %s" % document.default_layout
3470 if document.body[r] == "\\begin_deeper":
3471 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3473 document.body[r] = ""
3474 document.body[s] = ""
3478 for p in range(1, 5):
3479 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, j)
3482 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3483 endPlain = find_end_of_layout(document.body, beginPlain)
3484 endInset = find_end_of_inset(document.body, arg)
3485 content = document.body[beginPlain + 1 : endPlain]
3487 j = j - len(document.body[arg : endInset + 1])
3489 del document.body[arg : endInset + 1]
3490 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3492 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3493 endPlain = find_end_of_layout(document.body, beginPlain)
3494 endInset = find_end_of_inset(document.body, arg)
3495 content = document.body[beginPlain + 1 : endPlain]
3497 j = j - len(document.body[arg : endInset + 1])
3499 del document.body[arg : endInset + 1]
3500 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3502 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3503 endPlain = find_end_of_layout(document.body, beginPlain)
3504 endInset = find_end_of_inset(document.body, arg)
3505 content = document.body[beginPlain + 1 : endPlain]
3507 j = j - len(document.body[arg : endInset + 1])
3509 del document.body[arg : endInset + 1]
3510 subst += put_cmd_in_ert("[fragile,") + content + put_cmd_in_ert("]")
3512 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3513 endPlain = find_end_of_layout(document.body, beginPlain)
3514 endInset = find_end_of_inset(document.body, arg)
3515 content = document.body[beginPlain + 1 : endPlain]
3517 j = j - len(document.body[arg : endInset + 1])
3519 del document.body[arg : endInset + 1]
3520 subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
3522 subst += put_cmd_in_ert("[fragile]")
3524 document.body[i : i + 1] = subst
3528 def revert_newframes(document):
3529 " Reverts beamer Frame and PlainFrame layouts to old forms "
3531 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3532 if document.textclass not in beamer_classes:
3536 "Frame" : "BeginFrame",
3537 "PlainFrame" : "BeginPlainFrame",
3540 rx = re.compile(r'^\\begin_layout (\S+)$')
3543 i = find_token(document.body, "\\begin_layout", i)
3547 m = rx.match(document.body[i])
3551 if val not in frame_dict.keys():
3554 # Find end of sequence
3555 j = find_end_of_sequence(document.body, i)
3557 document.warning("Malformed LyX document. Cannot find end of Frame sequence!")
3561 subst = ["\\begin_layout %s" % frame_dict[val]]
3562 esubst = ["\\end_layout", "", "\\begin_layout EndFrame", "", "\\end_layout"]
3563 endseq = endseq + len(esubst) - len(document.body[j : j])
3564 if document.body[j] == "\\end_deeper":
3565 document.body[j : j] = ["\\end_deeper", ""] + esubst
3567 document.body[j : j] = esubst
3568 for q in range(i, j):
3569 if document.body[q] == "\\begin_layout %s" % val:
3570 document.body[q] = "\\begin_layout %s" % document.default_layout
3573 if document.body[r] == "\\begin_deeper":
3574 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3576 document.body[r] = ""
3577 document.body[s] = ""
3581 l = find_end_of_layout(document.body, i)
3582 for p in range(1, 5):
3583 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, l)
3586 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3587 endPlain = find_end_of_layout(document.body, beginPlain)
3588 endInset = find_end_of_inset(document.body, arg)
3589 content = document.body[beginPlain + 1 : endPlain]
3591 l = l - len(document.body[arg : endInset + 1])
3593 del document.body[arg : endInset + 1]
3594 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3596 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3597 endPlain = find_end_of_layout(document.body, beginPlain)
3598 endInset = find_end_of_inset(document.body, arg)
3599 content = document.body[beginPlain + 1 : endPlain]
3601 l = l - len(document.body[arg : endInset + 1])
3603 del document.body[arg : endInset + 1]
3604 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3606 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3607 endPlain = find_end_of_layout(document.body, beginPlain)
3608 endInset = find_end_of_inset(document.body, arg)
3609 content = document.body[beginPlain + 1 : endPlain]
3611 l = l - len(document.body[arg : endInset + 1])
3613 del document.body[arg : endInset + 1]
3614 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3616 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3617 endPlain = find_end_of_layout(document.body, beginPlain)
3618 endInset = find_end_of_inset(document.body, arg)
3619 content = document.body[beginPlain + 1 : endPlain]
3621 l = l - len(document.body[arg : endInset + 1])
3623 del document.body[arg : endInset + 1]
3626 document.body[i : i + 1] = subst
3629 # known encodings that do not change their names (same LyX and LaTeX names)
3630 known_enc_tuple = ("auto", "default", "ansinew", "applemac", "armscii8", "ascii",
3631 "cp437", "cp437de", "cp850", "cp852", "cp855", "cp858", "cp862", "cp865", "cp866",
3632 "cp1250", "cp1251", "cp1252", "cp1255", "cp1256", "cp1257", "koi8-r", "koi8-u",
3633 "pt154", "pt254", "tis620-0", "utf8", "utf8x", "utf8-plain")
3635 def convert_encodings(document):
3636 "Use the LyX names of the encodings instead of the LaTeX names."
3637 LaTeX2LyX_enc_dict = {
3638 "8859-6": "iso8859-6",
3639 "8859-8": "iso8859-8",
3641 "euc": "euc-jp-platex",
3646 "iso88595": "iso8859-5",
3647 "iso-8859-7": "iso8859-7",
3649 "jis": "jis-platex",
3651 "l7xenc": "iso8859-13",
3652 "latin1": "iso8859-1",
3653 "latin2": "iso8859-2",
3654 "latin3": "iso8859-3",
3655 "latin4": "iso8859-4",
3656 "latin5": "iso8859-9",
3657 "latin9": "iso8859-15",
3658 "latin10": "iso8859-16",
3659 "SJIS": "shift-jis",
3660 "sjis": "shift-jis-platex",
3663 i = find_token(document.header, "\\inputencoding" , 0)
3666 val = get_value(document.header, "\\inputencoding", i)
3667 if val in LaTeX2LyX_enc_dict.keys():
3668 document.header[i] = "\\inputencoding %s" % LaTeX2LyX_enc_dict[val]
3669 elif val not in known_enc_tuple:
3670 document.warning("Ignoring unknown input encoding: `%s'" % val)
3673 def revert_encodings(document):
3674 """Revert to using the LaTeX names of the encodings instead of the LyX names.
3675 Also revert utf8-platex to sjis, the language default when using Japanese.
3677 LyX2LaTeX_enc_dict = {
3682 "euc-jp-platex": "euc",
3685 "iso8859-1": "latin1",
3686 "iso8859-2": "latin2",
3687 "iso8859-3": "latin3",
3688 "iso8859-4": "latin4",
3689 "iso8859-5": "iso88595",
3690 "iso8859-6": "8859-6",
3691 "iso8859-7": "iso-8859-7",
3692 "iso8859-8": "8859-8",
3693 "iso8859-9": "latin5",
3694 "iso8859-13": "l7xenc",
3695 "iso8859-15": "latin9",
3696 "iso8859-16": "latin10",
3698 "jis-platex": "jis",
3699 "shift-jis": "SJIS",
3700 "shift-jis-platex": "sjis",
3702 "utf8-platex": "sjis"
3704 i = find_token(document.header, "\\inputencoding" , 0)
3707 val = get_value(document.header, "\\inputencoding", i)
3708 if val in LyX2LaTeX_enc_dict.keys():
3709 document.header[i] = "\\inputencoding %s" % LyX2LaTeX_enc_dict[val]
3710 elif val not in known_enc_tuple:
3711 document.warning("Ignoring unknown input encoding: `%s'" % val)
3714 def revert_IEEEtran_3(document):
3716 Reverts Flex Insets to TeX-code
3718 if document.textclass == "IEEEtran":
3724 h = find_token(document.body, "\\begin_inset Flex Author Mark", h)
3726 endh = find_end_of_inset(document.body, h)
3727 document.body[endh - 2 : endh + 1] = put_cmd_in_ert("}")
3728 document.body[h : h + 4] = put_cmd_in_ert("\\IEEEauthorrefmark{")
3731 i = find_token(document.body, "\\begin_inset Flex Author Name", i)
3733 endi = find_end_of_inset(document.body, i)
3734 document.body[endi - 2 : endi + 1] = put_cmd_in_ert("}")
3735 document.body[i : i + 4] = put_cmd_in_ert("\\IEEEauthorblockN{")
3738 j = find_token(document.body, "\\begin_inset Flex Author Affiliation", j)
3740 endj = find_end_of_inset(document.body, j)
3741 document.body[endj - 2 : endj + 1] = put_cmd_in_ert("}")
3742 document.body[j : j + 4] = put_cmd_in_ert("\\IEEEauthorblockA{")
3744 if i == -1 and j == -1 and h == -1:
3748 def revert_kurier_fonts(document):
3749 " Revert kurier font definition to LaTeX "
3751 i = find_token(document.header, "\\font_math", 0)
3753 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3754 val = get_value(document.header, "\\font_math", i)
3755 if val == "kurier-math":
3756 add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
3757 "\\usepackage[math]{kurier}\n" \
3758 "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
3759 document.header[i] = "\\font_math auto"
3761 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3762 kurier_fonts = ["kurier", "kurierc", "kurierl", "kurierlc"]
3763 k = find_token(document.header, "\\font_sans kurier", 0)
3765 sf = get_value(document.header, "\\font_sans", k)
3766 if sf in kurier_fonts:
3767 add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
3768 document.header[k] = "\\font_sans default"
3770 def revert_iwona_fonts(document):
3771 " Revert iwona font definition to LaTeX "
3773 i = find_token(document.header, "\\font_math", 0)
3775 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3776 val = get_value(document.header, "\\font_math", i)
3777 if val == "iwona-math":
3778 add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
3779 "\\usepackage[math]{iwona}\n" \
3780 "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
3781 document.header[i] = "\\font_math auto"
3783 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3784 iwona_fonts = ["iwona", "iwonac", "iwonal", "iwonalc"]
3785 k = find_token(document.header, "\\font_sans iwona", 0)
3787 sf = get_value(document.header, "\\font_sans", k)
3788 if sf in iwona_fonts:
3789 add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
3790 document.header[k] = "\\font_sans default"
3793 def revert_new_libertines(document):
3794 " Revert new libertine font definition to LaTeX "
3796 if find_token(document.header, "\\use_non_tex_fonts true", 0) != -1:
3799 i = find_token(document.header, "\\font_typewriter libertine-mono", 0)
3801 preamble = "\\usepackage"
3802 sc = find_token(document.header, "\\font_tt_scale", 0)
3804 scval = get_value(document.header, "\\font_tt_scale", sc)
3806 preamble += "[scale=%f]" % (float(scval) / 100)
3807 document.header[sc] = "\\font_tt_scale 100"
3808 preamble += "{libertineMono-type1}"
3809 add_to_preamble(document, [preamble])
3810 document.header[i] = "\\font_typewriter default"
3812 k = find_token(document.header, "\\font_sans biolinum", 0)
3814 preamble = "\\usepackage"
3816 j = find_token(document.header, "\\font_osf true", 0)
3821 sc = find_token(document.header, "\\font_sf_scale", 0)
3823 scval = get_value(document.header, "\\font_sf_scale", sc)
3825 options += ",scale=%f" % (float(scval) / 100)
3826 document.header[sc] = "\\font_sf_scale 100"
3828 preamble += "[" + options +"]"
3829 preamble += "{biolinum-type1}"
3830 add_to_preamble(document, [preamble])
3831 document.header[k] = "\\font_sans default"
3834 def convert_lyxframes(document):
3835 " Converts old beamer frames to new style "
3837 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3838 if document.textclass not in beamer_classes:
3841 framebeg = ["BeginFrame", "BeginPlainFrame"]
3842 frameend = ["Frame", "PlainFrame", "EndFrame", "BeginFrame", "BeginPlainFrame", "AgainFrame",
3843 "Section", "Section*", "Subsection", "Subsection*", "Subsubsection", "Subsubsection*"]
3844 for lay in framebeg:
3847 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
3850 parent = get_containing_layout(document.body, i)
3851 if parent == False or parent[1] != i:
3852 document.warning("Wrong parent layout!")
3855 frametype = parent[0]
3859 # Step I: Convert ERT arguments
3860 # FIXME: See restrictions in convert_beamerframeargs method
3861 ertend = convert_beamerframeargs(document, i, parbeg)
3864 # Step II: Now rename the layout and convert the title to an argument
3865 j = find_end_of_layout(document.body, i)
3866 document.body[j : j + 1] = ['\\end_layout', '', '\\end_inset', '', '\\end_layout']
3867 if lay == "BeginFrame":
3868 document.body[i] = "\\begin_layout Frame"
3870 document.body[i] = "\\begin_layout PlainFrame"
3871 document.body[ertend + 1 : ertend + 1] = ['\\begin_inset Argument 4',
3872 'status open', '', '\\begin_layout Plain Layout']
3873 # Step III: find real frame end
3877 fend = find_token(document.body, "\\begin_layout", jj)
3879 document.warning("Malformed LyX document: No real frame end!")
3881 val = get_value(document.body, "\\begin_layout", fend)
3882 if val not in frameend:
3885 old = document.body[fend]
3886 if val == frametype:
3887 document.body[fend : fend] = ['\\end_deeper', '', '\\begin_layout Separator', '', '\\end_layout']
3888 # consider explicit EndFrames between two identical frame types
3889 elif val == "EndFrame":
3890 nextlayout = find_token(document.body, "\\begin_layout", fend + 1)
3891 if nextlayout != -1 and get_value(document.body, "\\begin_layout", nextlayout) == frametype:
3892 document.body[fend : fend] = ['\\end_deeper', '', '\\begin_layout Separator', '', '\\end_layout']
3894 document.body[fend : fend] = ['\\end_deeper']
3896 document.body[fend : fend] = ['\\end_deeper']
3897 document.body[j + 1 : j + 1] = ['', '\\begin_deeper']
3902 def remove_endframes(document):
3903 " Remove deprecated beamer endframes "
3905 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3906 if document.textclass not in beamer_classes:
3911 i = find_token_exact(document.body, "\\begin_layout EndFrame", i)
3914 j = find_end_of_layout(document.body, i)
3916 document.warning("Malformed LyX document: Missing \\end_layout to EndFrame")
3919 del document.body[i : j + 1]
3922 def revert_powerdot_flexes(document):
3923 " Reverts powerdot flex insets "
3925 if document.textclass != "powerdot":
3928 flexes = {"Onslide" : "\\onslide",
3929 "Onslide*" : "\\onslide*",
3930 "Onslide+" : "\\onslide+"}
3931 rx = re.compile(r'^\\begin_inset Flex (.+)$')
3935 i = find_token(document.body, "\\begin_inset Flex", i)
3938 m = rx.match(document.body[i])
3940 flextype = m.group(1)
3941 z = find_end_of_inset(document.body, i)
3943 document.warning("Can't find end of Flex " + flextype + " inset.")
3946 if flextype in flexes:
3947 pre = put_cmd_in_ert(flexes[flextype])
3948 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
3950 argend = find_end_of_inset(document.body, arg)
3952 document.warning("Can't find end of Argument!")
3955 # Find containing paragraph layout
3956 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3957 endPlain = find_end_of_layout(document.body, beginPlain)
3958 argcontent = document.body[beginPlain + 1 : endPlain]
3960 z = z - len(document.body[arg : argend + 1])
3962 del document.body[arg : argend + 1]
3963 pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
3964 pre += put_cmd_in_ert("{")
3965 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
3966 endPlain = find_end_of_layout(document.body, beginPlain)
3968 z = z - len(document.body[i : beginPlain + 1])
3970 document.body[i : beginPlain + 1] = pre
3971 post = put_cmd_in_ert("}")
3972 document.body[z - 2 : z + 1] = post
3976 def revert_powerdot_pause(document):
3977 " Reverts powerdot pause layout to ERT "
3979 if document.textclass != "powerdot":
3984 i = find_token(document.body, "\\begin_layout Pause", i)
3987 j = find_end_of_layout(document.body, i)
3989 document.warning("Malformed LyX document: Can't find end of Pause layout")
3993 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\pause")
3994 for p in range(i, j):
3997 arg = find_token(document.body, "\\begin_inset Argument 1", i, j)
3999 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
4000 endPlain = find_end_of_layout(document.body, beginPlain)
4001 endInset = find_end_of_inset(document.body, p)
4002 content = document.body[beginPlain + 1 : endPlain]
4004 endlay = endlay - len(document.body[p : endInset + 1])
4006 del document.body[p : endInset + 1]
4007 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
4009 document.body[i : i + 1] = subst
4013 def revert_powerdot_itemargs(document):
4014 " Reverts powerdot item arguments to ERT "
4016 if document.textclass != "powerdot":
4020 list_layouts = ["Itemize", "ItemizeType1", "Enumerate", "EnumerateType1"]
4021 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
4024 i = find_token(document.body, "\\begin_inset Argument", i)
4027 # Find containing paragraph layout
4028 parent = get_containing_layout(document.body, i)
4030 document.warning("Malformed LyX document: Can't find parent paragraph layout")
4035 realparbeg = parent[3]
4036 layoutname = parent[0]
4038 for p in range(parbeg, parend):
4042 if layoutname in list_layouts:
4043 m = rx.match(document.body[p])
4046 if argnr == "item:1":
4047 j = find_end_of_inset(document.body, i)
4048 # Find containing paragraph layout
4049 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
4050 endPlain = find_end_of_layout(document.body, beginPlain)
4051 content = document.body[beginPlain + 1 : endPlain]
4052 del document.body[i:j+1]
4053 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
4054 document.body[realparbeg : realparbeg] = subst
4055 elif argnr == "item:2":
4056 j = find_end_of_inset(document.body, i)
4057 # Find containing paragraph layout
4058 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
4059 endPlain = find_end_of_layout(document.body, beginPlain)
4060 content = document.body[beginPlain + 1 : endPlain]
4061 del document.body[i:j+1]
4062 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
4063 document.body[realparbeg : realparbeg] = subst
4068 def revert_powerdot_columns(document):
4069 " Reverts powerdot twocolumn to TeX-code "
4070 if document.textclass != "powerdot":
4073 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
4076 i = find_token(document.body, "\\begin_layout Twocolumn", i)
4079 j = find_end_of_layout(document.body, i)
4081 document.warning("Malformed LyX document: Can't find end of Twocolumn layout")
4085 document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
4086 endlay += len(put_cmd_in_ert("}"))
4087 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\twocolumn")
4088 for p in range(i, j):
4091 m = rx.match(document.body[p])
4095 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
4096 endPlain = find_end_of_layout(document.body, beginPlain)
4097 endInset = find_end_of_inset(document.body, p)
4098 content = document.body[beginPlain + 1 : endPlain]
4100 endlay = endlay - len(document.body[p : endInset + 1])
4102 del document.body[p : endInset + 1]
4103 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
4105 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
4106 endPlain = find_end_of_layout(document.body, beginPlain)
4107 endInset = find_end_of_inset(document.body, p)
4108 content = document.body[beginPlain + 1 : endPlain]
4110 endlay = endlay - len(document.body[p : endInset + 1])
4112 del document.body[p : endInset + 1]
4113 subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
4115 subst += put_cmd_in_ert("{")
4116 document.body[i : i + 1] = subst
4120 def revert_mbox_fbox(document):
4121 'Convert revert mbox/fbox boxes to TeX-code'
4124 i = find_token(document.body, "\\begin_inset Box", i)
4127 j = find_token(document.body, "width", i)
4129 document.warning("Malformed LyX document: Can't find box width")
4131 width = get_value(document.body, "width", j)
4132 k = find_end_of_inset(document.body, j)
4134 document.warning("Malformed LyX document: Can't find end of box inset")
4137 BeginLayout = find_token(document.body, "\\begin_layout Plain Layout", j)
4138 EndLayout = find_token(document.body, "\\end_layout", BeginLayout)
4139 # replace if width is ""
4141 document.body[EndLayout:k + 1] = put_cmd_in_ert("}")
4142 if document.body[i] == "\\begin_inset Box Frameless":
4143 document.body[i:BeginLayout + 1] = put_cmd_in_ert("\\mbox{")
4144 if document.body[i] == "\\begin_inset Box Boxed":
4145 document.body[i:BeginLayout + 1] = put_cmd_in_ert("\\fbox{")
4149 def revert_starred_caption(document):
4150 " Reverts unnumbered longtable caption insets "
4154 i = find_token(document.body, "\\begin_inset Caption LongTableNoNumber", i)
4157 # This is not equivalent, but since the caption inset is a full blown
4158 # text inset a true conversion to ERT is too difficult.
4159 document.body[i] = "\\begin_inset Caption Standard"
4163 def revert_forced_local_layout(document):
4166 i = find_token(document.header, "\\begin_forced_local_layout", i)
4169 j = find_end_of(document.header, i, "\\begin_forced_local_layout", "\\end_forced_local_layout")
4171 # this should not happen
4173 regexp = re.compile(r'\s*forcelocal', re.IGNORECASE)
4174 k = find_re(document.header, regexp, i, j)
4176 del document.header[k]
4178 k = find_re(document.header, regexp, i, j)
4179 k = find_token(document.header, "\\begin_local_layout", 0)
4181 document.header[i] = "\\begin_local_layout"
4182 document.header[j] = "\\end_local_layout"
4184 l = find_end_of(document.header, k, "\\begin_local_layout", "\\end_local_layout")
4186 # this should not happen
4188 lines = document.header[i+1 : j]
4190 document.header[k+1 : k+1] = lines
4191 document.header[i : j ] = []
4193 document.header[i : j ] = []
4194 document.header[k+1 : k+1] = lines
4197 def revert_aa1(document):
4198 " Reverts InsetArguments of aa to TeX-code "
4199 if document.textclass == "aa":
4203 i = find_token(document.body, "\\begin_layout Abstract (structured)", i)
4205 revert_Argument_to_TeX_brace(document, i, 0, 1, 4, False, False)
4211 def revert_aa2(document):
4212 " Reverts InsetArguments of aa to TeX-code "
4213 if document.textclass == "aa":
4217 i = find_token(document.body, "\\begin_layout Abstract (structured)", i)
4219 document.body[i] = "\\begin_layout Abstract"
4225 def revert_tibetan(document):
4226 "Set the document language for Tibetan to English"
4228 if document.language == "tibetan":
4229 document.language = "english"
4230 i = find_token(document.header, "\\language", 0)
4232 document.header[i] = "\\language english"
4234 while j < len(document.body):
4235 j = find_token(document.body, "\\lang tibetan", j)
4237 document.body[j] = document.body[j].replace("\\lang tibetan", "\\lang english")
4240 j = len(document.body)
4249 # The idea here is that we will have a sequence of chunk paragraphs.
4250 # We want to convert them to paragraphs in one or several chunk insets.
4251 # Individual chunks are terminated by the character @ on the last line.
4252 # This line will be discarded, and following lines are treated as new
4253 # chunks, which go into their own insets.
4254 # The first line of a chunk should look like: <<CONTENT>>=
4255 # We will discard the delimiters, and put the CONTENT into the
4256 # optional argument of the inset, if the CONTENT is non-empty.
4257 def convert_chunks(document):
4258 first_re = re.compile(r'<<(.*)>>=(.*)')
4261 # find start of a block of chunks
4262 i = find_token(document.body, "\\begin_layout Chunk", file_pos)
4268 chunk_started = False
4271 # process the one we just found
4272 j = find_end_of_layout(document.body, i)
4274 document.warning("Malformed LyX documents. Can't find end of Chunk layout!")
4275 # there is no point continuing, as we will run into the same error again.
4277 this_chunk = "".join(document.body[i + 1:j])
4279 # there may be empty lines between chunks
4280 # we just skip them.
4281 if not chunk_started:
4282 if this_chunk != "":
4284 chunk_started = True
4287 contents.append(document.body[i + 1:j])
4289 # look for potential chunk terminator
4290 # on the last line of the chunk paragraph
4291 if document.body[j - 1] == "@":
4294 # look for subsequent chunk paragraph
4295 i = find_token(document.body, "\\begin_layout", j)
4299 if get_value(document.body, "\\begin_layout", i) != "Chunk":
4302 file_pos = end = j + 1
4304 # The last chunk should simply have an "@" in it
4305 # or at least end with "@" (can happen if @ is
4306 # preceded by a newline)
4307 lastpar = ''.join(contents[-1])
4308 if not lastpar.endswith("@"):
4309 document.warning("Unexpected chunk content: chunk not terminated by '@'!")
4313 # chunk par only contains "@". Just drop it.
4316 # chunk par contains more. Only drop the "@".
4319 # The first line should look like: <<CONTENT>>=
4320 # We want the CONTENT
4321 optarg = ' '.join(contents[0])
4323 # We can already have real chunk content in
4324 # the first par (separated from the options by a newline).
4325 # We collect such stuff to re-insert it later.
4328 match = first_re.search(optarg)
4330 optarg = match.groups()[0]
4331 if match.groups()[1] != "":
4333 for c in contents[0]:
4334 if c.endswith(">>="):
4338 postoptstuff.append(c)
4339 # We have stripped everything. This can be deleted.
4342 newstuff = ['\\begin_layout Standard',
4343 '\\begin_inset Flex Chunk',
4345 '\\begin_layout Plain Layout', '']
4347 # If we have a non-empty optional argument, insert it.
4348 if match and optarg != "":
4350 ['\\begin_inset Argument 1',
4352 '\\begin_layout Plain Layout',
4357 # Since we already opened a Plain layout, the first paragraph
4358 # does not need to do that.
4361 newstuff.extend(postoptstuff)
4362 newstuff.append('\\end_layout')
4366 newstuff.extend(['', '\\begin_layout Plain Layout', ''])
4370 newstuff.append('\\end_layout')
4372 newstuff.extend(['', '\\end_inset', '', '\\end_layout', ''])
4374 document.body[start:end] = newstuff
4376 file_pos += len(newstuff) - (end - start)
4379 def revert_chunks(document):
4382 i = find_token(document.body, "\\begin_inset Flex Chunk", i)
4386 iend = find_end_of_inset(document.body, i)
4388 document.warning("Can't find end of Chunk!")
4392 # Look for optional argument
4394 ostart = find_token(document.body, "\\begin_inset Argument 1", i, iend)
4396 oend = find_end_of_inset(document.body, ostart)
4397 k = find_token(document.body, "\\begin_layout Plain Layout", ostart, oend)
4399 document.warning("Malformed LyX document: Can't find argument contents!")
4401 m = find_end_of_layout(document.body, k)
4402 optarg = "".join(document.body[k+1:m])
4405 # We now remove the optional argument, so we have something
4406 # uniform on which to work
4407 document.body[ostart : oend + 1] = []
4408 # iend is now invalid
4409 iend = find_end_of_inset(document.body, i)
4411 retval = get_containing_layout(document.body, i)
4413 document.warning("Can't find containing layout for Chunk!")
4416 (lname, lstart, lend, pstart) = retval
4417 # we now want to work through the various paragraphs, and collect their contents
4421 k = find_token(document.body, "\\begin_layout Plain Layout", k, lend)
4424 j = find_end_of_layout(document.body, k)
4426 document.warning("Can't find end of layout inside chunk!")
4428 parlist.append(document.body[k+1:j])
4430 # we now need to wrap all of these paragraphs in chunks
4433 newlines.extend(["\\begin_layout Chunk", "", "<<" + optarg + ">>=", "\\end_layout", ""])
4434 for stuff in parlist:
4435 newlines.extend(["\\begin_layout Chunk"] + stuff + ["\\end_layout", ""])
4436 newlines.extend(["\\begin_layout Chunk", "", "@", "\\end_layout", ""])
4437 # replace old content with new content
4438 document.body[lstart : lend + 1] = newlines
4439 i = lstart + len(newlines)
4446 supported_versions = ["2.1.0","2.1"]
4449 [415, [convert_undertilde]],
4451 [417, [convert_japanese_encodings]],
4452 [418, [convert_justification]],
4454 [420, [convert_biblio_style]],
4455 [421, [convert_longtable_captions]],
4456 [422, [convert_use_packages]],
4457 [423, [convert_use_mathtools]],
4458 [424, [convert_cite_engine_type]],
4462 [428, [convert_cell_rotation]],
4463 [429, [convert_table_rotation]],
4464 [430, [convert_listoflistings]],
4465 [431, [convert_use_amssymb]],
4467 [433, [convert_armenian]],
4475 [441, [convert_mdnomath]],
4480 [446, [convert_latexargs]],
4481 [447, [convert_IEEEtran, convert_AASTeX, convert_AGUTeX, convert_IJMP, convert_SIGPLAN, convert_SIGGRAPH, convert_EuropeCV, convert_Initials, convert_ModernCV]],
4482 [448, [convert_literate]],
4485 [451, [convert_beamerargs, convert_againframe_args, convert_corollary_args, convert_quote_args]],
4486 [452, [convert_beamerblocks]],
4487 [453, [convert_use_stmaryrd]],
4488 [454, [convert_overprint]],
4490 [456, [convert_epigraph]],
4491 [457, [convert_use_stackrel]],
4492 [458, [convert_captioninsets, convert_captionlayouts]],
4497 [463, [convert_encodings]],
4498 [464, [convert_use_cancel]],
4499 [465, [convert_lyxframes, remove_endframes]],
4505 [471, [convert_cite_engine_type_default]],
4508 [474, [convert_chunks]],
4512 [473, [revert_chunks]],
4513 [472, [revert_tibetan]],
4514 [471, [revert_aa1,revert_aa2]],
4515 [470, [revert_cite_engine_type_default]],
4516 [469, [revert_forced_local_layout]],
4517 [468, [revert_starred_caption]],
4518 [467, [revert_mbox_fbox]],
4519 [466, [revert_iwona_fonts]],
4520 [465, [revert_powerdot_flexes, revert_powerdot_pause, revert_powerdot_itemargs, revert_powerdot_columns]],
4522 [463, [revert_use_cancel]],
4523 [462, [revert_encodings]],
4524 [461, [revert_new_libertines]],
4525 [460, [revert_kurier_fonts]],
4526 [459, [revert_IEEEtran_3]],
4527 [458, [revert_fragileframe, revert_newframes]],
4528 [457, [revert_captioninsets, revert_captionlayouts]],
4529 [456, [revert_use_stackrel]],
4530 [455, [revert_epigraph]],
4531 [454, [revert_frametitle]],
4532 [453, [revert_overprint]],
4533 [452, [revert_use_stmaryrd]],
4534 [451, [revert_beamerblocks]],
4535 [450, [revert_beamerargs, revert_beamerargs2, revert_beamerargs3, revert_beamerflex]],
4536 [449, [revert_garamondx, revert_garamondx_newtxmath]],
4537 [448, [revert_itemargs]],
4538 [447, [revert_literate]],
4539 [446, [revert_IEEEtran, revert_IEEEtran_2, revert_AASTeX, revert_AGUTeX, revert_IJMP, revert_SIGPLAN, revert_SIGGRAPH, revert_EuropeCV, revert_Initials, revert_ModernCV_3, revert_ModernCV_4]],
4540 [445, [revert_latexargs]],
4541 [444, [revert_uop]],
4542 [443, [revert_biolinum]],
4544 [441, [revert_newtxmath]],
4545 [440, [revert_mdnomath]],
4546 [439, [revert_mathfonts]],
4547 [438, [revert_minionpro]],
4548 [437, [revert_ipadeco, revert_ipachar]],
4549 [436, [revert_texgyre]],
4550 [435, [revert_mathdesign]],
4551 [434, [revert_txtt]],
4552 [433, [revert_libertine]],
4553 [432, [revert_armenian]],
4554 [431, [revert_languages, revert_ancientgreek]],
4555 [430, [revert_use_amssymb]],
4556 [429, [revert_listoflistings]],
4557 [428, [revert_table_rotation]],
4558 [427, [revert_cell_rotation]],
4559 [426, [revert_tipa]],
4560 [425, [revert_verbatim]],
4561 [424, [revert_cancel]],
4562 [423, [revert_cite_engine_type]],
4563 [422, [revert_use_mathtools]],
4564 [421, [revert_use_packages]],
4565 [420, [revert_longtable_captions]],
4566 [419, [revert_biblio_style]],
4567 [418, [revert_australian]],
4568 [417, [revert_justification]],
4569 [416, [revert_japanese_encodings]],
4570 [415, [revert_negative_space, revert_math_spaces]],
4571 [414, [revert_undertilde]],
4572 [413, [revert_visible_space]]
4576 if __name__ == "__main__":