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", "mathdots", "mhchem", "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)
554 regexp = re.compile(r'(\\use_package\s+%s)' % p)
555 i = find_re(document.header, regexp, j)
557 value = get_value(document.header, "\\use_package %s" % p, i).split()[1]
558 del document.header[i]
560 document.header.insert(j, "\\use_%s %s" % (p, value))
564 def convert_use_package(document, pkg):
565 i = find_token(document.header, "\\use_package", 0)
567 document.warning("Malformed LyX document: Can't find \\use_package.")
569 j = find_token(document.preamble, "\\usepackage{" + pkg + "}", 0)
571 document.header.insert(i + 1, "\\use_package " + pkg + " 0")
573 document.header.insert(i + 1, "\\use_package " + pkg + " 2")
574 del document.preamble[j]
577 def revert_use_package(document, pkg, commands, oldauto):
578 # oldauto defines how the version we are reverting to behaves:
579 # if it is true, the old version uses the package automatically.
580 # if it is false, the old version never uses the package.
581 regexp = re.compile(r'(\\use_package\s+%s)' % pkg)
582 i = find_re(document.header, regexp, 0)
583 value = "1" # default is auto
585 value = get_value(document.header, "\\use_package" , i).split()[1]
586 del document.header[i]
587 if value == "2": # on
588 add_to_preamble(document, ["\\usepackage{" + pkg + "}"])
589 elif value == "1" and not oldauto: # auto
592 i = find_token(document.body, '\\begin_inset Formula', i)
595 j = find_end_of_inset(document.body, i)
597 document.warning("Malformed LyX document: Can't find end of Formula inset at line " + str(i))
600 code = "\n".join(document.body[i:j])
602 if code.find("\\%s" % c) != -1:
603 add_to_preamble(document, ["\\usepackage{" + pkg + "}"])
608 def convert_use_mathtools(document):
609 "insert use_package mathtools"
610 convert_use_package(document, "mathtools")
613 def revert_use_mathtools(document):
614 "remove use_package mathtools"
615 commands = ["mathclap", "mathllap", "mathrlap", \
616 "lgathered", "rgathered", "vcentcolon", "dblcolon", \
617 "coloneqq", "Coloneqq", "coloneq", "Coloneq", "eqqcolon", \
618 "Eqqcolon", "eqcolon", "Eqcolon", "colonapprox", \
619 "Colonapprox", "colonsim", "Colonsim"]
620 revert_use_package(document, "mathtools", commands, False)
623 def convert_use_stmaryrd(document):
624 "insert use_package stmaryrd"
625 convert_use_package(document, "stmaryrd")
628 def revert_use_stmaryrd(document):
629 "remove use_package stmaryrd"
630 # commands provided by stmaryrd.sty but LyX uses other packages:
631 # boxdot lightning, bigtriangledown, bigtriangleup
632 commands = ["shortleftarrow", "shortrightarrow", "shortuparrow", \
633 "shortdownarrow", "Yup", "Ydown", "Yleft", "Yright", \
634 "varcurlyvee", "varcurlywedge", "minuso", "baro", \
635 "sslash", "bbslash", "moo", "varotimes", "varoast", \
636 "varobar", "varodot", "varoslash", "varobslash", \
637 "varocircle", "varoplus", "varominus", "boxast", \
638 "boxbar", "boxslash", "boxbslash", "boxcircle", \
639 "boxbox", "boxempty", "merge", "vartimes", \
640 "fatsemi", "sswarrow", "ssearrow", "curlywedgeuparrow", \
641 "curlywedgedownarrow", "fatslash", "fatbslash", "lbag", \
642 "rbag", "varbigcirc", "leftrightarroweq", \
643 "curlyveedownarrow", "curlyveeuparrow", "nnwarrow", \
644 "nnearrow", "leftslice", "rightslice", "varolessthan", \
645 "varogreaterthan", "varovee", "varowedge", "talloblong", \
646 "interleave", "obar", "obslash", "olessthan", \
647 "ogreaterthan", "ovee", "owedge", "oblong", "inplus", \
648 "niplus", "nplus", "subsetplus", "supsetplus", \
649 "subsetpluseq", "supsetpluseq", "Lbag", "Rbag", \
650 "llbracket", "rrbracket", "llparenthesis", \
651 "rrparenthesis", "binampersand", "bindnasrepma", \
652 "trianglelefteqslant", "trianglerighteqslant", \
653 "ntrianglelefteqslant", "ntrianglerighteqslant", \
654 "llfloor", "rrfloor", "llceil", "rrceil", "arrownot", \
655 "Arrownot", "Mapstochar", "mapsfromchar", "Mapsfromchar", \
656 "leftrightarrowtriangle", "leftarrowtriangle", \
657 "rightarrowtriangle", \
658 "bigcurlyvee", "bigcurlywedge", "bigsqcap", "bigbox", \
659 "bigparallel", "biginterleave", "bignplus", \
660 "varcopyright", "longarrownot", "Longarrownot", \
661 "Mapsto", "mapsfrom", "Mapsfrom" "Longmapsto", \
662 "longmapsfrom", "Longmapsfrom"]
663 revert_use_package(document, "stmaryrd", commands, False)
667 def convert_use_stackrel(document):
668 "insert use_package stackrel"
669 convert_use_package(document, "stackrel")
672 def revert_use_stackrel(document):
673 "remove use_package stackrel"
674 commands = ["stackrel"]
675 revert_use_package(document, "stackrel", commands, False)
678 def convert_cite_engine_type(document):
679 "Determine the \\cite_engine_type from the citation engine."
680 i = find_token(document.header, "\\cite_engine", 0)
683 engine = get_value(document.header, "\\cite_engine", i)
685 engine, type = engine.split("_")
687 type = {"basic": "numerical", "jurabib": "authoryear"}[engine]
688 document.header[i] = "\\cite_engine " + engine
689 document.header.insert(i + 1, "\\cite_engine_type " + type)
692 def revert_cite_engine_type(document):
693 "Natbib had the type appended with an underscore."
694 engine_type = "numerical"
695 i = find_token(document.header, "\\cite_engine_type" , 0)
697 document.warning("No \\cite_engine_type line. Assuming numerical.")
699 engine_type = get_value(document.header, "\\cite_engine_type", i)
700 del document.header[i]
702 # We are looking for the natbib citation engine
703 i = find_token(document.header, "\\cite_engine natbib", 0)
706 document.header[i] = "\\cite_engine natbib_" + engine_type
709 def convert_cite_engine_type_default(document):
710 "Convert \\cite_engine_type to default for the basic citation engine."
711 i = find_token(document.header, "\\cite_engine basic", 0)
714 i = find_token(document.header, "\\cite_engine_type" , 0)
717 document.header[i] = "\\cite_engine_type default"
720 def revert_cite_engine_type_default(document):
721 """Revert \\cite_engine_type default.
723 Revert to numerical for the basic cite engine, otherwise to authoryear."""
724 engine_type = "authoryear"
725 i = find_token(document.header, "\\cite_engine_type default" , 0)
728 j = find_token(document.header, "\\cite_engine basic", 0)
730 engine_type = "numerical"
731 document.header[i] = "\\cite_engine_type " + engine_type
734 # this is the same, as revert_use_cancel() except for the default
735 def revert_cancel(document):
736 "add cancel to the preamble if necessary"
737 commands = ["cancelto", "cancel", "bcancel", "xcancel"]
738 revert_use_package(document, "cancel", commands, False)
741 def revert_verbatim(document):
742 " Revert verbatim einvironments completely to TeX-code. "
745 subst_end = ['\end_layout', '', '\\begin_layout Plain Layout',
747 '\\begin_layout Plain Layout', '', '',
750 '\\end_layout', '', '\\end_inset',
751 '', '', '\\end_layout']
752 subst_begin = ['\\begin_layout Standard', '\\noindent',
753 '\\begin_inset ERT', 'status open', '',
754 '\\begin_layout Plain Layout', '', '', '\\backslash',
756 '\\end_layout', '', '\\begin_layout Plain Layout', '']
759 i = find_token(document.body, "\\begin_layout Verbatim", i)
762 j = find_end_of_layout(document.body, i)
764 document.warning("Malformed LyX document: Can't find end of Verbatim layout")
767 # delete all line breaks insets (there are no other insets)
770 n = find_token(document.body, "\\begin_inset Newline newline", l, j)
772 n = find_token(document.body, "\\begin_inset Newline linebreak", l, j)
775 m = find_end_of_inset(document.body, n)
776 del(document.body[m:m+1])
777 document.body[n:n+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
779 # we deleted a line, so the end of the inset moved forward.
781 # consecutive verbatim environments need to be connected
782 k = find_token(document.body, "\\begin_layout Verbatim", j)
783 if k == j + 2 and consecutive == False:
785 document.body[j:j+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
786 document.body[i:i+1] = subst_begin
788 if k == j + 2 and consecutive == True:
789 document.body[j:j+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
790 del(document.body[i:i+1])
792 if k != j + 2 and consecutive == True:
793 document.body[j:j+1] = subst_end
794 # the next paragraph must not be indented
795 document.body[j+19:j+19] = ['\\noindent']
796 del(document.body[i:i+1])
800 document.body[j:j+1] = subst_end
801 # the next paragraph must not be indented
802 document.body[j+19:j+19] = ['\\noindent']
803 document.body[i:i+1] = subst_begin
806 def revert_tipa(document):
807 " Revert native TIPA insets to mathed or ERT. "
810 i = find_token(document.body, "\\begin_inset IPA", i)
813 j = find_end_of_inset(document.body, i)
815 document.warning("Malformed LyX document: Can't find end of IPA inset")
819 n = find_token(document.body, "\\begin_layout", i, j)
821 document.warning("Malformed LyX document: IPA inset has no embedded layout")
824 m = find_end_of_layout(document.body, n)
826 document.warning("Malformed LyX document: Can't find end of embedded layout")
829 content = document.body[n+1:m]
830 p = find_token(document.body, "\\begin_layout", m, j)
831 if p != -1 or len(content) > 1:
833 content = document.body[i+1:j]
835 # IPA insets with multiple pars need to be wrapped by \begin{IPA}...\end{IPA}
836 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}")
837 add_to_preamble(document, ["\\usepackage{tipa,tipx}"])
839 # single-par IPA insets can be reverted to mathed
840 document.body[i:j+1] = ["\\begin_inset Formula $\\text{\\textipa{" + content[0] + "}}$", "\\end_inset"]
844 def revert_cell_rotation(document):
845 "Revert cell rotations to TeX-code"
847 load_rotating = False
851 # first, let's find out if we need to do anything
852 i = find_token(document.body, '<cell ', i)
855 j = document.body[i].find('rotate="')
857 k = document.body[i].find('"', j + 8)
858 value = document.body[i][j + 8 : k]
860 rgx = re.compile(r' rotate="[^"]+?"')
861 # remove rotate option
862 document.body[i] = rgx.sub('', document.body[i])
864 rgx = re.compile(r' rotate="[^"]+?"')
865 document.body[i] = rgx.sub('rotate="true"', document.body[i])
867 rgx = re.compile(r' rotate="[^"]+?"')
869 # remove rotate option
870 document.body[i] = rgx.sub('', document.body[i])
872 document.body[i + 5 : i + 5] = \
873 put_cmd_in_ert("\\end{turn}")
874 document.body[i + 4 : i + 4] = \
875 put_cmd_in_ert("\\begin{turn}{" + value + "}")
881 add_to_preamble(document, ["\\@ifundefined{turnbox}{\usepackage{rotating}}{}"])
884 def convert_cell_rotation(document):
885 'Convert cell rotation statements from "true" to "90"'
889 # first, let's find out if we need to do anything
890 i = find_token(document.body, '<cell ', i)
893 j = document.body[i].find('rotate="true"')
895 rgx = re.compile(r'rotate="[^"]+?"')
896 # convert "true" to "90"
897 document.body[i] = rgx.sub('rotate="90"', document.body[i])
902 def revert_table_rotation(document):
903 "Revert table rotations to TeX-code"
905 load_rotating = False
909 # first, let's find out if we need to do anything
910 i = find_token(document.body, '<features ', i)
913 j = document.body[i].find('rotate="')
915 end_table = find_token(document.body, '</lyxtabular>', j)
916 k = document.body[i].find('"', j + 8)
917 value = document.body[i][j + 8 : k]
919 rgx = re.compile(r' rotate="[^"]+?"')
920 # remove rotate option
921 document.body[i] = rgx.sub('', document.body[i])
923 rgx = re.compile(r'rotate="[^"]+?"')
924 document.body[i] = rgx.sub('rotate="true"', document.body[i])
926 rgx = re.compile(r' rotate="[^"]+?"')
928 # remove rotate option
929 document.body[i] = rgx.sub('', document.body[i])
931 document.body[end_table + 3 : end_table + 3] = \
932 put_cmd_in_ert("\\end{turn}")
933 document.body[i - 2 : i - 2] = \
934 put_cmd_in_ert("\\begin{turn}{" + value + "}")
940 add_to_preamble(document, ["\\@ifundefined{turnbox}{\usepackage{rotating}}{}"])
943 def convert_table_rotation(document):
944 'Convert table rotation statements from "true" to "90"'
948 # first, let's find out if we need to do anything
949 i = find_token(document.body, '<features ', i)
952 j = document.body[i].find('rotate="true"')
954 rgx = re.compile(r'rotate="[^"]+?"')
955 # convert "true" to "90"
956 document.body[i] = rgx.sub('rotate="90"', document.body[i])
961 def convert_listoflistings(document):
962 'Convert ERT \lstlistoflistings to TOC lstlistoflistings inset'
963 # We can support roundtrip because the command is so simple
966 i = find_token(document.body, "\\begin_inset ERT", i)
969 j = find_end_of_inset(document.body, i)
971 document.warning("Malformed LyX document: Can't find end of ERT inset")
974 ert = get_ert(document.body, i)
975 if ert == "\\lstlistoflistings{}":
976 document.body[i:j] = ["\\begin_inset CommandInset toc", "LatexCommand lstlistoflistings", ""]
982 def revert_listoflistings(document):
983 'Convert TOC lstlistoflistings inset to ERT lstlistoflistings'
986 i = find_token(document.body, "\\begin_inset CommandInset toc", i)
989 if document.body[i+1] == "LatexCommand lstlistoflistings":
990 j = find_end_of_inset(document.body, i)
992 document.warning("Malformed LyX document: Can't find end of TOC inset")
995 subst = put_cmd_in_ert("\\lstlistoflistings{}")
996 document.body[i:j+1] = subst
997 add_to_preamble(document, ["\\usepackage{listings}"])
1001 def convert_use_amssymb(document):
1002 "insert use_package amssymb"
1003 regexp = re.compile(r'(\\use_package\s+amsmath)')
1004 i = find_re(document.header, regexp, 0)
1006 document.warning("Malformed LyX document: Can't find \\use_package amsmath.")
1008 value = get_value(document.header, "\\use_package" , i).split()[1]
1011 useamsmath = int(value)
1013 document.warning("Invalid \\use_package amsmath: " + value + ". Assuming auto.")
1015 j = find_token(document.preamble, "\\usepackage{amssymb}", 0)
1017 document.header.insert(i + 1, "\\use_package amssymb %d" % useamsmath)
1019 document.header.insert(i + 1, "\\use_package amssymb 2")
1020 del document.preamble[j]
1023 def revert_use_amssymb(document):
1024 "remove use_package amssymb"
1025 regexp1 = re.compile(r'(\\use_package\s+amsmath)')
1026 regexp2 = re.compile(r'(\\use_package\s+amssymb)')
1027 i = find_re(document.header, regexp1, 0)
1028 j = find_re(document.header, regexp2, 0)
1029 value1 = "1" # default is auto
1030 value2 = "1" # default is auto
1032 value1 = get_value(document.header, "\\use_package" , i).split()[1]
1034 value2 = get_value(document.header, "\\use_package" , j).split()[1]
1035 del document.header[j]
1036 if value1 != value2 and value2 == "2": # on
1037 add_to_preamble(document, ["\\usepackage{amssymb}"])
1040 def convert_use_cancel(document):
1041 "insert use_package cancel"
1042 convert_use_package(document, "cancel")
1045 def revert_use_cancel(document):
1046 "remove use_package cancel"
1047 commands = ["cancel", "bcancel", "xcancel", "cancelto"]
1048 revert_use_package(document, "cancel", commands, True)
1051 def revert_ancientgreek(document):
1052 "Set the document language for ancientgreek to greek"
1054 if document.language == "ancientgreek":
1055 document.language = "greek"
1056 i = find_token(document.header, "\\language", 0)
1058 document.header[i] = "\\language greek"
1061 j = find_token(document.body, "\\lang ancientgreek", j)
1065 document.body[j] = document.body[j].replace("\\lang ancientgreek", "\\lang greek")
1069 def revert_languages(document):
1070 "Set the document language for new supported languages to English"
1073 "coptic", "divehi", "hindi", "kurmanji", "lao", "marathi", "occitan", "sanskrit",
1074 "syriac", "tamil", "telugu", "urdu"
1076 for n in range(len(languages)):
1077 if document.language == languages[n]:
1078 document.language = "english"
1079 i = find_token(document.header, "\\language", 0)
1081 document.header[i] = "\\language english"
1083 while j < len(document.body):
1084 j = find_token(document.body, "\\lang " + languages[n], j)
1086 document.body[j] = document.body[j].replace("\\lang " + languages[n], "\\lang english")
1089 j = len(document.body)
1092 def convert_armenian(document):
1093 "Use polyglossia and thus non-TeX fonts for Armenian"
1095 if document.language == "armenian":
1096 i = find_token(document.header, "\\use_non_tex_fonts", 0)
1098 document.header[i] = "\\use_non_tex_fonts true"
1101 def revert_armenian(document):
1102 "Use ArmTeX and thus TeX fonts for Armenian"
1104 if document.language == "armenian":
1105 i = find_token(document.header, "\\use_non_tex_fonts", 0)
1107 document.header[i] = "\\use_non_tex_fonts false"
1110 def revert_libertine(document):
1111 " Revert native libertine font definition to LaTeX "
1113 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1114 i = find_token(document.header, "\\font_roman libertine", 0)
1117 j = find_token(document.header, "\\font_osf true", 0)
1120 preamble = "\\usepackage"
1122 document.header[j] = "\\font_osf false"
1125 preamble += "[lining]"
1126 preamble += "{libertine-type1}"
1127 add_to_preamble(document, [preamble])
1128 document.header[i] = "\\font_roman default"
1131 def revert_txtt(document):
1132 " Revert native txtt font definition to LaTeX "
1134 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1135 i = find_token(document.header, "\\font_typewriter txtt", 0)
1137 preamble = "\\renewcommand{\\ttdefault}{txtt}"
1138 add_to_preamble(document, [preamble])
1139 document.header[i] = "\\font_typewriter default"
1142 def revert_mathdesign(document):
1143 " Revert native mathdesign font definition to LaTeX "
1145 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1151 i = find_token(document.header, "\\font_roman", 0)
1154 val = get_value(document.header, "\\font_roman", i)
1155 if val in mathdesign_dict.keys():
1156 preamble = "\\usepackage[%s" % mathdesign_dict[val]
1158 j = find_token(document.header, "\\font_osf true", 0)
1161 document.header[j] = "\\font_osf false"
1162 l = find_token(document.header, "\\font_sc true", 0)
1165 document.header[l] = "\\font_sc false"
1167 preamble += ",expert"
1168 preamble += "]{mathdesign}"
1169 add_to_preamble(document, [preamble])
1170 document.header[i] = "\\font_roman default"
1173 def revert_texgyre(document):
1174 " Revert native TeXGyre font definition to LaTeX "
1176 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1177 texgyre_fonts = ["tgadventor", "tgbonum", "tgchorus", "tgcursor", \
1178 "tgheros", "tgpagella", "tgschola", "tgtermes"]
1179 i = find_token(document.header, "\\font_roman", 0)
1181 val = get_value(document.header, "\\font_roman", i)
1182 if val in texgyre_fonts:
1183 preamble = "\\usepackage{%s}" % val
1184 add_to_preamble(document, [preamble])
1185 document.header[i] = "\\font_roman default"
1186 i = find_token(document.header, "\\font_sans", 0)
1188 val = get_value(document.header, "\\font_sans", i)
1189 if val in texgyre_fonts:
1190 preamble = "\\usepackage{%s}" % val
1191 add_to_preamble(document, [preamble])
1192 document.header[i] = "\\font_sans default"
1193 i = find_token(document.header, "\\font_typewriter", 0)
1195 val = get_value(document.header, "\\font_typewriter", i)
1196 if val in texgyre_fonts:
1197 preamble = "\\usepackage{%s}" % val
1198 add_to_preamble(document, [preamble])
1199 document.header[i] = "\\font_typewriter default"
1202 def revert_ipadeco(document):
1203 " Revert IPA decorations to ERT "
1206 i = find_token(document.body, "\\begin_inset IPADeco", i)
1209 end = find_end_of_inset(document.body, i)
1211 document.warning("Can't find end of inset at line " + str(i))
1214 line = document.body[i]
1215 rx = re.compile(r'\\begin_inset IPADeco (.*)$')
1217 decotype = m.group(1)
1218 if decotype != "toptiebar" and decotype != "bottomtiebar":
1219 document.warning("Invalid IPADeco type: " + decotype)
1222 blay = find_token(document.body, "\\begin_layout Plain Layout", i, end)
1224 document.warning("Can't find layout for inset at line " + str(i))
1227 bend = find_end_of_layout(document.body, blay)
1229 document.warning("Malformed LyX document: Could not find end of IPADeco inset's layout.")
1232 substi = ["\\begin_inset ERT", "status collapsed", "",
1233 "\\begin_layout Plain Layout", "", "", "\\backslash",
1234 decotype + "{", "\\end_layout", "", "\\end_inset"]
1235 substj = ["\\size default", "", "\\begin_inset ERT", "status collapsed", "",
1236 "\\begin_layout Plain Layout", "", "}", "\\end_layout", "", "\\end_inset"]
1237 # do the later one first so as not to mess up the numbering
1238 document.body[bend:end + 1] = substj
1239 document.body[i:blay + 1] = substi
1240 i = end + len(substi) + len(substj) - (end - bend) - (blay - i) - 2
1241 add_to_preamble(document, "\\usepackage{tipa}")
1244 def revert_ipachar(document):
1245 ' Revert \\IPAChar to ERT '
1248 while i < len(document.body):
1249 m = re.match(r'(.*)\\IPAChar \\(\w+\{\w+\})(.*)', document.body[i])
1253 ipachar = m.group(2)
1256 '\\begin_inset ERT',
1257 'status collapsed', '',
1258 '\\begin_layout Standard',
1259 '', '', '\\backslash',
1264 document.body[i: i+1] = subst
1269 add_to_preamble(document, "\\usepackage{tone}")
1272 def revert_minionpro(document):
1273 " Revert native MinionPro font definition to LaTeX "
1275 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1276 i = find_token(document.header, "\\font_roman minionpro", 0)
1279 j = find_token(document.header, "\\font_osf true", 0)
1282 preamble = "\\usepackage"
1284 document.header[j] = "\\font_osf false"
1287 preamble += "{MinionPro}"
1288 add_to_preamble(document, [preamble])
1289 document.header[i] = "\\font_roman default"
1292 def revert_mathfonts(document):
1293 " Revert native math font definitions to LaTeX "
1295 i = find_token(document.header, "\\font_math", 0)
1298 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1299 val = get_value(document.header, "\\font_math", i)
1300 if val == "eulervm":
1301 add_to_preamble(document, "\\usepackage{eulervm}")
1302 elif val == "default":
1304 "lmodern": "\\renewcommand{\\rmdefault}{lmr}",
1305 "minionpro": "\\usepackage[onlytext,lf]{MinionPro}",
1306 "minionpro-osf": "\\usepackage[onlytext]{MinionPro}",
1307 "palatino": "\\renewcommand{\\rmdefault}{ppl}",
1308 "palatino-osf": "\\renewcommand{\\rmdefault}{pplj}",
1309 "times": "\\renewcommand{\\rmdefault}{ptm}",
1310 "utopia": "\\renewcommand{\\rmdefault}{futs}",
1311 "utopia-osf": "\\renewcommand{\\rmdefault}{futj}",
1313 j = find_token(document.header, "\\font_roman", 0)
1315 rm = get_value(document.header, "\\font_roman", j)
1316 k = find_token(document.header, "\\font_osf true", 0)
1319 if rm in mathfont_dict.keys():
1320 add_to_preamble(document, mathfont_dict[rm])
1321 document.header[j] = "\\font_roman default"
1323 document.header[k] = "\\font_osf false"
1324 del document.header[i]
1327 def revert_mdnomath(document):
1328 " Revert mathdesign and fourier without math "
1330 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1332 "md-charter": "mdbch",
1333 "md-utopia": "mdput",
1334 "md-garamond": "mdugm"
1336 i = find_token(document.header, "\\font_roman", 0)
1339 val = get_value(document.header, "\\font_roman", i)
1340 if val in mathdesign_dict.keys():
1341 j = find_token(document.header, "\\font_math", 0)
1343 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1344 mval = get_value(document.header, "\\font_math", j)
1345 if mval == "default":
1346 document.header[i] = "\\font_roman default"
1347 add_to_preamble(document, "\\renewcommand{\\rmdefault}{%s}" % mathdesign_dict[val])
1349 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1352 def convert_mdnomath(document):
1353 " Change mathdesign font name "
1355 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1357 "mdbch": "md-charter",
1358 "mdput": "md-utopia",
1359 "mdugm": "md-garamond"
1361 i = find_token(document.header, "\\font_roman", 0)
1364 val = get_value(document.header, "\\font_roman", i)
1365 if val in mathdesign_dict.keys():
1366 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1369 def revert_newtxmath(document):
1370 " Revert native newtxmath definitions to LaTeX "
1372 i = find_token(document.header, "\\font_math", 0)
1375 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1376 val = get_value(document.header, "\\font_math", i)
1378 "libertine-ntxm": "\\usepackage[libertine]{newtxmath}",
1379 "minion-ntxm": "\\usepackage[minion]{newtxmath}",
1380 "newtxmath": "\\usepackage{newtxmath}",
1382 if val in mathfont_dict.keys():
1383 add_to_preamble(document, mathfont_dict[val])
1384 document.header[i] = "\\font_math auto"
1387 def revert_biolinum(document):
1388 " Revert native biolinum font definition to LaTeX "
1390 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1391 i = find_token(document.header, "\\font_sans biolinum", 0)
1394 j = find_token(document.header, "\\font_osf true", 0)
1397 preamble = "\\usepackage"
1400 preamble += "{biolinum-type1}"
1401 add_to_preamble(document, [preamble])
1402 document.header[i] = "\\font_sans default"
1405 def revert_uop(document):
1406 " Revert native URW Classico (Optima) font definition to LaTeX "
1408 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1409 i = find_token(document.header, "\\font_sans uop", 0)
1411 preamble = "\\renewcommand{\\sfdefault}{uop}"
1412 add_to_preamble(document, [preamble])
1413 document.header[i] = "\\font_sans default"
1416 def convert_latexargs(document):
1417 " Convert InsetArgument to new syntax "
1419 if find_token(document.body, "\\begin_inset Argument", 0) == -1:
1423 # A list of layouts (document classes) with only optional or no arguments.
1424 # These can be safely converted to the new syntax
1425 # (I took the liberty to add some of my personal layouts/modules here; JSP)
1426 safe_layouts = ["aa", "aapaper", "aastex", "achemso", "acmsiggraph", "AEA",
1427 "agu-dtd", "agums", "agutex", "amsart", "amsbook", "apa",
1428 "arab-article", "armenian-article", "article-beamer", "article",
1429 "beamer", "book", "broadway", "chess", "cl2emult", "ctex-article",
1430 "ctex-book", "ctex-report", "dinbrief", "docbook-book", "docbook-chapter",
1431 "docbook", "docbook-section", "doublecol-new", "dtk", "ectaart", "egs",
1432 "elsarticle", "elsart", "entcs", "europecv", "extarticle", "extbook",
1433 "extletter", "extreport", "foils", "frletter", "g-brief2", "g-brief",
1434 "heb-article", "heb-letter", "hollywood", "IEEEtran", "ijmpc", "ijmpd",
1435 "iopart", "isprs", "jarticle", "jasatex", "jbook", "jgrga", "jreport",
1436 "jsarticle", "jsbeamer", "jsbook", "jss", "kluwer", "latex8", "letter", "lettre",
1437 "literate-article", "literate-book", "literate-report", "llncs", "ltugboat",
1438 "memoir", "moderncv", "mwart", "mwbk", "mwrep", "paper", "powerdot",
1439 "recipebook", "report", "revtex4", "revtex", "scrartcl", "scrarticle-beamer",
1440 "scrbook", "scrlettr", "scrlttr2", "scrreprt", "seminar", "siamltex",
1441 "sigplanconf", "simplecv", "singlecol", "singlecol-new", "slides", "spie",
1442 "svglobal3", "svglobal", "svjog", "svmono", "svmult", "svprobth", "tarticle",
1443 "tbook", "treport", "tufte-book", "tufte-handout"]
1444 # A list of "safe" modules, same as above
1445 safe_modules = ["biblatex", "beameraddons", "beamersession", "braille", "customHeadersFooters",
1446 "endnotes", "enumitem", "eqs-within-sections", "figs-within-sections", "fix-cm",
1447 "fixltx2e", "foottoend", "hanging", "jscharstyles", "knitr", "lilypond",
1448 "linguistics", "linguisticx", "logicalmkup", "minimalistic", "nomindex", "noweb",
1449 "pdfcomment", "sweave", "tabs-within-sections", "theorems-ams-bytype",
1450 "theorems-ams-extended-bytype", "theorems-ams-extended", "theorems-ams", "theorems-bytype",
1451 "theorems-chap-bytype", "theorems-chap", "theorems-named", "theorems-sec-bytype",
1452 "theorems-sec", "theorems-starred", "theorems-std", "todonotes"]
1453 # Modules we need to take care of
1454 caveat_modules = ["initials"]
1455 # information about the relevant styles in caveat_modules (number of opt and req args)
1456 # use this if we get more caveat_modules. For now, use hard coding (see below).
1457 # initials = [{'Layout' : 'Initial', 'opt' : 1, 'req' : 1}]
1459 # Is this a known safe layout?
1460 safe_layout = document.textclass in safe_layouts
1462 document.warning("Lyx2lyx knows nothing about textclass '%s'. "
1463 "Please check if short title insets have been converted correctly."
1464 % document.textclass)
1465 # Do we use unsafe or unknown modules
1466 mods = document.get_module_list()
1467 unknown_modules = False
1468 used_caveat_modules = list()
1470 if mod in safe_modules:
1472 if mod in caveat_modules:
1473 used_caveat_modules.append(mod)
1475 unknown_modules = True
1476 document.warning("Lyx2lyx knows nothing about module '%s'. "
1477 "Please check if short title insets have been converted correctly."
1482 i = find_token(document.body, "\\begin_inset Argument", i)
1486 if not safe_layout or unknown_modules:
1487 # We cannot do more here since we have no access to this layout.
1488 # InsetArgument itself will do the real work
1489 # (see InsetArgument::updateBuffer())
1490 document.body[i] = "\\begin_inset Argument 999"
1494 # Find containing paragraph layout
1495 parent = get_containing_layout(document.body, i)
1497 document.warning("Malformed LyX document: Can't find parent paragraph layout")
1504 if len(used_caveat_modules) > 0:
1505 # We know for now that this must be the initials module with the Initial layout
1506 # If we get more such modules, we need some automating.
1507 if parent[0] == "Initial":
1508 # Layout has 1 opt and 1 req arg.
1509 # Count the actual arguments
1511 for p in range(parbeg, parend):
1512 if document.body[p] == "\\begin_inset Argument":
1517 # Collect all arguments in this paragraph
1519 for p in range(parbeg, parend):
1520 if document.body[p] == "\\begin_inset Argument":
1522 if allowed_opts != -1:
1523 # We have less arguments than opt + required.
1524 # required must take precedence.
1525 if argnr > allowed_opts and argnr < first_req:
1527 document.body[p] = "\\begin_inset Argument %d" % argnr
1531 def revert_latexargs(document):
1532 " Revert InsetArgument to old syntax "
1535 rx = re.compile(r'^\\begin_inset Argument (\d+)$')
1538 # Search for Argument insets
1539 i = find_token(document.body, "\\begin_inset Argument", i)
1542 m = rx.match(document.body[i])
1544 # No ID: inset already reverted
1547 # Find containing paragraph layout
1548 parent = get_containing_layout(document.body, i)
1550 document.warning("Malformed LyX document: Can't find parent paragraph layout")
1555 # Do not set realparbeg to parent[3], since this does not work if we
1556 # have another inset (e.g. label or index) before the first argument
1557 # inset (this is the case in the user guide of LyX 2.0.8)
1559 # Collect all arguments in this paragraph
1561 for p in range(parbeg, parend):
1562 m = rx.match(document.body[p])
1565 # This is the first argument inset
1567 val = int(m.group(1))
1568 j = find_end_of_inset(document.body, p)
1569 # Revert to old syntax
1570 document.body[p] = "\\begin_inset Argument"
1572 document.warning("Malformed LyX document: Can't find end of Argument inset")
1575 args[val] = document.body[p : j + 1]
1577 realparend = realparend - len(document.body[p : j + 1])
1578 # Remove arg inset at this position
1579 del document.body[p : j + 1]
1583 # No argument inset found
1584 realparbeg = parent[3]
1585 # Now sort the arg insets
1587 for f in sorted(args):
1590 # Insert the sorted arg insets at paragraph begin
1591 document.body[realparbeg : realparbeg] = subst
1593 i = realparbeg + 1 + len(subst)
1596 def revert_IEEEtran(document):
1598 Reverts InsetArgument of
1601 Biography without photo
1604 if document.textclass == "IEEEtran":
1611 i = find_token(document.body, "\\begin_layout Page headings", i)
1613 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1616 i2 = find_token(document.body, "\\begin_inset Flex Paragraph Start", i2)
1618 revert_Argument_to_TeX_brace(document, i2, 0, 1, 1, False, False)
1621 j = find_token(document.body, "\\begin_layout Biography without photo", j)
1623 revert_Argument_to_TeX_brace(document, j, 0, 1, 1, True, False)
1626 k = find_token(document.body, "\\begin_layout Biography", k)
1627 kA = find_token(document.body, "\\begin_layout Biography without photo", k)
1628 if k == kA and k != -1:
1632 # start with the second argument, therefore 2
1633 revert_Argument_to_TeX_brace(document, k, 0, 2, 2, True, False)
1635 if i == -1 and i2 == -1 and j == -1 and k == -1:
1639 def revert_IEEEtran_2(document):
1641 Reverts Flex Paragraph Start to TeX-code
1643 if document.textclass == "IEEEtran":
1646 begin = find_token(document.body, "\\begin_inset Flex Paragraph Start", begin)
1649 end1 = find_end_of_inset(document.body, begin)
1650 document.body[end1 - 2 : end1 + 1] = put_cmd_in_ert("}")
1651 document.body[begin : begin + 4] = put_cmd_in_ert("\\IEEEPARstart{")
1655 def convert_IEEEtran(document):
1660 Biography without photo
1663 if document.textclass == "IEEEtran":
1669 i = find_token(document.body, "\\begin_layout Page headings", i)
1671 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
1674 j = find_token(document.body, "\\begin_layout Biography without photo", j)
1676 convert_TeX_brace_to_Argument(document, j, 1, 1, False, True, False)
1679 # assure that we don't handle Biography Biography without photo
1680 k = find_token(document.body, "\\begin_layout Biography", k)
1681 kA = find_token(document.body, "\\begin_layout Biography without photo", k - 1)
1682 if k == kA and k != -1:
1686 # the argument we want to convert is the second one
1687 convert_TeX_brace_to_Argument(document, k, 2, 2, False, True, False)
1689 if i == -1 and j == -1 and k == -1:
1693 def revert_AASTeX(document):
1694 " Reverts InsetArgument of Altaffilation to TeX-code "
1695 if document.textclass == "aastex":
1698 i = find_token(document.body, "\\begin_layout Altaffilation", i)
1701 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1705 def convert_AASTeX(document):
1706 " Converts ERT of Altaffilation to InsetArgument "
1707 if document.textclass == "aastex":
1710 i = find_token(document.body, "\\begin_layout Altaffilation", i)
1713 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
1717 def revert_AGUTeX(document):
1718 " Reverts InsetArgument of Author affiliation to TeX-code "
1719 if document.textclass == "agutex":
1722 i = find_token(document.body, "\\begin_layout Author affiliation", i)
1725 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1729 def convert_AGUTeX(document):
1730 " Converts ERT of Author affiliation to InsetArgument "
1731 if document.textclass == "agutex":
1734 i = find_token(document.body, "\\begin_layout Author affiliation", i)
1737 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
1741 def revert_IJMP(document):
1742 " Reverts InsetArgument of MarkBoth to TeX-code "
1743 if document.textclass == "ijmpc" or document.textclass == "ijmpd":
1746 i = find_token(document.body, "\\begin_layout MarkBoth", i)
1749 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1753 def convert_IJMP(document):
1754 " Converts ERT of MarkBoth to InsetArgument "
1755 if document.textclass == "ijmpc" or document.textclass == "ijmpd":
1758 i = find_token(document.body, "\\begin_layout MarkBoth", i)
1761 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
1765 def revert_SIGPLAN(document):
1766 " Reverts InsetArguments of SIGPLAN to TeX-code "
1767 if document.textclass == "sigplanconf":
1772 i = find_token(document.body, "\\begin_layout Conference", i)
1774 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1777 j = find_token(document.body, "\\begin_layout Author", j)
1779 revert_Argument_to_TeX_brace(document, j, 0, 1, 2, False, False)
1781 if i == -1 and j == -1:
1785 def convert_SIGPLAN(document):
1786 " Converts ERT of SIGPLAN to InsetArgument "
1787 if document.textclass == "sigplanconf":
1792 i = find_token(document.body, "\\begin_layout Conference", i)
1794 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
1797 j = find_token(document.body, "\\begin_layout Author", j)
1799 convert_TeX_brace_to_Argument(document, j, 1, 2, False, False, False)
1801 if i == -1 and j == -1:
1805 def revert_SIGGRAPH(document):
1806 " Reverts InsetArgument of Flex CRcat to TeX-code "
1807 if document.textclass == "acmsiggraph":
1810 i = find_token(document.body, "\\begin_inset Flex CRcat", i)
1813 revert_Argument_to_TeX_brace(document, i, 0, 1, 3, False, False)
1817 def convert_SIGGRAPH(document):
1818 " Converts ERT of Flex CRcat to InsetArgument "
1819 if document.textclass == "acmsiggraph":
1822 i = find_token(document.body, "\\begin_inset Flex CRcat", i)
1825 convert_TeX_brace_to_Argument(document, i, 1, 3, True, False, False)
1829 def revert_EuropeCV(document):
1830 " Reverts InsetArguments of europeCV to TeX-code "
1831 if document.textclass == "europecv":
1838 i = find_token(document.body, "\\begin_layout Item", i)
1840 revert_Argument_to_TeX_brace(document, i, 0, 2, 2, False, False)
1843 j = find_token(document.body, "\\begin_layout BulletedItem", j)
1845 revert_Argument_to_TeX_brace(document, j, 0, 2, 2, False, False)
1848 k = find_token(document.body, "\\begin_layout Language", k)
1850 revert_Argument_to_TeX_brace(document, k, 0, 2, 6, False, False)
1853 m = find_token(document.body, "\\begin_layout LastLanguage", m)
1855 revert_Argument_to_TeX_brace(document, m, 0, 2, 6, False, False)
1857 if i == -1 and j == -1 and k == -1 and m == -1:
1861 def convert_EuropeCV(document):
1862 " Converts ERT of europeCV to InsetArgument "
1863 if document.textclass == "europecv":
1870 i = find_token(document.body, "\\begin_layout Item", i)
1872 convert_TeX_brace_to_Argument(document, i, 2, 2, False, False, False)
1875 j = find_token(document.body, "\\begin_layout BulletedItem", j)
1877 convert_TeX_brace_to_Argument(document, j, 2, 2, False, False, False)
1880 k = find_token(document.body, "\\begin_layout Language", k)
1882 convert_TeX_brace_to_Argument(document, k, 2, 6, False, False, False)
1885 m = find_token(document.body, "\\begin_layout LastLanguage", m)
1887 convert_TeX_brace_to_Argument(document, m, 2, 6, False, False, False)
1889 if i == -1 and j == -1 and k == -1 and m == -1:
1893 def revert_ModernCV(document):
1894 " Reverts InsetArguments of modernCV to TeX-code "
1895 if document.textclass == "moderncv":
1903 j = find_token(document.body, "\\begin_layout Entry", j)
1905 revert_Argument_to_TeX_brace(document, j, 0, 1, 5, False, False)
1908 k = find_token(document.body, "\\begin_layout Item", k)
1910 revert_Argument_to_TeX_brace(document, k, 0, 1, 1, False, False)
1913 m = find_token(document.body, "\\begin_layout ItemWithComment", m)
1915 revert_Argument_to_TeX_brace(document, m, 0, 1, 2, False, False)
1916 document.body[m] = document.body[m].replace("\\begin_layout ItemWithComment", "\\begin_layout Language")
1919 o = find_token(document.body, "\\begin_layout DoubleItem", o)
1921 revert_Argument_to_TeX_brace(document, o, 0, 1, 3, False, False)
1922 document.body[o] = document.body[o].replace("\\begin_layout DoubleItem", "\\begin_layout Computer")
1925 p = find_token(document.body, "\\begin_layout Social", p)
1927 revert_Argument_to_TeX_brace(document, p, 0, 1, 1, False, True)
1929 if j == -1 and k == -1 and m == -1 and o == -1 and p == -1:
1933 def revert_ModernCV_2(document):
1934 " Reverts the Flex:Column inset of modernCV to TeX-code "
1935 if document.textclass == "moderncv":
1939 flex = find_token(document.body, "\\begin_inset Flex Column", flex)
1942 flexEnd = find_end_of_inset(document.body, flex)
1943 wasOpt = revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, False, True)
1944 revert_Argument_to_TeX_brace(document, flex, 0, 2, 2, False, False)
1945 flexEnd = find_end_of_inset(document.body, flex)
1947 document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\cvcolumn")
1949 document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\cvcolumn{")
1950 document.body[flexEnd + 4 : flexEnd + 7] = put_cmd_in_ert("}")
1954 def revert_ModernCV_3(document):
1955 " Reverts the Column style of modernCV to TeX-code "
1956 if document.textclass == "moderncv":
1957 # revert the layouts
1958 revert_ModernCV(document)
1960 # get the position of the end of the last column inset
1961 LastFlexEnd = revert_ModernCV_2(document)
1963 p = find_token(document.body, "\\begin_layout Columns", p)
1966 pEnd = find_end_of_layout(document.body, p)
1967 document.body[p] = document.body[p].replace("\\begin_layout Columns", "\\begin_layout Standard")
1968 if LastFlexEnd != -1:
1969 document.body[p + 1 : p + 1] = put_cmd_in_ert("\\begin{cvcolumns}")
1970 document.body[LastFlexEnd + 24 : LastFlexEnd + 24] = put_cmd_in_ert("\\end{cvcolumns}")
1974 def revert_ModernCV_4(document):
1975 " Reverts the style Social to TeX-code "
1976 if document.textclass == "moderncv":
1977 # revert the layouts
1978 revert_ModernCV(document)
1981 p = find_token(document.body, "\\begin_layout Social", p)
1984 pEnd = find_end_of_layout(document.body, p)
1985 document.body[p] = document.body[p].replace("\\begin_layout Social", "\\begin_layout Standard")
1986 document.body[p + 1 : p + 1] = put_cmd_in_ert("\\social")
1987 hasOpt = find_token(document.body, "[", p + 9)
1989 document.body[p + 30 : p + 30] = put_cmd_in_ert("{")
1990 document.body[p + 41 : p + 41] = put_cmd_in_ert("}")
1992 document.body[p + 11 : p + 11] = put_cmd_in_ert("{")
1993 document.body[p + 21 : p + 21] = put_cmd_in_ert("}")
1997 def convert_ModernCV(document):
1998 " Converts ERT of modernCV to InsetArgument "
1999 if document.textclass == "moderncv":
2007 i = find_token(document.body, "\\begin_layout DoubleItem", i)
2009 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
2010 document.body[o] = document.body[o].replace("\\begin_layout DoubleItem", "\\begin_layout DoubleListItem")
2013 j = find_token(document.body, "\\begin_layout Entry", j)
2015 convert_TeX_brace_to_Argument(document, j, 1, 5, False, False, False)
2018 k = find_token(document.body, "\\begin_layout Item", k)
2020 convert_TeX_brace_to_Argument(document, k, 1, 1, False, False, False)
2023 m = find_token(document.body, "\\begin_layout Language", m)
2025 convert_TeX_brace_to_Argument(document, m, 1, 2, False, False, False)
2027 if i == -1 and j == -1 and k == -1 and m == -1:
2031 def revert_Initials(document):
2032 " Reverts InsetArgument of Initial to TeX-code "
2035 i = find_token(document.body, "\\begin_layout Initial", i)
2038 # first arg (optional) and second arg (first mandatory) are supported in LyX 2.0.x
2039 revert_Argument_to_TeX_brace(document, i, 0, 3, 3, False, False)
2043 def convert_Initials(document):
2044 " Converts ERT of Initial to InsetArgument "
2047 i = find_token(document.body, "\\begin_layout Initial", i)
2050 convert_TeX_brace_to_Argument(document, i, 3, 3, False, False, False)
2054 def revert_literate(document):
2055 " Revert Literate document to old format "
2056 if del_token(document.header, "noweb", 0):
2057 document.textclass = "literate-" + document.textclass
2060 i = find_token(document.body, "\\begin_layout Chunk", i)
2063 document.body[i] = "\\begin_layout Scrap"
2067 def convert_literate(document):
2068 " Convert Literate document to new format"
2069 i = find_token(document.header, "\\textclass", 0)
2070 if (i != -1) and "literate-" in document.header[i]:
2071 document.textclass = document.header[i].replace("\\textclass literate-", "")
2072 j = find_token(document.header, "\\begin_modules", 0)
2074 document.header.insert(j + 1, "noweb")
2076 document.header.insert(i + 1, "\\end_modules")
2077 document.header.insert(i + 1, "noweb")
2078 document.header.insert(i + 1, "\\begin_modules")
2081 i = find_token(document.body, "\\begin_layout Scrap", i)
2084 document.body[i] = "\\begin_layout Chunk"
2088 def revert_itemargs(document):
2089 " Reverts \\item arguments to TeX-code "
2092 i = find_token(document.body, "\\begin_inset Argument item:", i)
2095 j = find_end_of_inset(document.body, i)
2096 # Find containing paragraph layout
2097 parent = get_containing_layout(document.body, i)
2099 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2103 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2104 endPlain = find_end_of_layout(document.body, beginPlain)
2105 content = document.body[beginPlain + 1 : endPlain]
2106 del document.body[i:j+1]
2107 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2108 document.body[parbeg : parbeg] = subst
2112 def revert_garamondx_newtxmath(document):
2113 " Revert native garamond newtxmath definition to LaTeX "
2115 i = find_token(document.header, "\\font_math", 0)
2118 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
2119 val = get_value(document.header, "\\font_math", i)
2120 if val == "garamondx-ntxm":
2121 add_to_preamble(document, "\\usepackage[garamondx]{newtxmath}")
2122 document.header[i] = "\\font_math auto"
2125 def revert_garamondx(document):
2126 " Revert native garamond font definition to LaTeX "
2128 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
2129 i = find_token(document.header, "\\font_roman garamondx", 0)
2132 j = find_token(document.header, "\\font_osf true", 0)
2135 preamble = "\\usepackage"
2137 preamble += "[osfI]"
2138 preamble += "{garamondx}"
2139 add_to_preamble(document, [preamble])
2140 document.header[i] = "\\font_roman default"
2143 def convert_beamerargs(document):
2144 " Converts beamer arguments to new layout "
2146 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2147 if document.textclass not in beamer_classes:
2150 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
2151 list_layouts = ["Itemize", "Enumerate", "Description"]
2152 rx = re.compile(r'^\\begin_inset Argument (\d+)$')
2156 i = find_token(document.body, "\\begin_inset Argument", i)
2159 # Find containing paragraph layout
2160 parent = get_containing_layout(document.body, i)
2162 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2167 layoutname = parent[0]
2168 for p in range(parbeg, parend):
2169 if layoutname in shifted_layouts:
2170 m = rx.match(document.body[p])
2172 argnr = int(m.group(1))
2174 document.body[p] = "\\begin_inset Argument %d" % argnr
2175 if layoutname == "AgainFrame":
2176 m = rx.match(document.body[p])
2178 document.body[p] = "\\begin_inset Argument 3"
2179 if document.body[p + 4] == "\\begin_inset ERT":
2180 if document.body[p + 9].startswith("<"):
2181 # This is an overlay specification
2183 document.body[p + 9] = document.body[p + 9][1:]
2184 if document.body[p + 9].endswith(">"):
2186 document.body[p + 9] = document.body[p + 9][:-1]
2188 document.body[p] = "\\begin_inset Argument 2"
2189 if layoutname in list_layouts:
2190 m = rx.match(document.body[p])
2192 if m.group(1) == "1":
2193 if document.body[p + 4] == "\\begin_inset ERT":
2194 if document.body[p + 9].startswith("<"):
2195 # This is an overlay specification
2197 document.body[p + 9] = document.body[p + 9][1:]
2198 if document.body[p + 9].endswith(">"):
2200 document.body[p + 9] = document.body[p + 9][:-1]
2201 elif document.body[p + 4].startswith("<"):
2202 # This is an overlay specification (without ERT)
2204 document.body[p + 4] = document.body[p + 4][1:]
2205 if document.body[p + 4].endswith(">"):
2207 document.body[p + 4] = document.body[p + 4][:-1]
2208 elif layoutname != "Itemize":
2210 document.body[p] = "\\begin_inset Argument 2"
2215 # Helper function for the frame conversion routines
2217 # FIXME: This method currently requires the arguments to be either
2218 # * In one (whole) ERT each: <ERT>[<arg1>]</ERT><ERT><arg2></ERT><ERT>[arg3]</ERT>
2219 # * Altogether in one whole ERT: <ERT>[<arg1>]<arg2>[arg3]</ERT>
2220 # If individual arguments mix ERT and non-ERT or are splitted
2221 # over several ERTs, the parsing fails.
2222 def convert_beamerframeargs(document, i, parbeg):
2225 if document.body[parbeg] != "\\begin_inset ERT":
2227 ertend = find_end_of_inset(document.body, parbeg)
2229 document.warning("Malformed LyX document: missing ERT \\end_inset")
2231 ertcont = parbeg + 5
2232 if document.body[ertcont].startswith("[<"):
2233 # This is a default overlay specification
2235 document.body[ertcont] = document.body[ertcont][2:]
2236 if document.body[ertcont].endswith(">]"):
2238 document.body[ertcont] = document.body[ertcont][:-2]
2239 elif document.body[ertcont].endswith("]"):
2241 tok = document.body[ertcont].find('>][')
2243 subst = [document.body[ertcont][:tok],
2244 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2245 'status collapsed', '', '\\begin_layout Plain Layout',
2246 document.body[ertcont][tok + 3:-1]]
2247 document.body[ertcont : ertcont + 1] = subst
2249 # Convert to ArgInset
2250 document.body[parbeg] = "\\begin_inset Argument 2"
2251 elif document.body[ertcont].startswith("<"):
2252 # This is an overlay specification
2254 document.body[ertcont] = document.body[ertcont][1:]
2255 if document.body[ertcont].endswith(">"):
2257 document.body[ertcont] = document.body[ertcont][:-1]
2258 # Convert to ArgInset
2259 document.body[parbeg] = "\\begin_inset Argument 1"
2260 elif document.body[ertcont].endswith(">]"):
2262 tok = document.body[ertcont].find('>[<')
2264 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2265 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2266 'status collapsed', '', '\\begin_layout Plain Layout',
2267 document.body[ertcont][tok + 3:-2]]
2268 # Convert to ArgInset
2269 document.body[parbeg] = "\\begin_inset Argument 1"
2271 elif document.body[ertcont].endswith("]"):
2273 tok = document.body[ertcont].find('>[<')
2276 tokk = document.body[ertcont].find('>][')
2278 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2279 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2280 'status collapsed', '', '\\begin_layout Plain Layout',
2281 document.body[ertcont][tok + 3:tokk],
2282 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2283 'status collapsed', '', '\\begin_layout Plain Layout',
2284 document.body[ertcont][tokk + 3:-1]]
2287 tokk = document.body[ertcont].find('>[')
2289 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tokk],
2290 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2291 'status collapsed', '', '\\begin_layout Plain Layout',
2292 document.body[ertcont][tokk + 2:-1]]
2294 # Convert to ArgInset
2295 document.body[parbeg] = "\\begin_inset Argument 1"
2296 elif document.body[ertcont].startswith("["):
2297 # This is an ERT option
2299 document.body[ertcont] = document.body[ertcont][1:]
2300 if document.body[ertcont].endswith("]"):
2302 document.body[ertcont] = document.body[ertcont][:-1]
2303 # Convert to ArgInset
2304 document.body[parbeg] = "\\begin_inset Argument 3"
2310 def convert_againframe_args(document):
2311 " Converts beamer AgainFrame to new layout "
2313 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2314 if document.textclass not in beamer_classes:
2319 i = find_token(document.body, "\\begin_layout AgainFrame", i)
2322 parent = get_containing_layout(document.body, i)
2324 document.warning("Wrong parent layout!")
2328 # Convert ERT arguments
2329 # FIXME: See restrictions in convert_beamerframeargs method
2330 ertend = convert_beamerframeargs(document, i, parbeg)
2336 def convert_corollary_args(document):
2337 " Converts beamer corrolary-style ERT arguments native InsetArgs "
2339 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2340 if document.textclass not in beamer_classes:
2343 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2344 for lay in corollary_layouts:
2347 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2350 parent = get_containing_layout(document.body, i)
2352 document.warning("Wrong parent layout!")
2356 if document.body[parbeg] == "\\begin_inset ERT":
2357 ertcont = parbeg + 5
2358 if document.body[ertcont].startswith("<"):
2359 # This is an overlay specification
2361 document.body[ertcont] = document.body[ertcont][1:]
2362 if document.body[ertcont].endswith(">"):
2364 document.body[ertcont] = document.body[ertcont][:-1]
2365 elif document.body[ertcont].endswith("]"):
2367 tok = document.body[ertcont].find('>[')
2369 subst = [document.body[ertcont][:tok],
2370 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2371 'status collapsed', '', '\\begin_layout Plain Layout',
2372 document.body[ertcont][tok + 2:-1]]
2373 document.body[ertcont : ertcont + 1] = subst
2374 # Convert to ArgInset
2375 document.body[parbeg] = "\\begin_inset Argument 1"
2378 elif document.body[ertcont].startswith("["):
2379 if document.body[ertcont].endswith("]"):
2380 # This is an ERT option
2382 document.body[ertcont] = document.body[ertcont][1:]
2384 document.body[ertcont] = document.body[ertcont][:-1]
2385 # Convert to ArgInset
2386 document.body[parbeg] = "\\begin_inset Argument 2"
2388 convert_TeX_brace_to_Argument(document, i, 2, 2, False, True, True)
2395 def convert_quote_args(document):
2396 " Converts beamer quote style ERT args to native InsetArgs "
2398 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2399 if document.textclass not in beamer_classes:
2402 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2403 for lay in quote_layouts:
2406 i = find_token(document.body, "\\begin_layout " + lay, i)
2409 parent = get_containing_layout(document.body, i)
2411 document.warning("Wrong parent layout!")
2415 if document.body[parbeg] == "\\begin_inset ERT":
2416 if document.body[i + 6].startswith("<"):
2417 # This is an overlay specification
2419 document.body[i + 6] = document.body[i + 6][1:]
2420 if document.body[i + 6].endswith(">"):
2422 document.body[i + 6] = document.body[i + 6][:-1]
2423 # Convert to ArgInset
2424 document.body[i + 1] = "\\begin_inset Argument 1"
2428 def revert_beamerargs(document):
2429 " Reverts beamer arguments to old layout "
2431 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2432 if document.textclass not in beamer_classes:
2436 list_layouts = ["Itemize", "Enumerate", "Description"]
2437 headings = ["Part", "Section", "Section*", "Subsection", "Subsection*",
2438 "Subsubsection", "Subsubsection*", "FrameSubtitle", "NoteItem"]
2439 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2440 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2441 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2444 i = find_token(document.body, "\\begin_inset Argument", i)
2447 # Find containing paragraph layout
2448 parent = get_containing_layout(document.body, i)
2450 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2455 realparbeg = parent[3]
2456 layoutname = parent[0]
2458 for p in range(parbeg, parend):
2462 if layoutname in headings:
2463 m = rx.match(document.body[p])
2467 # Find containing paragraph layout
2468 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2469 endPlain = find_end_of_layout(document.body, beginPlain)
2470 endInset = find_end_of_inset(document.body, p)
2471 argcontent = document.body[beginPlain + 1 : endPlain]
2473 realparend = realparend - len(document.body[p : endInset + 1])
2475 del document.body[p : endInset + 1]
2476 if layoutname == "FrameSubtitle":
2477 pre = put_cmd_in_ert("\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2478 elif layoutname == "NoteItem":
2479 pre = put_cmd_in_ert("\\note<") + argcontent + put_cmd_in_ert(">[item]")
2480 elif layoutname.endswith('*'):
2481 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower()[:-1] + "<") + argcontent + put_cmd_in_ert(">*")
2483 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2484 secarg = find_token(document.body, "\\begin_inset Argument 2", parbeg, parend)
2486 # Find containing paragraph layout
2487 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", secarg)
2488 endPlain = find_end_of_layout(document.body, beginPlain)
2489 endInset = find_end_of_inset(document.body, secarg)
2490 argcontent = document.body[beginPlain + 1 : endPlain]
2492 realparend = realparend - len(document.body[secarg : endInset + 1])
2493 del document.body[secarg : endInset + 1]
2494 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2495 pre += put_cmd_in_ert("{")
2496 document.body[parbeg] = "\\begin_layout Standard"
2497 document.body[realparbeg : realparbeg] = pre
2498 pe = find_end_of_layout(document.body, parbeg)
2499 post = put_cmd_in_ert("}")
2500 document.body[pe : pe] = post
2501 realparend += len(pre) + len(post)
2502 if layoutname == "AgainFrame":
2503 m = rx.match(document.body[p])
2507 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2508 endPlain = find_end_of_layout(document.body, beginPlain)
2509 endInset = find_end_of_inset(document.body, p)
2510 content = document.body[beginPlain + 1 : endPlain]
2512 realparend = realparend - len(document.body[p : endInset + 1])
2514 del document.body[p : endInset + 1]
2515 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2516 document.body[realparbeg : realparbeg] = subst
2517 if layoutname == "Overprint":
2518 m = rx.match(document.body[p])
2522 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2523 endPlain = find_end_of_layout(document.body, beginPlain)
2524 endInset = find_end_of_inset(document.body, p)
2525 content = document.body[beginPlain + 1 : endPlain]
2527 realparend = realparend - len(document.body[p : endInset + 1])
2529 del document.body[p : endInset + 1]
2530 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2531 document.body[realparbeg : realparbeg] = subst
2532 if layoutname == "OverlayArea":
2533 m = rx.match(document.body[p])
2537 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2538 endPlain = find_end_of_layout(document.body, beginPlain)
2539 endInset = find_end_of_inset(document.body, p)
2540 content = document.body[beginPlain + 1 : endPlain]
2542 realparend = realparend - len(document.body[p : endInset + 1])
2544 del document.body[p : endInset + 1]
2545 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2546 document.body[realparbeg : realparbeg] = subst
2547 if layoutname in list_layouts:
2548 m = rx.match(document.body[p])
2552 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2553 endPlain = find_end_of_layout(document.body, beginPlain)
2554 endInset = find_end_of_inset(document.body, p)
2555 content = document.body[beginPlain + 1 : endPlain]
2556 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2557 realparend = realparend + len(subst) - len(content)
2558 document.body[beginPlain + 1 : endPlain] = subst
2559 elif argnr == "item:1":
2560 j = find_end_of_inset(document.body, i)
2561 # Find containing paragraph layout
2562 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2563 endPlain = find_end_of_layout(document.body, beginPlain)
2564 content = document.body[beginPlain + 1 : endPlain]
2565 del document.body[i:j+1]
2566 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2567 document.body[realparbeg : realparbeg] = subst
2568 elif argnr == "item:2":
2569 j = find_end_of_inset(document.body, i)
2570 # Find containing paragraph layout
2571 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2572 endPlain = find_end_of_layout(document.body, beginPlain)
2573 content = document.body[beginPlain + 1 : endPlain]
2574 del document.body[i:j+1]
2575 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2576 document.body[realparbeg : realparbeg] = subst
2577 if layoutname in quote_layouts:
2578 m = rx.match(document.body[p])
2582 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2583 endPlain = find_end_of_layout(document.body, beginPlain)
2584 endInset = find_end_of_inset(document.body, p)
2585 content = document.body[beginPlain + 1 : endPlain]
2587 realparend = realparend - len(document.body[p : endInset + 1])
2589 del document.body[p : endInset + 1]
2590 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2591 document.body[realparbeg : realparbeg] = subst
2592 if layoutname in corollary_layouts:
2593 m = rx.match(document.body[p])
2597 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2598 endPlain = find_end_of_layout(document.body, beginPlain)
2599 endInset = find_end_of_inset(document.body, p)
2600 content = document.body[beginPlain + 1 : endPlain]
2602 realparend = realparend - len(document.body[p : endInset + 1])
2604 del document.body[p : endInset + 1]
2605 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2606 document.body[realparbeg : realparbeg] = subst
2611 def revert_beamerargs2(document):
2612 " Reverts beamer arguments to old layout, step 2 "
2614 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2615 if document.textclass not in beamer_classes:
2619 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
2620 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2621 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2624 i = find_token(document.body, "\\begin_inset Argument", i)
2627 # Find containing paragraph layout
2628 parent = get_containing_layout(document.body, i)
2630 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2635 realparbeg = parent[3]
2636 layoutname = parent[0]
2638 for p in range(parbeg, parend):
2642 if layoutname in shifted_layouts:
2643 m = rx.match(document.body[p])
2647 document.body[p] = "\\begin_inset Argument 1"
2648 if layoutname in corollary_layouts:
2649 m = rx.match(document.body[p])
2653 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2654 endPlain = find_end_of_layout(document.body, beginPlain)
2655 endInset = find_end_of_inset(document.body, p)
2656 content = document.body[beginPlain + 1 : endPlain]
2658 realparend = realparend - len(document.body[p : endInset + 1])
2660 del document.body[p : endInset + 1]
2661 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2662 document.body[realparbeg : realparbeg] = subst
2663 if layoutname == "OverlayArea":
2664 m = rx.match(document.body[p])
2668 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2669 endPlain = find_end_of_layout(document.body, beginPlain)
2670 endInset = find_end_of_inset(document.body, p)
2671 content = document.body[beginPlain + 1 : endPlain]
2673 realparend = realparend - len(document.body[p : endInset + 1])
2675 del document.body[p : endInset + 1]
2676 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2677 document.body[realparbeg : realparbeg] = subst
2678 if layoutname == "AgainFrame":
2679 m = rx.match(document.body[p])
2683 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2684 endPlain = find_end_of_layout(document.body, beginPlain)
2685 endInset = find_end_of_inset(document.body, p)
2686 content = document.body[beginPlain + 1 : endPlain]
2688 realparend = realparend - len(document.body[p : endInset + 1])
2690 del document.body[p : endInset + 1]
2691 subst = put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
2692 document.body[realparbeg : realparbeg] = subst
2696 def revert_beamerargs3(document):
2697 " Reverts beamer arguments to old layout, step 3 "
2699 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2700 if document.textclass not in beamer_classes:
2703 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2706 i = find_token(document.body, "\\begin_inset Argument", i)
2709 # Find containing paragraph layout
2710 parent = get_containing_layout(document.body, i)
2712 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2717 realparbeg = parent[3]
2718 layoutname = parent[0]
2720 for p in range(parbeg, parend):
2724 if layoutname == "AgainFrame":
2725 m = rx.match(document.body[p])
2729 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2730 endPlain = find_end_of_layout(document.body, beginPlain)
2731 endInset = find_end_of_inset(document.body, p)
2732 content = document.body[beginPlain + 1 : endPlain]
2734 realparend = realparend - len(document.body[p : endInset + 1])
2736 del document.body[p : endInset + 1]
2737 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2738 document.body[realparbeg : realparbeg] = subst
2742 def revert_beamerflex(document):
2743 " Reverts beamer Flex insets "
2745 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2746 if document.textclass not in beamer_classes:
2749 new_flexes = {"Bold" : "\\textbf", "Emphasize" : "\\emph", "Only" : "\\only",
2750 "Uncover" : "\\uncover", "Visible" : "\\visible",
2751 "Invisible" : "\\invisible", "Alternative" : "\\alt",
2752 "Beamer_Note" : "\\note"}
2753 old_flexes = {"Alert" : "\\alert", "Structure" : "\\structure"}
2754 rx = re.compile(r'^\\begin_inset Flex (.+)$')
2758 i = find_token(document.body, "\\begin_inset Flex", i)
2761 m = rx.match(document.body[i])
2763 flextype = m.group(1)
2764 z = find_end_of_inset(document.body, i)
2766 document.warning("Can't find end of Flex " + flextype + " inset.")
2769 if flextype in new_flexes:
2770 pre = put_cmd_in_ert(new_flexes[flextype])
2771 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2773 argend = find_end_of_inset(document.body, arg)
2775 document.warning("Can't find end of Argument!")
2778 # Find containing paragraph layout
2779 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2780 endPlain = find_end_of_layout(document.body, beginPlain)
2781 argcontent = document.body[beginPlain + 1 : endPlain]
2783 z = z - len(document.body[arg : argend + 1])
2785 del document.body[arg : argend + 1]
2786 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2787 arg = find_token(document.body, "\\begin_inset Argument 2", i, z)
2789 argend = find_end_of_inset(document.body, arg)
2791 document.warning("Can't find end of Argument!")
2794 # Find containing paragraph layout
2795 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2796 endPlain = find_end_of_layout(document.body, beginPlain)
2797 argcontent = document.body[beginPlain + 1 : endPlain]
2799 z = z - len(document.body[arg : argend + 1])
2801 del document.body[arg : argend + 1]
2802 if flextype == "Alternative":
2803 pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
2805 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2806 pre += put_cmd_in_ert("{")
2807 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2808 endPlain = find_end_of_layout(document.body, beginPlain)
2810 z = z - len(document.body[i : beginPlain + 1])
2812 document.body[i : beginPlain + 1] = pre
2813 post = put_cmd_in_ert("}")
2814 document.body[z - 2 : z + 1] = post
2815 elif flextype in old_flexes:
2816 pre = put_cmd_in_ert(old_flexes[flextype])
2817 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2821 argend = find_end_of_inset(document.body, arg)
2823 document.warning("Can't find end of Argument!")
2826 # Find containing paragraph layout
2827 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2828 endPlain = find_end_of_layout(document.body, beginPlain)
2829 argcontent = document.body[beginPlain + 1 : endPlain]
2831 z = z - len(document.body[arg : argend + 1])
2833 del document.body[arg : argend + 1]
2834 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2835 pre += put_cmd_in_ert("{")
2836 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2837 endPlain = find_end_of_layout(document.body, beginPlain)
2839 z = z - len(document.body[i : beginPlain + 1])
2841 document.body[i : beginPlain + 1] = pre
2842 post = put_cmd_in_ert("}")
2843 document.body[z - 2 : z + 1] = post
2848 def revert_beamerblocks(document):
2849 " Reverts beamer block arguments to ERT "
2851 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2852 if document.textclass not in beamer_classes:
2855 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2857 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2860 i = find_token(document.body, "\\begin_inset Argument", i)
2863 # Find containing paragraph layout
2864 parent = get_containing_layout(document.body, i)
2866 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2871 realparbeg = parent[3]
2872 layoutname = parent[0]
2874 for p in range(parbeg, parend):
2878 if layoutname in blocks:
2879 m = rx.match(document.body[p])
2883 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2884 endPlain = find_end_of_layout(document.body, beginPlain)
2885 endInset = find_end_of_inset(document.body, p)
2886 content = document.body[beginPlain + 1 : endPlain]
2888 realparend = realparend - len(document.body[p : endInset + 1])
2890 del document.body[p : endInset + 1]
2891 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2892 document.body[realparbeg : realparbeg] = subst
2894 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2895 endPlain = find_end_of_layout(document.body, beginPlain)
2896 endInset = find_end_of_inset(document.body, p)
2897 content = document.body[beginPlain + 1 : endPlain]
2899 realparend = realparend - len(document.body[p : endInset + 1])
2901 del document.body[p : endInset + 1]
2902 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2903 document.body[realparbeg : realparbeg] = subst
2908 def convert_beamerblocks(document):
2909 " Converts beamer block ERT args to native InsetArgs "
2911 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2912 if document.textclass not in beamer_classes:
2915 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2919 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2922 parent = get_containing_layout(document.body, i)
2923 if parent == False or parent[1] != i:
2924 document.warning("Wrong parent layout!")
2931 if document.body[parbeg] == "\\begin_inset ERT":
2932 ertcontfirstline = parbeg + 5
2933 ertcontlastline = parend - 6
2935 if document.body[ertcontfirstline].startswith("<"):
2936 # This is an overlay specification
2938 document.body[ertcontfirstline] = document.body[ertcontfirstline][1:]
2939 if document.body[ertcontlastline].endswith(">"):
2941 document.body[ertcontlastline] = document.body[ertcontlastline][:-1]
2942 # Convert to ArgInset
2943 document.body[parbeg] = "\\begin_inset Argument 1"
2944 elif document.body[ertcontlastline].endswith("}"):
2946 document.body[ertcontlastline] = document.body[ertcontlastline][:-1]
2948 ertcontdivline = ertcontfirstline
2949 tok = document.body[ertcontdivline].find('>{')
2951 regexp = re.compile(r'.*>\{', re.IGNORECASE)
2952 ertcontdivline = find_re(document.body, regexp, ertcontfirstline, ertcontlastline)
2953 tok = document.body[ertcontdivline].find('>{')
2955 if ertcontfirstline < ertcontlastline:
2956 # Multiline ERT. Might contain TeX code. Embrace in ERT.
2957 document.body[ertcontlastline : ertcontlastline + 1] = [
2958 document.body[ertcontlastline], '\\end_layout', '', '\\end_inset']
2959 document.body[ertcontdivline : ertcontdivline + 1] = [document.body[ertcontdivline][:tok],
2960 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2961 'status collapsed', '', '\\begin_layout Plain Layout',
2962 '\\begin_inset ERT', '', 'status open' '', '\\begin_layout Plain Layout',
2963 document.body[ertcontdivline][tok + 2:]]
2965 document.body[ertcontdivline : ertcontdivline + 1] = [document.body[ertcontdivline][:tok],
2966 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2967 'status collapsed', '', '\\begin_layout Plain Layout',
2968 document.body[ertcontdivline][tok + 2:]]
2969 # Convert to ArgInset
2970 document.body[parbeg] = "\\begin_inset Argument 1"
2971 elif document.body[ertcontfirstline].startswith("{"):
2972 # This is the block title
2973 if document.body[ertcontlastline].endswith("}"):
2974 # strip off the braces
2975 document.body[ertcontfirstline] = document.body[ertcontfirstline][1:]
2976 document.body[ertcontlastline] = document.body[ertcontlastline][:-1]
2977 if ertcontfirstline < ertcontlastline:
2978 # Multiline ERT. Might contain TeX code. Embrace in ERT.
2979 document.body[parend : parend + 1] = [
2980 document.body[parend], '\\end_layout', '', '\\end_inset']
2981 document.body[parbeg : parbeg + 1] = ['\\begin_inset Argument 2',
2982 'status collapsed', '', '\\begin_layout Plain Layout',
2983 '\\begin_inset ERT', '']
2985 # Convert to ArgInset
2986 document.body[parbeg] = "\\begin_inset Argument 2"
2987 elif count_pars_in_inset(document.body, ertcontfirstline) > 1:
2988 # Multipar ERT. Skip this.
2991 convert_TeX_brace_to_Argument(document, i, 2, 2, False, True, False)
2994 j = find_end_of_layout(document.body, i)
2996 document.warning("end of layout not found!")
2997 k = find_token(document.body, "\\begin_inset Argument", i, j)
2999 document.warning("InsetArgument not found!")
3001 l = find_end_of_inset(document.body, k)
3002 m = find_token(document.body, "\\begin_inset ERT", l, j)
3005 ertcontfirstline = m + 5
3010 def convert_overprint(document):
3011 " Convert old beamer overprint layouts to ERT "
3013 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3014 if document.textclass not in beamer_classes:
3019 i = find_token(document.body, "\\begin_layout Overprint", i)
3022 # Find end of sequence
3023 j = find_end_of_sequence(document.body, i)
3025 document.warning("Malformed LyX document. Cannot find end of Overprint sequence!")
3029 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
3031 if document.body[j] == "\\end_deeper":
3032 esubst = ["", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
3034 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
3035 endseq = endseq + len(esubst) - len(document.body[j : j])
3036 document.body[j : j] = esubst
3037 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
3039 argend = find_end_of_layout(document.body, argbeg)
3041 document.warning("Malformed LyX document. Cannot find end of Overprint argument!")
3044 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3045 endPlain = find_end_of_layout(document.body, beginPlain)
3046 content = document.body[beginPlain + 1 : endPlain]
3048 endseq = endseq - len(document.body[argbeg : argend + 1])
3050 del document.body[argbeg : argend + 1]
3051 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3053 endseq = endseq - len(document.body[i : i])
3054 document.body[i : i] = subst + ["\\end_layout"]
3055 endseq += len(subst)
3057 for p in range(i, endseq):
3058 if document.body[p] == "\\begin_layout Overprint":
3059 document.body[p] = "\\begin_layout Standard"
3064 def revert_overprint(document):
3065 " Revert old beamer overprint layouts to ERT "
3067 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3068 if document.textclass not in beamer_classes:
3073 i = find_token(document.body, "\\begin_layout Overprint", i)
3076 # Find end of sequence
3077 j = find_end_of_sequence(document.body, i)
3079 document.warning("Malformed LyX document. Cannot find end of Overprint sequence!")
3083 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
3084 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}")
3085 endseq = endseq + len(esubst) - len(document.body[j : j])
3086 if document.body[j] == "\\end_deeper":
3087 document.body[j : j] = ["\\end_deeper", ""] + esubst
3089 document.body[j : j] = esubst
3092 if document.body[r] == "\\begin_deeper":
3093 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3095 document.body[r] = ""
3096 document.body[s] = ""
3100 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
3102 argend = find_end_of_inset(document.body, argbeg)
3104 document.warning("Malformed LyX document. Cannot find end of Overprint argument!")
3107 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3108 endPlain = find_end_of_layout(document.body, beginPlain)
3109 content = document.body[beginPlain + 1 : endPlain]
3111 endseq = endseq - len(document.body[argbeg : argend])
3113 del document.body[argbeg : argend + 1]
3114 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3116 endseq = endseq - len(document.body[i : i])
3117 document.body[i : i] = subst + ["\\end_layout"]
3118 endseq += len(subst)
3124 if document.body[p] == "\\begin_layout Overprint":
3125 q = find_end_of_layout(document.body, p)
3127 document.warning("Malformed LyX document. Cannot find end of Overprint layout!")
3130 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\onslide")
3131 argbeg = find_token(document.body, "\\begin_inset Argument item:1", p, q)
3133 argend = find_end_of_inset(document.body, argbeg)
3135 document.warning("Malformed LyX document. Cannot find end of Overprint item argument!")
3138 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3139 endPlain = find_end_of_layout(document.body, beginPlain)
3140 content = document.body[beginPlain + 1 : endPlain]
3142 endseq = endseq - len(document.body[argbeg : argend + 1])
3144 del document.body[argbeg : argend + 1]
3145 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3146 endseq = endseq - len(document.body[p : p + 1]) + len(subst)
3147 document.body[p : p + 1] = subst
3153 def revert_frametitle(document):
3154 " Reverts beamer frametitle layout to ERT "
3156 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3157 if document.textclass not in beamer_classes:
3160 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
3163 i = find_token(document.body, "\\begin_layout FrameTitle", i)
3166 j = find_end_of_layout(document.body, i)
3168 document.warning("Malformed LyX document: Can't find end of FrameTitle layout")
3172 document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
3173 endlay += len(put_cmd_in_ert("}"))
3174 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\frametitle")
3175 for p in range(i, j):
3178 m = rx.match(document.body[p])
3182 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3183 endPlain = find_end_of_layout(document.body, beginPlain)
3184 endInset = find_end_of_inset(document.body, p)
3185 content = document.body[beginPlain + 1 : endPlain]
3187 endlay = endlay - len(document.body[p : endInset + 1])
3189 del document.body[p : endInset + 1]
3190 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3192 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3193 endPlain = find_end_of_layout(document.body, beginPlain)
3194 endInset = find_end_of_inset(document.body, p)
3195 content = document.body[beginPlain + 1 : endPlain]
3197 endlay = endlay - len(document.body[p : endInset + 1])
3199 del document.body[p : endInset + 1]
3200 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3202 subst += put_cmd_in_ert("{")
3203 document.body[i : i + 1] = subst
3207 def convert_epigraph(document):
3208 " Converts memoir epigraph to new syntax "
3210 if document.textclass != "memoir":
3215 i = find_token(document.body, "\\begin_layout Epigraph", i)
3218 j = find_end_of_layout(document.body, i)
3220 document.warning("Malformed LyX document: Can't find end of Epigraph layout")
3225 ert = find_token(document.body, "\\begin_inset ERT", i, j)
3227 endInset = find_end_of_inset(document.body, ert)
3228 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", ert)
3229 endPlain = find_end_of_layout(document.body, beginPlain)
3230 ertcont = beginPlain + 2
3231 if document.body[ertcont] == "}{":
3233 # Convert to ArgInset
3234 endlay = endlay - 2 * len(document.body[j])
3235 begsubst = ['\\begin_inset Argument post:1', 'status collapsed', '',
3236 '\\begin_layout Plain Layout']
3237 endsubst = ['\\end_layout', '', '\\end_inset', '', document.body[j]]
3238 document.body[j : j + 1] = endsubst
3239 document.body[endInset + 1 : endInset + 1] = begsubst
3241 endlay += len(begsubst) + len(endsubst)
3242 endlay = endlay - len(document.body[ert : endInset + 1])
3243 del document.body[ert : endInset + 1]
3248 def revert_epigraph(document):
3249 " Reverts memoir epigraph argument to ERT "
3251 if document.textclass != "memoir":
3256 i = find_token(document.body, "\\begin_layout Epigraph", i)
3259 j = find_end_of_layout(document.body, i)
3261 document.warning("Malformed LyX document: Can't find end of Epigraph layout")
3266 p = find_token(document.body, "\\begin_layout Argument post:1", i, j)
3268 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3269 endPlain = find_end_of_layout(document.body, beginPlain)
3270 endInset = find_end_of_inset(document.body, p)
3271 content = document.body[beginPlain + 1 : endPlain]
3273 endlay = endlay - len(document.body[p : endInset + 1])
3275 del document.body[p : endInset + 1]
3276 subst += put_cmd_in_ert("}{") + content
3278 subst += put_cmd_in_ert("}{")
3280 document.body[j : j] = subst + document.body[j : j]
3284 def convert_captioninsets(document):
3285 " Converts caption insets to new syntax "
3289 i = find_token(document.body, "\\begin_inset Caption", i)
3292 document.body[i] = "\\begin_inset Caption Standard"
3296 def revert_captioninsets(document):
3297 " Reverts caption insets to old syntax "
3301 i = find_token(document.body, "\\begin_inset Caption Standard", i)
3304 document.body[i] = "\\begin_inset Caption"
3308 def convert_captionlayouts(document):
3309 " Convert caption layouts to caption insets. "
3312 "Captionabove": "Above",
3313 "Captionbelow": "Below",
3314 "FigCaption" : "FigCaption",
3315 "Table_Caption" : "Table",
3316 "CenteredCaption" : "Centered",
3317 "Bicaption" : "Bicaption",
3322 i = find_token(document.body, "\\begin_layout", i)
3325 val = get_value(document.body, "\\begin_layout", i)
3326 if val in caption_dict.keys():
3327 j = find_end_of_layout(document.body, i)
3329 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3332 document.body[j:j] = ["\\end_layout", "", "\\end_inset", "", ""]
3333 document.body[i:i+1] = ["\\begin_layout %s" % document.default_layout,
3334 "\\begin_inset Caption %s" % caption_dict[val], "",
3335 "\\begin_layout %s" % document.default_layout]
3339 def revert_captionlayouts(document):
3340 " Revert caption insets to caption layouts. "
3343 "Above" : "Captionabove",
3344 "Below" : "Captionbelow",
3345 "FigCaption" : "FigCaption",
3346 "Table" : "Table_Caption",
3347 "Centered" : "CenteredCaption",
3348 "Bicaption" : "Bicaption",
3352 rx = re.compile(r'^\\begin_inset Caption (\S+)$')
3354 i = find_token(document.body, "\\begin_inset Caption", i)
3358 m = rx.match(document.body[i])
3362 if val not in caption_dict.keys():
3366 # We either need to delete the previous \begin_layout line, or we
3367 # need to end the previous layout if this inset is not in the first
3368 # position of the paragraph.
3369 layout_before = find_token_backwards(document.body, "\\begin_layout", i)
3370 if layout_before == -1:
3371 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3373 layout_line = document.body[layout_before]
3374 del_layout_before = True
3375 l = layout_before + 1
3377 if document.body[l] != "":
3378 del_layout_before = False
3381 if del_layout_before:
3382 del document.body[layout_before:i]
3385 document.body[i:i] = ["\\end_layout", ""]
3388 # Find start of layout in the inset and end of inset
3389 j = find_token(document.body, "\\begin_layout", i)
3391 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3393 k = find_end_of_inset(document.body, i)
3395 document.warning("Malformed LyX document: Missing `\\end_inset'.")
3398 # We either need to delete the following \end_layout line, or we need
3399 # to restart the old layout if this inset is not at the paragraph end.
3400 layout_after = find_token(document.body, "\\end_layout", k)
3401 if layout_after == -1:
3402 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3404 del_layout_after = True
3406 while l < layout_after:
3407 if document.body[l] != "":
3408 del_layout_after = False
3411 if del_layout_after:
3412 del document.body[k+1:layout_after+1]
3414 document.body[k+1:k+1] = [layout_line, ""]
3416 # delete \begin_layout and \end_inset and replace \begin_inset with
3417 # "\begin_layout XXX". This works because we can only have one
3418 # paragraph in the caption inset: The old \end_layout will be recycled.
3419 del document.body[k]
3420 if document.body[k] == "":
3421 del document.body[k]
3422 del document.body[j]
3423 if document.body[j] == "":
3424 del document.body[j]
3425 document.body[i] = "\\begin_layout %s" % caption_dict[val]
3426 if document.body[i+1] == "":
3427 del document.body[i+1]
3431 def revert_fragileframe(document):
3432 " Reverts beamer FragileFrame layout to ERT "
3434 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3435 if document.textclass not in beamer_classes:
3440 i = find_token(document.body, "\\begin_layout FragileFrame", i)
3443 # Find end of sequence
3444 j = find_end_of_sequence(document.body, i)
3446 document.warning("Malformed LyX document. Cannot find end of FragileFrame sequence!")
3450 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{frame}")
3451 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{frame}")
3452 endseq = endseq + len(esubst) - len(document.body[j : j])
3453 if document.body[j] == "\\end_deeper":
3454 document.body[j : j] = ["\\end_deeper", ""] + esubst
3456 document.body[j : j] = esubst
3457 for q in range(i, j):
3458 if document.body[q] == "\\begin_layout FragileFrame":
3459 document.body[q] = "\\begin_layout %s" % document.default_layout
3462 if document.body[r] == "\\begin_deeper":
3463 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3465 document.body[r] = ""
3466 document.body[s] = ""
3470 for p in range(1, 5):
3471 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, j)
3474 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3475 endPlain = find_end_of_layout(document.body, beginPlain)
3476 endInset = find_end_of_inset(document.body, arg)
3477 content = document.body[beginPlain + 1 : endPlain]
3479 j = j - len(document.body[arg : endInset + 1])
3481 del document.body[arg : endInset + 1]
3482 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3484 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3485 endPlain = find_end_of_layout(document.body, beginPlain)
3486 endInset = find_end_of_inset(document.body, arg)
3487 content = document.body[beginPlain + 1 : endPlain]
3489 j = j - len(document.body[arg : endInset + 1])
3491 del document.body[arg : endInset + 1]
3492 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3494 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3495 endPlain = find_end_of_layout(document.body, beginPlain)
3496 endInset = find_end_of_inset(document.body, arg)
3497 content = document.body[beginPlain + 1 : endPlain]
3499 j = j - len(document.body[arg : endInset + 1])
3501 del document.body[arg : endInset + 1]
3502 subst += put_cmd_in_ert("[fragile,") + content + put_cmd_in_ert("]")
3504 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3505 endPlain = find_end_of_layout(document.body, beginPlain)
3506 endInset = find_end_of_inset(document.body, arg)
3507 content = document.body[beginPlain + 1 : endPlain]
3509 j = j - len(document.body[arg : endInset + 1])
3511 del document.body[arg : endInset + 1]
3512 subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
3514 subst += put_cmd_in_ert("[fragile]")
3516 document.body[i : i + 1] = subst
3520 def revert_newframes(document):
3521 " Reverts beamer Frame and PlainFrame layouts to old forms "
3523 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3524 if document.textclass not in beamer_classes:
3528 "Frame" : "BeginFrame",
3529 "PlainFrame" : "BeginPlainFrame",
3532 rx = re.compile(r'^\\begin_layout (\S+)$')
3535 i = find_token(document.body, "\\begin_layout", i)
3539 m = rx.match(document.body[i])
3543 if val not in frame_dict.keys():
3546 # Find end of sequence
3547 j = find_end_of_sequence(document.body, i)
3549 document.warning("Malformed LyX document. Cannot find end of Frame sequence!")
3553 subst = ["\\begin_layout %s" % frame_dict[val]]
3554 esubst = ["\\end_layout", "", "\\begin_layout EndFrame", "", "\\end_layout"]
3555 endseq = endseq + len(esubst) - len(document.body[j : j])
3556 if document.body[j] == "\\end_deeper":
3557 document.body[j : j] = ["\\end_deeper", ""] + esubst
3559 document.body[j : j] = esubst
3560 for q in range(i, j):
3561 if document.body[q] == "\\begin_layout %s" % val:
3562 document.body[q] = "\\begin_layout %s" % document.default_layout
3565 if document.body[r] == "\\begin_deeper":
3566 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3568 document.body[r] = ""
3569 document.body[s] = ""
3573 l = find_end_of_layout(document.body, i)
3574 for p in range(1, 5):
3575 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, l)
3578 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3579 endPlain = find_end_of_layout(document.body, beginPlain)
3580 endInset = find_end_of_inset(document.body, arg)
3581 content = document.body[beginPlain + 1 : endPlain]
3583 l = l - len(document.body[arg : endInset + 1])
3585 del document.body[arg : endInset + 1]
3586 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3588 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3589 endPlain = find_end_of_layout(document.body, beginPlain)
3590 endInset = find_end_of_inset(document.body, arg)
3591 content = document.body[beginPlain + 1 : endPlain]
3593 l = l - len(document.body[arg : endInset + 1])
3595 del document.body[arg : endInset + 1]
3596 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3598 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3599 endPlain = find_end_of_layout(document.body, beginPlain)
3600 endInset = find_end_of_inset(document.body, arg)
3601 content = document.body[beginPlain + 1 : endPlain]
3603 l = l - len(document.body[arg : endInset + 1])
3605 del document.body[arg : endInset + 1]
3606 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3608 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3609 endPlain = find_end_of_layout(document.body, beginPlain)
3610 endInset = find_end_of_inset(document.body, arg)
3611 content = document.body[beginPlain + 1 : endPlain]
3613 l = l - len(document.body[arg : endInset + 1])
3615 del document.body[arg : endInset + 1]
3618 document.body[i : i + 1] = subst
3621 # known encodings that do not change their names (same LyX and LaTeX names)
3622 known_enc_tuple = ("auto", "default", "ansinew", "applemac", "armscii8", "ascii",
3623 "cp437", "cp437de", "cp850", "cp852", "cp855", "cp858", "cp862", "cp865", "cp866",
3624 "cp1250", "cp1251", "cp1252", "cp1255", "cp1256", "cp1257", "koi8-r", "koi8-u",
3625 "pt154", "pt254", "tis620-0", "utf8", "utf8x", "utf8-plain")
3627 def convert_encodings(document):
3628 "Use the LyX names of the encodings instead of the LaTeX names."
3629 LaTeX2LyX_enc_dict = {
3630 "8859-6": "iso8859-6",
3631 "8859-8": "iso8859-8",
3633 "euc": "euc-jp-platex",
3638 "iso88595": "iso8859-5",
3639 "iso-8859-7": "iso8859-7",
3641 "jis": "jis-platex",
3643 "l7xenc": "iso8859-13",
3644 "latin1": "iso8859-1",
3645 "latin2": "iso8859-2",
3646 "latin3": "iso8859-3",
3647 "latin4": "iso8859-4",
3648 "latin5": "iso8859-9",
3649 "latin9": "iso8859-15",
3650 "latin10": "iso8859-16",
3651 "SJIS": "shift-jis",
3652 "sjis": "shift-jis-platex",
3655 i = find_token(document.header, "\\inputencoding" , 0)
3658 val = get_value(document.header, "\\inputencoding", i)
3659 if val in LaTeX2LyX_enc_dict.keys():
3660 document.header[i] = "\\inputencoding %s" % LaTeX2LyX_enc_dict[val]
3661 elif val not in known_enc_tuple:
3662 document.warning("Ignoring unknown input encoding: `%s'" % val)
3665 def revert_encodings(document):
3666 """Revert to using the LaTeX names of the encodings instead of the LyX names.
3667 Also revert utf8-platex to sjis, the language default when using Japanese.
3669 LyX2LaTeX_enc_dict = {
3674 "euc-jp-platex": "euc",
3677 "iso8859-1": "latin1",
3678 "iso8859-2": "latin2",
3679 "iso8859-3": "latin3",
3680 "iso8859-4": "latin4",
3681 "iso8859-5": "iso88595",
3682 "iso8859-6": "8859-6",
3683 "iso8859-7": "iso-8859-7",
3684 "iso8859-8": "8859-8",
3685 "iso8859-9": "latin5",
3686 "iso8859-13": "l7xenc",
3687 "iso8859-15": "latin9",
3688 "iso8859-16": "latin10",
3690 "jis-platex": "jis",
3691 "shift-jis": "SJIS",
3692 "shift-jis-platex": "sjis",
3694 "utf8-platex": "sjis"
3696 i = find_token(document.header, "\\inputencoding" , 0)
3699 val = get_value(document.header, "\\inputencoding", i)
3700 if val in LyX2LaTeX_enc_dict.keys():
3701 document.header[i] = "\\inputencoding %s" % LyX2LaTeX_enc_dict[val]
3702 elif val not in known_enc_tuple:
3703 document.warning("Ignoring unknown input encoding: `%s'" % val)
3706 def revert_IEEEtran_3(document):
3708 Reverts Flex Insets to TeX-code
3710 if document.textclass == "IEEEtran":
3716 h = find_token(document.body, "\\begin_inset Flex Author Mark", h)
3718 endh = find_end_of_inset(document.body, h)
3719 document.body[endh - 2 : endh + 1] = put_cmd_in_ert("}")
3720 document.body[h : h + 4] = put_cmd_in_ert("\\IEEEauthorrefmark{")
3723 i = find_token(document.body, "\\begin_inset Flex Author Name", i)
3725 endi = find_end_of_inset(document.body, i)
3726 document.body[endi - 2 : endi + 1] = put_cmd_in_ert("}")
3727 document.body[i : i + 4] = put_cmd_in_ert("\\IEEEauthorblockN{")
3730 j = find_token(document.body, "\\begin_inset Flex Author Affiliation", j)
3732 endj = find_end_of_inset(document.body, j)
3733 document.body[endj - 2 : endj + 1] = put_cmd_in_ert("}")
3734 document.body[j : j + 4] = put_cmd_in_ert("\\IEEEauthorblockA{")
3736 if i == -1 and j == -1 and h == -1:
3740 def revert_kurier_fonts(document):
3741 " Revert kurier font definition to LaTeX "
3743 i = find_token(document.header, "\\font_math", 0)
3745 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3746 val = get_value(document.header, "\\font_math", i)
3747 if val == "kurier-math":
3748 add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
3749 "\\usepackage[math]{kurier}\n" \
3750 "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
3751 document.header[i] = "\\font_math auto"
3753 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3754 kurier_fonts = ["kurier", "kurierc", "kurierl", "kurierlc"]
3755 k = find_token(document.header, "\\font_sans kurier", 0)
3757 sf = get_value(document.header, "\\font_sans", k)
3758 if sf in kurier_fonts:
3759 add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
3760 document.header[k] = "\\font_sans default"
3762 def revert_iwona_fonts(document):
3763 " Revert iwona font definition to LaTeX "
3765 i = find_token(document.header, "\\font_math", 0)
3767 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3768 val = get_value(document.header, "\\font_math", i)
3769 if val == "iwona-math":
3770 add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
3771 "\\usepackage[math]{iwona}\n" \
3772 "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
3773 document.header[i] = "\\font_math auto"
3775 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3776 iwona_fonts = ["iwona", "iwonac", "iwonal", "iwonalc"]
3777 k = find_token(document.header, "\\font_sans iwona", 0)
3779 sf = get_value(document.header, "\\font_sans", k)
3780 if sf in iwona_fonts:
3781 add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
3782 document.header[k] = "\\font_sans default"
3785 def revert_new_libertines(document):
3786 " Revert new libertine font definition to LaTeX "
3788 if find_token(document.header, "\\use_non_tex_fonts true", 0) != -1:
3791 i = find_token(document.header, "\\font_typewriter libertine-mono", 0)
3793 preamble = "\\usepackage"
3794 sc = find_token(document.header, "\\font_tt_scale", 0)
3796 scval = get_value(document.header, "\\font_tt_scale", sc)
3798 preamble += "[scale=%f]" % (float(scval) / 100)
3799 document.header[sc] = "\\font_tt_scale 100"
3800 preamble += "{libertineMono-type1}"
3801 add_to_preamble(document, [preamble])
3802 document.header[i] = "\\font_typewriter default"
3804 k = find_token(document.header, "\\font_sans biolinum", 0)
3806 preamble = "\\usepackage"
3808 j = find_token(document.header, "\\font_osf true", 0)
3813 sc = find_token(document.header, "\\font_sf_scale", 0)
3815 scval = get_value(document.header, "\\font_sf_scale", sc)
3817 options += ",scale=%f" % (float(scval) / 100)
3818 document.header[sc] = "\\font_sf_scale 100"
3820 preamble += "[" + options +"]"
3821 preamble += "{biolinum-type1}"
3822 add_to_preamble(document, [preamble])
3823 document.header[k] = "\\font_sans default"
3826 def convert_lyxframes(document):
3827 " Converts old beamer frames to new style "
3829 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3830 if document.textclass not in beamer_classes:
3833 framebeg = ["BeginFrame", "BeginPlainFrame"]
3834 frameend = ["Frame", "PlainFrame", "EndFrame", "BeginFrame", "BeginPlainFrame", "AgainFrame",
3835 "Section", "Section*", "Subsection", "Subsection*", "Subsubsection", "Subsubsection*"]
3836 for lay in framebeg:
3839 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
3842 parent = get_containing_layout(document.body, i)
3843 if parent == False or parent[1] != i:
3844 document.warning("Wrong parent layout!")
3847 frametype = parent[0]
3851 # Step I: Convert ERT arguments
3852 # FIXME: See restrictions in convert_beamerframeargs method
3853 ertend = convert_beamerframeargs(document, i, parbeg)
3856 # Step II: Now rename the layout and convert the title to an argument
3857 j = find_end_of_layout(document.body, i)
3858 document.body[j : j + 1] = ['\\end_layout', '', '\\end_inset', '', '\\end_layout']
3859 if lay == "BeginFrame":
3860 document.body[i] = "\\begin_layout Frame"
3862 document.body[i] = "\\begin_layout PlainFrame"
3863 document.body[ertend + 1 : ertend + 1] = ['\\begin_inset Argument 4',
3864 'status open', '', '\\begin_layout Plain Layout']
3865 # Step III: find real frame end
3869 fend = find_token(document.body, "\\begin_layout", jj)
3871 document.warning("Malformed LyX document: No real frame end!")
3873 val = get_value(document.body, "\\begin_layout", fend)
3874 if val not in frameend:
3877 old = document.body[fend]
3878 if val == frametype:
3879 document.body[fend : fend] = ['\\end_deeper', '', '\\begin_layout Separator', '', '\\end_layout']
3880 # consider explicit EndFrames between two identical frame types
3881 elif val == "EndFrame":
3882 nextlayout = find_token(document.body, "\\begin_layout", fend + 1)
3883 if nextlayout != -1 and get_value(document.body, "\\begin_layout", nextlayout) == frametype:
3884 document.body[fend : fend] = ['\\end_deeper', '', '\\begin_layout Separator', '', '\\end_layout']
3886 document.body[fend : fend] = ['\\end_deeper']
3888 document.body[fend : fend] = ['\\end_deeper']
3889 document.body[j + 1 : j + 1] = ['', '\\begin_deeper']
3894 def remove_endframes(document):
3895 " Remove deprecated beamer endframes "
3897 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3898 if document.textclass not in beamer_classes:
3903 i = find_token_exact(document.body, "\\begin_layout EndFrame", i)
3906 j = find_end_of_layout(document.body, i)
3908 document.warning("Malformed LyX document: Missing \\end_layout to EndFrame")
3911 del document.body[i : j + 1]
3914 def revert_powerdot_flexes(document):
3915 " Reverts powerdot flex insets "
3917 if document.textclass != "powerdot":
3920 flexes = {"Onslide" : "\\onslide",
3921 "Onslide*" : "\\onslide*",
3922 "Onslide+" : "\\onslide+"}
3923 rx = re.compile(r'^\\begin_inset Flex (.+)$')
3927 i = find_token(document.body, "\\begin_inset Flex", i)
3930 m = rx.match(document.body[i])
3932 flextype = m.group(1)
3933 z = find_end_of_inset(document.body, i)
3935 document.warning("Can't find end of Flex " + flextype + " inset.")
3938 if flextype in flexes:
3939 pre = put_cmd_in_ert(flexes[flextype])
3940 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
3942 argend = find_end_of_inset(document.body, arg)
3944 document.warning("Can't find end of Argument!")
3947 # Find containing paragraph layout
3948 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3949 endPlain = find_end_of_layout(document.body, beginPlain)
3950 argcontent = document.body[beginPlain + 1 : endPlain]
3952 z = z - len(document.body[arg : argend + 1])
3954 del document.body[arg : argend + 1]
3955 pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
3956 pre += put_cmd_in_ert("{")
3957 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
3958 endPlain = find_end_of_layout(document.body, beginPlain)
3960 z = z - len(document.body[i : beginPlain + 1])
3962 document.body[i : beginPlain + 1] = pre
3963 post = put_cmd_in_ert("}")
3964 document.body[z - 2 : z + 1] = post
3968 def revert_powerdot_pause(document):
3969 " Reverts powerdot pause layout to ERT "
3971 if document.textclass != "powerdot":
3976 i = find_token(document.body, "\\begin_layout Pause", i)
3979 j = find_end_of_layout(document.body, i)
3981 document.warning("Malformed LyX document: Can't find end of Pause layout")
3985 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\pause")
3986 for p in range(i, j):
3989 arg = find_token(document.body, "\\begin_inset Argument 1", i, j)
3991 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3992 endPlain = find_end_of_layout(document.body, beginPlain)
3993 endInset = find_end_of_inset(document.body, p)
3994 content = document.body[beginPlain + 1 : endPlain]
3996 endlay = endlay - len(document.body[p : endInset + 1])
3998 del document.body[p : endInset + 1]
3999 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
4001 document.body[i : i + 1] = subst
4005 def revert_powerdot_itemargs(document):
4006 " Reverts powerdot item arguments to ERT "
4008 if document.textclass != "powerdot":
4012 list_layouts = ["Itemize", "ItemizeType1", "Enumerate", "EnumerateType1"]
4013 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
4016 i = find_token(document.body, "\\begin_inset Argument", i)
4019 # Find containing paragraph layout
4020 parent = get_containing_layout(document.body, i)
4022 document.warning("Malformed LyX document: Can't find parent paragraph layout")
4027 realparbeg = parent[3]
4028 layoutname = parent[0]
4030 for p in range(parbeg, parend):
4034 if layoutname in list_layouts:
4035 m = rx.match(document.body[p])
4038 if argnr == "item:1":
4039 j = find_end_of_inset(document.body, i)
4040 # Find containing paragraph layout
4041 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
4042 endPlain = find_end_of_layout(document.body, beginPlain)
4043 content = document.body[beginPlain + 1 : endPlain]
4044 del document.body[i:j+1]
4045 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
4046 document.body[realparbeg : realparbeg] = subst
4047 elif argnr == "item:2":
4048 j = find_end_of_inset(document.body, i)
4049 # Find containing paragraph layout
4050 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
4051 endPlain = find_end_of_layout(document.body, beginPlain)
4052 content = document.body[beginPlain + 1 : endPlain]
4053 del document.body[i:j+1]
4054 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
4055 document.body[realparbeg : realparbeg] = subst
4060 def revert_powerdot_columns(document):
4061 " Reverts powerdot twocolumn to TeX-code "
4062 if document.textclass != "powerdot":
4065 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
4068 i = find_token(document.body, "\\begin_layout Twocolumn", i)
4071 j = find_end_of_layout(document.body, i)
4073 document.warning("Malformed LyX document: Can't find end of Twocolumn layout")
4077 document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
4078 endlay += len(put_cmd_in_ert("}"))
4079 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\twocolumn")
4080 for p in range(i, j):
4083 m = rx.match(document.body[p])
4087 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
4088 endPlain = find_end_of_layout(document.body, beginPlain)
4089 endInset = find_end_of_inset(document.body, p)
4090 content = document.body[beginPlain + 1 : endPlain]
4092 endlay = endlay - len(document.body[p : endInset + 1])
4094 del document.body[p : endInset + 1]
4095 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
4097 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
4098 endPlain = find_end_of_layout(document.body, beginPlain)
4099 endInset = find_end_of_inset(document.body, p)
4100 content = document.body[beginPlain + 1 : endPlain]
4102 endlay = endlay - len(document.body[p : endInset + 1])
4104 del document.body[p : endInset + 1]
4105 subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
4107 subst += put_cmd_in_ert("{")
4108 document.body[i : i + 1] = subst
4112 def revert_mbox_fbox(document):
4113 'Convert revert mbox/fbox boxes to TeX-code'
4116 i = find_token(document.body, "\\begin_inset Box", i)
4119 j = find_token(document.body, "width", i)
4121 document.warning("Malformed LyX document: Can't find box width")
4123 width = get_value(document.body, "width", j)
4124 k = find_end_of_inset(document.body, j)
4126 document.warning("Malformed LyX document: Can't find end of box inset")
4129 BeginLayout = find_token(document.body, "\\begin_layout Plain Layout", j)
4130 EndLayout = find_token(document.body, "\\end_layout", BeginLayout)
4131 # replace if width is ""
4133 document.body[EndLayout:k + 1] = put_cmd_in_ert("}")
4134 if document.body[i] == "\\begin_inset Box Frameless":
4135 document.body[i:BeginLayout + 1] = put_cmd_in_ert("\\mbox{")
4136 if document.body[i] == "\\begin_inset Box Boxed":
4137 document.body[i:BeginLayout + 1] = put_cmd_in_ert("\\fbox{")
4141 def revert_starred_caption(document):
4142 " Reverts unnumbered longtable caption insets "
4146 i = find_token(document.body, "\\begin_inset Caption LongTableNoNumber", i)
4149 # This is not equivalent, but since the caption inset is a full blown
4150 # text inset a true conversion to ERT is too difficult.
4151 document.body[i] = "\\begin_inset Caption Standard"
4155 def revert_forced_local_layout(document):
4158 i = find_token(document.header, "\\begin_forced_local_layout", i)
4161 j = find_end_of(document.header, i, "\\begin_forced_local_layout", "\\end_forced_local_layout")
4163 # this should not happen
4165 regexp = re.compile(r'\s*forcelocal', re.IGNORECASE)
4166 k = find_re(document.header, regexp, i, j)
4168 del document.header[k]
4170 k = find_re(document.header, regexp, i, j)
4171 k = find_token(document.header, "\\begin_local_layout", 0)
4173 document.header[i] = "\\begin_local_layout"
4174 document.header[j] = "\\end_local_layout"
4176 l = find_end_of(document.header, k, "\\begin_local_layout", "\\end_local_layout")
4178 # this should not happen
4180 lines = document.header[i+1 : j]
4182 document.header[k+1 : k+1] = lines
4183 document.header[i : j ] = []
4185 document.header[i : j ] = []
4186 document.header[k+1 : k+1] = lines
4189 def revert_aa1(document):
4190 " Reverts InsetArguments of aa to TeX-code "
4191 if document.textclass == "aa":
4195 i = find_token(document.body, "\\begin_layout Abstract (structured)", i)
4197 revert_Argument_to_TeX_brace(document, i, 0, 1, 4, False, False)
4203 def revert_aa2(document):
4204 " Reverts InsetArguments of aa to TeX-code "
4205 if document.textclass == "aa":
4209 i = find_token(document.body, "\\begin_layout Abstract (structured)", i)
4211 document.body[i] = "\\begin_layout Abstract"
4217 def revert_tibetan(document):
4218 "Set the document language for Tibetan to English"
4220 if document.language == "tibetan":
4221 document.language = "english"
4222 i = find_token(document.header, "\\language", 0)
4224 document.header[i] = "\\language english"
4226 while j < len(document.body):
4227 j = find_token(document.body, "\\lang tibetan", j)
4229 document.body[j] = document.body[j].replace("\\lang tibetan", "\\lang english")
4232 j = len(document.body)
4241 # The idea here is that we will have a sequence of chunk paragraphs.
4242 # We want to convert them to paragraphs in one or several chunk insets.
4243 # Individual chunks are terminated by the character @ on the last line.
4244 # This line will be discarded, and following lines are treated as new
4245 # chunks, which go into their own insets.
4246 # The first line of a chunk should look like: <<CONTENT>>=
4247 # We will discard the delimiters, and put the CONTENT into the
4248 # optional argument of the inset, if the CONTENT is non-empty.
4249 def convert_chunks(document):
4250 first_re = re.compile(r'<<(.*)>>=(.*)')
4253 # find start of a block of chunks
4254 i = find_token(document.body, "\\begin_layout Chunk", file_pos)
4260 chunk_started = False
4263 # process the one we just found
4264 j = find_end_of_layout(document.body, i)
4266 document.warning("Malformed LyX documents. Can't find end of Chunk layout!")
4267 # there is no point continuing, as we will run into the same error again.
4269 this_chunk = "".join(document.body[i + 1:j])
4271 # there may be empty lines between chunks
4272 # we just skip them.
4273 if not chunk_started:
4274 if this_chunk != "":
4276 chunk_started = True
4279 contents.append(document.body[i + 1:j])
4281 # look for potential chunk terminator
4282 # on the last line of the chunk paragraph
4283 if document.body[j - 1] == "@":
4286 # look for subsequent chunk paragraph
4287 i = find_token(document.body, "\\begin_layout", j)
4291 if get_value(document.body, "\\begin_layout", i) != "Chunk":
4294 file_pos = end = j + 1
4296 # The last chunk should simply have an "@" in it
4297 # or at least end with "@" (can happen if @ is
4298 # preceded by a newline)
4299 lastpar = ''.join(contents[-1])
4300 if not lastpar.endswith("@"):
4301 document.warning("Unexpected chunk content: chunk not terminated by '@'!")
4305 # chunk par only contains "@". Just drop it.
4308 # chunk par contains more. Only drop the "@".
4311 # The first line should look like: <<CONTENT>>=
4312 # We want the CONTENT
4313 optarg = ' '.join(contents[0])
4315 # We can already have real chunk content in
4316 # the first par (separated from the options by a newline).
4317 # We collect such stuff to re-insert it later.
4320 match = first_re.search(optarg)
4322 optarg = match.groups()[0]
4323 if match.groups()[1] != "":
4325 for c in contents[0]:
4326 if c.endswith(">>="):
4330 postoptstuff.append(c)
4331 # We have stripped everything. This can be deleted.
4334 newstuff = ['\\begin_layout Standard',
4335 '\\begin_inset Flex Chunk',
4337 '\\begin_layout Plain Layout', '']
4339 # If we have a non-empty optional argument, insert it.
4340 if match and optarg != "":
4342 ['\\begin_inset Argument 1',
4344 '\\begin_layout Plain Layout',
4349 # Since we already opened a Plain layout, the first paragraph
4350 # does not need to do that.
4353 newstuff.extend(postoptstuff)
4354 newstuff.append('\\end_layout')
4358 newstuff.extend(['', '\\begin_layout Plain Layout', ''])
4362 newstuff.append('\\end_layout')
4364 newstuff.extend(['', '\\end_inset', '', '\\end_layout', ''])
4366 document.body[start:end] = newstuff
4368 file_pos += len(newstuff) - (end - start)
4371 def revert_chunks(document):
4374 i = find_token(document.body, "\\begin_inset Flex Chunk", i)
4378 iend = find_end_of_inset(document.body, i)
4380 document.warning("Can't find end of Chunk!")
4384 # Look for optional argument
4386 ostart = find_token(document.body, "\\begin_inset Argument 1", i, iend)
4388 oend = find_end_of_inset(document.body, ostart)
4389 k = find_token(document.body, "\\begin_layout Plain Layout", ostart, oend)
4391 document.warning("Malformed LyX document: Can't find argument contents!")
4393 m = find_end_of_layout(document.body, k)
4394 optarg = "".join(document.body[k+1:m])
4397 # We now remove the optional argument, so we have something
4398 # uniform on which to work
4399 document.body[ostart : oend + 1] = []
4400 # iend is now invalid
4401 iend = find_end_of_inset(document.body, i)
4403 retval = get_containing_layout(document.body, i)
4405 document.warning("Can't find containing layout for Chunk!")
4408 (lname, lstart, lend, pstart) = retval
4409 # we now want to work through the various paragraphs, and collect their contents
4413 k = find_token(document.body, "\\begin_layout Plain Layout", k, lend)
4416 j = find_end_of_layout(document.body, k)
4418 document.warning("Can't find end of layout inside chunk!")
4420 parlist.append(document.body[k+1:j])
4422 # we now need to wrap all of these paragraphs in chunks
4425 newlines.extend(["\\begin_layout Chunk", "", "<<" + optarg + ">>=", "\\end_layout", ""])
4426 for stuff in parlist:
4427 newlines.extend(["\\begin_layout Chunk"] + stuff + ["\\end_layout", ""])
4428 newlines.extend(["\\begin_layout Chunk", "", "@", "\\end_layout", ""])
4429 # replace old content with new content
4430 document.body[lstart : lend + 1] = newlines
4431 i = lstart + len(newlines)
4438 supported_versions = ["2.1.0","2.1"]
4441 [415, [convert_undertilde]],
4443 [417, [convert_japanese_encodings]],
4444 [418, [convert_justification]],
4446 [420, [convert_biblio_style]],
4447 [421, [convert_longtable_captions]],
4448 [422, [convert_use_packages]],
4449 [423, [convert_use_mathtools]],
4450 [424, [convert_cite_engine_type]],
4454 [428, [convert_cell_rotation]],
4455 [429, [convert_table_rotation]],
4456 [430, [convert_listoflistings]],
4457 [431, [convert_use_amssymb]],
4459 [433, [convert_armenian]],
4467 [441, [convert_mdnomath]],
4472 [446, [convert_latexargs]],
4473 [447, [convert_IEEEtran, convert_AASTeX, convert_AGUTeX, convert_IJMP, convert_SIGPLAN, convert_SIGGRAPH, convert_EuropeCV, convert_Initials, convert_ModernCV]],
4474 [448, [convert_literate]],
4477 [451, [convert_beamerargs, convert_againframe_args, convert_corollary_args, convert_quote_args]],
4478 [452, [convert_beamerblocks]],
4479 [453, [convert_use_stmaryrd]],
4480 [454, [convert_overprint]],
4482 [456, [convert_epigraph]],
4483 [457, [convert_use_stackrel]],
4484 [458, [convert_captioninsets, convert_captionlayouts]],
4489 [463, [convert_encodings]],
4490 [464, [convert_use_cancel]],
4491 [465, [convert_lyxframes, remove_endframes]],
4497 [471, [convert_cite_engine_type_default]],
4500 [474, [convert_chunks]],
4504 [473, [revert_chunks]],
4505 [472, [revert_tibetan]],
4506 [471, [revert_aa1,revert_aa2]],
4507 [470, [revert_cite_engine_type_default]],
4508 [469, [revert_forced_local_layout]],
4509 [468, [revert_starred_caption]],
4510 [467, [revert_mbox_fbox]],
4511 [466, [revert_iwona_fonts]],
4512 [465, [revert_powerdot_flexes, revert_powerdot_pause, revert_powerdot_itemargs, revert_powerdot_columns]],
4514 [463, [revert_use_cancel]],
4515 [462, [revert_encodings]],
4516 [461, [revert_new_libertines]],
4517 [460, [revert_kurier_fonts]],
4518 [459, [revert_IEEEtran_3]],
4519 [458, [revert_fragileframe, revert_newframes]],
4520 [457, [revert_captioninsets, revert_captionlayouts]],
4521 [456, [revert_use_stackrel]],
4522 [455, [revert_epigraph]],
4523 [454, [revert_frametitle]],
4524 [453, [revert_overprint]],
4525 [452, [revert_use_stmaryrd]],
4526 [451, [revert_beamerblocks]],
4527 [450, [revert_beamerargs, revert_beamerargs2, revert_beamerargs3, revert_beamerflex]],
4528 [449, [revert_garamondx, revert_garamondx_newtxmath]],
4529 [448, [revert_itemargs]],
4530 [447, [revert_literate]],
4531 [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]],
4532 [445, [revert_latexargs]],
4533 [444, [revert_uop]],
4534 [443, [revert_biolinum]],
4536 [441, [revert_newtxmath]],
4537 [440, [revert_mdnomath]],
4538 [439, [revert_mathfonts]],
4539 [438, [revert_minionpro]],
4540 [437, [revert_ipadeco, revert_ipachar]],
4541 [436, [revert_texgyre]],
4542 [435, [revert_mathdesign]],
4543 [434, [revert_txtt]],
4544 [433, [revert_libertine]],
4545 [432, [revert_armenian]],
4546 [431, [revert_languages, revert_ancientgreek]],
4547 [430, [revert_use_amssymb]],
4548 [429, [revert_listoflistings]],
4549 [428, [revert_table_rotation]],
4550 [427, [revert_cell_rotation]],
4551 [426, [revert_tipa]],
4552 [425, [revert_verbatim]],
4553 [424, [revert_cancel]],
4554 [423, [revert_cite_engine_type]],
4555 [422, [revert_use_mathtools]],
4556 [421, [revert_use_packages]],
4557 [420, [revert_longtable_captions]],
4558 [419, [revert_biblio_style]],
4559 [418, [revert_australian]],
4560 [417, [revert_justification]],
4561 [416, [revert_japanese_encodings]],
4562 [415, [revert_negative_space, revert_math_spaces]],
4563 [414, [revert_undertilde]],
4564 [413, [revert_visible_space]]
4568 if __name__ == "__main__":