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 realparbeg = parent[3]
1556 # Collect all arguments in this paragraph
1558 for p in range(parbeg, parend):
1559 m = rx.match(document.body[p])
1561 val = int(m.group(1))
1562 j = find_end_of_inset(document.body, p)
1563 # Revert to old syntax
1564 document.body[p] = "\\begin_inset Argument"
1566 document.warning("Malformed LyX document: Can't find end of Argument inset")
1569 args[val] = document.body[p : j + 1]
1571 realparend = realparend - len(document.body[p : j + 1])
1572 # Remove arg inset at this position
1573 del document.body[p : j + 1]
1576 # Now sort the arg insets
1578 for f in sorted(args):
1581 # Insert the sorted arg insets at paragraph begin
1582 document.body[realparbeg : realparbeg] = subst
1584 i = realparbeg + 1 + len(subst)
1587 def revert_IEEEtran(document):
1589 Reverts InsetArgument of
1592 Biography without photo
1595 if document.textclass == "IEEEtran":
1602 i = find_token(document.body, "\\begin_layout Page headings", i)
1604 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1607 i2 = find_token(document.body, "\\begin_inset Flex Paragraph Start", i2)
1609 revert_Argument_to_TeX_brace(document, i2, 0, 1, 1, False, False)
1612 j = find_token(document.body, "\\begin_layout Biography without photo", j)
1614 revert_Argument_to_TeX_brace(document, j, 0, 1, 1, True, False)
1617 k = find_token(document.body, "\\begin_layout Biography", k)
1618 kA = find_token(document.body, "\\begin_layout Biography without photo", k)
1619 if k == kA and k != -1:
1623 # start with the second argument, therefore 2
1624 revert_Argument_to_TeX_brace(document, k, 0, 2, 2, True, False)
1626 if i == -1 and i2 == -1 and j == -1 and k == -1:
1630 def revert_IEEEtran_2(document):
1632 Reverts Flex Paragraph Start to TeX-code
1634 if document.textclass == "IEEEtran":
1637 begin = find_token(document.body, "\\begin_inset Flex Paragraph Start", begin)
1640 end1 = find_end_of_inset(document.body, begin)
1641 document.body[end1 - 2 : end1 + 1] = put_cmd_in_ert("}")
1642 document.body[begin : begin + 4] = put_cmd_in_ert("\\IEEEPARstart{")
1646 def convert_IEEEtran(document):
1651 Biography without photo
1654 if document.textclass == "IEEEtran":
1660 i = find_token(document.body, "\\begin_layout Page headings", i)
1662 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
1665 j = find_token(document.body, "\\begin_layout Biography without photo", j)
1667 convert_TeX_brace_to_Argument(document, j, 1, 1, False, True, False)
1670 # assure that we don't handle Biography Biography without photo
1671 k = find_token(document.body, "\\begin_layout Biography", k)
1672 kA = find_token(document.body, "\\begin_layout Biography without photo", k - 1)
1673 if k == kA and k != -1:
1677 # the argument we want to convert is the second one
1678 convert_TeX_brace_to_Argument(document, k, 2, 2, False, True, False)
1680 if i == -1 and j == -1 and k == -1:
1684 def revert_AASTeX(document):
1685 " Reverts InsetArgument of Altaffilation to TeX-code "
1686 if document.textclass == "aastex":
1689 i = find_token(document.body, "\\begin_layout Altaffilation", i)
1692 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1696 def convert_AASTeX(document):
1697 " Converts ERT of Altaffilation to InsetArgument "
1698 if document.textclass == "aastex":
1701 i = find_token(document.body, "\\begin_layout Altaffilation", i)
1704 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
1708 def revert_AGUTeX(document):
1709 " Reverts InsetArgument of Author affiliation to TeX-code "
1710 if document.textclass == "agutex":
1713 i = find_token(document.body, "\\begin_layout Author affiliation", i)
1716 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1720 def convert_AGUTeX(document):
1721 " Converts ERT of Author affiliation to InsetArgument "
1722 if document.textclass == "agutex":
1725 i = find_token(document.body, "\\begin_layout Author affiliation", i)
1728 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
1732 def revert_IJMP(document):
1733 " Reverts InsetArgument of MarkBoth to TeX-code "
1734 if document.textclass == "ijmpc" or document.textclass == "ijmpd":
1737 i = find_token(document.body, "\\begin_layout MarkBoth", i)
1740 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1744 def convert_IJMP(document):
1745 " Converts ERT of MarkBoth to InsetArgument "
1746 if document.textclass == "ijmpc" or document.textclass == "ijmpd":
1749 i = find_token(document.body, "\\begin_layout MarkBoth", i)
1752 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
1756 def revert_SIGPLAN(document):
1757 " Reverts InsetArguments of SIGPLAN to TeX-code "
1758 if document.textclass == "sigplanconf":
1763 i = find_token(document.body, "\\begin_layout Conference", i)
1765 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1768 j = find_token(document.body, "\\begin_layout Author", j)
1770 revert_Argument_to_TeX_brace(document, j, 0, 1, 2, False, False)
1772 if i == -1 and j == -1:
1776 def convert_SIGPLAN(document):
1777 " Converts ERT of SIGPLAN to InsetArgument "
1778 if document.textclass == "sigplanconf":
1783 i = find_token(document.body, "\\begin_layout Conference", i)
1785 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
1788 j = find_token(document.body, "\\begin_layout Author", j)
1790 convert_TeX_brace_to_Argument(document, j, 1, 2, False, False, False)
1792 if i == -1 and j == -1:
1796 def revert_SIGGRAPH(document):
1797 " Reverts InsetArgument of Flex CRcat to TeX-code "
1798 if document.textclass == "acmsiggraph":
1801 i = find_token(document.body, "\\begin_inset Flex CRcat", i)
1804 revert_Argument_to_TeX_brace(document, i, 0, 1, 3, False, False)
1808 def convert_SIGGRAPH(document):
1809 " Converts ERT of Flex CRcat to InsetArgument "
1810 if document.textclass == "acmsiggraph":
1813 i = find_token(document.body, "\\begin_inset Flex CRcat", i)
1816 convert_TeX_brace_to_Argument(document, i, 1, 3, True, False, False)
1820 def revert_EuropeCV(document):
1821 " Reverts InsetArguments of europeCV to TeX-code "
1822 if document.textclass == "europecv":
1829 i = find_token(document.body, "\\begin_layout Item", i)
1831 revert_Argument_to_TeX_brace(document, i, 0, 2, 2, False, False)
1834 j = find_token(document.body, "\\begin_layout BulletedItem", j)
1836 revert_Argument_to_TeX_brace(document, j, 0, 2, 2, False, False)
1839 k = find_token(document.body, "\\begin_layout Language", k)
1841 revert_Argument_to_TeX_brace(document, k, 0, 2, 6, False, False)
1844 m = find_token(document.body, "\\begin_layout LastLanguage", m)
1846 revert_Argument_to_TeX_brace(document, m, 0, 2, 6, False, False)
1848 if i == -1 and j == -1 and k == -1 and m == -1:
1852 def convert_EuropeCV(document):
1853 " Converts ERT of europeCV to InsetArgument "
1854 if document.textclass == "europecv":
1861 i = find_token(document.body, "\\begin_layout Item", i)
1863 convert_TeX_brace_to_Argument(document, i, 2, 2, False, False, False)
1866 j = find_token(document.body, "\\begin_layout BulletedItem", j)
1868 convert_TeX_brace_to_Argument(document, j, 2, 2, False, False, False)
1871 k = find_token(document.body, "\\begin_layout Language", k)
1873 convert_TeX_brace_to_Argument(document, k, 2, 6, False, False, False)
1876 m = find_token(document.body, "\\begin_layout LastLanguage", m)
1878 convert_TeX_brace_to_Argument(document, m, 2, 6, False, False, False)
1880 if i == -1 and j == -1 and k == -1 and m == -1:
1884 def revert_ModernCV(document):
1885 " Reverts InsetArguments of modernCV to TeX-code "
1886 if document.textclass == "moderncv":
1894 j = find_token(document.body, "\\begin_layout Entry", j)
1896 revert_Argument_to_TeX_brace(document, j, 0, 1, 5, False, False)
1899 k = find_token(document.body, "\\begin_layout Item", k)
1901 revert_Argument_to_TeX_brace(document, k, 0, 1, 1, False, False)
1904 m = find_token(document.body, "\\begin_layout ItemWithComment", m)
1906 revert_Argument_to_TeX_brace(document, m, 0, 1, 2, False, False)
1907 document.body[m] = document.body[m].replace("\\begin_layout ItemWithComment", "\\begin_layout Language")
1910 o = find_token(document.body, "\\begin_layout DoubleItem", o)
1912 revert_Argument_to_TeX_brace(document, o, 0, 1, 3, False, False)
1913 document.body[o] = document.body[o].replace("\\begin_layout DoubleItem", "\\begin_layout Computer")
1916 p = find_token(document.body, "\\begin_layout Social", p)
1918 revert_Argument_to_TeX_brace(document, p, 0, 1, 1, False, True)
1920 if j == -1 and k == -1 and m == -1 and o == -1 and p == -1:
1924 def revert_ModernCV_2(document):
1925 " Reverts the Flex:Column inset of modernCV to TeX-code "
1926 if document.textclass == "moderncv":
1930 flex = find_token(document.body, "\\begin_inset Flex Column", flex)
1933 flexEnd = find_end_of_inset(document.body, flex)
1934 wasOpt = revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, False, True)
1935 revert_Argument_to_TeX_brace(document, flex, 0, 2, 2, False, False)
1936 flexEnd = find_end_of_inset(document.body, flex)
1938 document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\cvcolumn")
1940 document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\cvcolumn{")
1941 document.body[flexEnd + 4 : flexEnd + 7] = put_cmd_in_ert("}")
1945 def revert_ModernCV_3(document):
1946 " Reverts the Column style of modernCV to TeX-code "
1947 if document.textclass == "moderncv":
1948 # revert the layouts
1949 revert_ModernCV(document)
1951 # get the position of the end of the last column inset
1952 LastFlexEnd = revert_ModernCV_2(document)
1954 p = find_token(document.body, "\\begin_layout Columns", p)
1957 pEnd = find_end_of_layout(document.body, p)
1958 document.body[p] = document.body[p].replace("\\begin_layout Columns", "\\begin_layout Standard")
1959 if LastFlexEnd != -1:
1960 document.body[p + 1 : p + 1] = put_cmd_in_ert("\\begin{cvcolumns}")
1961 document.body[LastFlexEnd + 24 : LastFlexEnd + 24] = put_cmd_in_ert("\\end{cvcolumns}")
1965 def revert_ModernCV_4(document):
1966 " Reverts the style Social to TeX-code "
1967 if document.textclass == "moderncv":
1968 # revert the layouts
1969 revert_ModernCV(document)
1972 p = find_token(document.body, "\\begin_layout Social", p)
1975 pEnd = find_end_of_layout(document.body, p)
1976 document.body[p] = document.body[p].replace("\\begin_layout Social", "\\begin_layout Standard")
1977 document.body[p + 1 : p + 1] = put_cmd_in_ert("\\social")
1978 hasOpt = find_token(document.body, "[", p + 9)
1980 document.body[p + 30 : p + 30] = put_cmd_in_ert("{")
1981 document.body[p + 41 : p + 41] = put_cmd_in_ert("}")
1983 document.body[p + 11 : p + 11] = put_cmd_in_ert("{")
1984 document.body[p + 21 : p + 21] = put_cmd_in_ert("}")
1988 def convert_ModernCV(document):
1989 " Converts ERT of modernCV to InsetArgument "
1990 if document.textclass == "moderncv":
1998 i = find_token(document.body, "\\begin_layout DoubleItem", i)
2000 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
2001 document.body[o] = document.body[o].replace("\\begin_layout DoubleItem", "\\begin_layout DoubleListItem")
2004 j = find_token(document.body, "\\begin_layout Entry", j)
2006 convert_TeX_brace_to_Argument(document, j, 1, 5, False, False, False)
2009 k = find_token(document.body, "\\begin_layout Item", k)
2011 convert_TeX_brace_to_Argument(document, k, 1, 1, False, False, False)
2014 m = find_token(document.body, "\\begin_layout Language", m)
2016 convert_TeX_brace_to_Argument(document, m, 1, 2, False, False, False)
2018 if i == -1 and j == -1 and k == -1 and m == -1:
2022 def revert_Initials(document):
2023 " Reverts InsetArgument of Initial to TeX-code "
2026 i = find_token(document.body, "\\begin_layout Initial", i)
2029 # first arg (optional) and second arg (first mandatory) are supported in LyX 2.0.x
2030 revert_Argument_to_TeX_brace(document, i, 0, 3, 3, False, False)
2034 def convert_Initials(document):
2035 " Converts ERT of Initial to InsetArgument "
2038 i = find_token(document.body, "\\begin_layout Initial", i)
2041 convert_TeX_brace_to_Argument(document, i, 3, 3, False, False, False)
2045 def revert_literate(document):
2046 " Revert Literate document to old format "
2047 if del_token(document.header, "noweb", 0):
2048 document.textclass = "literate-" + document.textclass
2051 i = find_token(document.body, "\\begin_layout Chunk", i)
2054 document.body[i] = "\\begin_layout Scrap"
2058 def convert_literate(document):
2059 " Convert Literate document to new format"
2060 i = find_token(document.header, "\\textclass", 0)
2061 if (i != -1) and "literate-" in document.header[i]:
2062 document.textclass = document.header[i].replace("\\textclass literate-", "")
2063 j = find_token(document.header, "\\begin_modules", 0)
2065 document.header.insert(j + 1, "noweb")
2067 document.header.insert(i + 1, "\\end_modules")
2068 document.header.insert(i + 1, "noweb")
2069 document.header.insert(i + 1, "\\begin_modules")
2072 i = find_token(document.body, "\\begin_layout Scrap", i)
2075 document.body[i] = "\\begin_layout Chunk"
2079 def revert_itemargs(document):
2080 " Reverts \\item arguments to TeX-code "
2083 i = find_token(document.body, "\\begin_inset Argument item:", i)
2086 j = find_end_of_inset(document.body, i)
2087 # Find containing paragraph layout
2088 parent = get_containing_layout(document.body, i)
2090 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2094 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2095 endPlain = find_end_of_layout(document.body, beginPlain)
2096 content = document.body[beginPlain + 1 : endPlain]
2097 del document.body[i:j+1]
2098 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2099 document.body[parbeg : parbeg] = subst
2103 def revert_garamondx_newtxmath(document):
2104 " Revert native garamond newtxmath definition to LaTeX "
2106 i = find_token(document.header, "\\font_math", 0)
2109 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
2110 val = get_value(document.header, "\\font_math", i)
2111 if val == "garamondx-ntxm":
2112 add_to_preamble(document, "\\usepackage[garamondx]{newtxmath}")
2113 document.header[i] = "\\font_math auto"
2116 def revert_garamondx(document):
2117 " Revert native garamond font definition to LaTeX "
2119 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
2120 i = find_token(document.header, "\\font_roman garamondx", 0)
2123 j = find_token(document.header, "\\font_osf true", 0)
2126 preamble = "\\usepackage"
2128 preamble += "[osfI]"
2129 preamble += "{garamondx}"
2130 add_to_preamble(document, [preamble])
2131 document.header[i] = "\\font_roman default"
2134 def convert_beamerargs(document):
2135 " Converts beamer arguments to new layout "
2137 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2138 if document.textclass not in beamer_classes:
2141 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
2142 list_layouts = ["Itemize", "Enumerate", "Description"]
2143 rx = re.compile(r'^\\begin_inset Argument (\d+)$')
2147 i = find_token(document.body, "\\begin_inset Argument", i)
2150 # Find containing paragraph layout
2151 parent = get_containing_layout(document.body, i)
2153 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2158 layoutname = parent[0]
2159 for p in range(parbeg, parend):
2160 if layoutname in shifted_layouts:
2161 m = rx.match(document.body[p])
2163 argnr = int(m.group(1))
2165 document.body[p] = "\\begin_inset Argument %d" % argnr
2166 if layoutname == "AgainFrame":
2167 m = rx.match(document.body[p])
2169 document.body[p] = "\\begin_inset Argument 3"
2170 if document.body[p + 4] == "\\begin_inset ERT":
2171 if document.body[p + 9].startswith("<"):
2172 # This is an overlay specification
2174 document.body[p + 9] = document.body[p + 9][1:]
2175 if document.body[p + 9].endswith(">"):
2177 document.body[p + 9] = document.body[p + 9][:-1]
2179 document.body[p] = "\\begin_inset Argument 2"
2180 if layoutname in list_layouts:
2181 m = rx.match(document.body[p])
2183 if m.group(1) == "1":
2184 if document.body[p + 4] == "\\begin_inset ERT":
2185 if document.body[p + 9].startswith("<"):
2186 # This is an overlay specification
2188 document.body[p + 9] = document.body[p + 9][1:]
2189 if document.body[p + 9].endswith(">"):
2191 document.body[p + 9] = document.body[p + 9][:-1]
2192 elif document.body[p + 4].startswith("<"):
2193 # This is an overlay specification (without ERT)
2195 document.body[p + 4] = document.body[p + 4][1:]
2196 if document.body[p + 4].endswith(">"):
2198 document.body[p + 4] = document.body[p + 4][:-1]
2199 elif layoutname != "Itemize":
2201 document.body[p] = "\\begin_inset Argument 2"
2206 # Helper function for the frame conversion routines
2208 # FIXME: This method currently requires the arguments to be either
2209 # * In one (whole) ERT each: <ERT>[<arg1>]</ERT><ERT><arg2></ERT><ERT>[arg3]</ERT>
2210 # * Altogether in one whole ERT: <ERT>[<arg1>]<arg2>[arg3]</ERT>
2211 # If individual arguments mix ERT and non-ERT or are splitted
2212 # over several ERTs, the parsing fails.
2213 def convert_beamerframeargs(document, i, parbeg):
2216 if document.body[parbeg] != "\\begin_inset ERT":
2218 ertend = find_end_of_inset(document.body, parbeg)
2220 document.warning("Malformed LyX document: missing ERT \\end_inset")
2222 ertcont = parbeg + 5
2223 if document.body[ertcont].startswith("[<"):
2224 # This is a default overlay specification
2226 document.body[ertcont] = document.body[ertcont][2:]
2227 if document.body[ertcont].endswith(">]"):
2229 document.body[ertcont] = document.body[ertcont][:-2]
2230 elif document.body[ertcont].endswith("]"):
2232 tok = document.body[ertcont].find('>][')
2234 subst = [document.body[ertcont][:tok],
2235 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2236 'status collapsed', '', '\\begin_layout Plain Layout',
2237 document.body[ertcont][tok + 3:-1]]
2238 document.body[ertcont : ertcont + 1] = subst
2240 # Convert to ArgInset
2241 document.body[parbeg] = "\\begin_inset Argument 2"
2242 elif document.body[ertcont].startswith("<"):
2243 # This is an overlay specification
2245 document.body[ertcont] = document.body[ertcont][1:]
2246 if document.body[ertcont].endswith(">"):
2248 document.body[ertcont] = document.body[ertcont][:-1]
2249 # Convert to ArgInset
2250 document.body[parbeg] = "\\begin_inset Argument 1"
2251 elif document.body[ertcont].endswith(">]"):
2253 tok = document.body[ertcont].find('>[<')
2255 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2256 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2257 'status collapsed', '', '\\begin_layout Plain Layout',
2258 document.body[ertcont][tok + 3:-2]]
2259 # Convert to ArgInset
2260 document.body[parbeg] = "\\begin_inset Argument 1"
2262 elif document.body[ertcont].endswith("]"):
2264 tok = document.body[ertcont].find('>[<')
2267 tokk = document.body[ertcont].find('>][')
2269 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2270 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2271 'status collapsed', '', '\\begin_layout Plain Layout',
2272 document.body[ertcont][tok + 3:tokk],
2273 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2274 'status collapsed', '', '\\begin_layout Plain Layout',
2275 document.body[ertcont][tokk + 3:-1]]
2278 tokk = document.body[ertcont].find('>[')
2280 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tokk],
2281 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2282 'status collapsed', '', '\\begin_layout Plain Layout',
2283 document.body[ertcont][tokk + 2:-1]]
2285 # Convert to ArgInset
2286 document.body[parbeg] = "\\begin_inset Argument 1"
2287 elif document.body[ertcont].startswith("["):
2288 # This is an ERT option
2290 document.body[ertcont] = document.body[ertcont][1:]
2291 if document.body[ertcont].endswith("]"):
2293 document.body[ertcont] = document.body[ertcont][:-1]
2294 # Convert to ArgInset
2295 document.body[parbeg] = "\\begin_inset Argument 3"
2301 def convert_againframe_args(document):
2302 " Converts beamer AgainFrame to new layout "
2304 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2305 if document.textclass not in beamer_classes:
2310 i = find_token(document.body, "\\begin_layout AgainFrame", i)
2313 parent = get_containing_layout(document.body, i)
2315 document.warning("Wrong parent layout!")
2319 # Convert ERT arguments
2320 # FIXME: See restrictions in convert_beamerframeargs method
2321 ertend = convert_beamerframeargs(document, i, parbeg)
2327 def convert_corollary_args(document):
2328 " Converts beamer corrolary-style ERT arguments native InsetArgs "
2330 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2331 if document.textclass not in beamer_classes:
2334 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2335 for lay in corollary_layouts:
2338 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2341 parent = get_containing_layout(document.body, i)
2343 document.warning("Wrong parent layout!")
2347 if document.body[parbeg] == "\\begin_inset ERT":
2348 ertcont = parbeg + 5
2349 if document.body[ertcont].startswith("<"):
2350 # This is an overlay specification
2352 document.body[ertcont] = document.body[ertcont][1:]
2353 if document.body[ertcont].endswith(">"):
2355 document.body[ertcont] = document.body[ertcont][:-1]
2356 elif document.body[ertcont].endswith("]"):
2358 tok = document.body[ertcont].find('>[')
2360 subst = [document.body[ertcont][:tok],
2361 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2362 'status collapsed', '', '\\begin_layout Plain Layout',
2363 document.body[ertcont][tok + 2:-1]]
2364 document.body[ertcont : ertcont + 1] = subst
2365 # Convert to ArgInset
2366 document.body[parbeg] = "\\begin_inset Argument 1"
2369 elif document.body[ertcont].startswith("["):
2370 if document.body[ertcont].endswith("]"):
2371 # This is an ERT option
2373 document.body[ertcont] = document.body[ertcont][1:]
2375 document.body[ertcont] = document.body[ertcont][:-1]
2376 # Convert to ArgInset
2377 document.body[parbeg] = "\\begin_inset Argument 2"
2379 convert_TeX_brace_to_Argument(document, i, 2, 2, False, True, True)
2386 def convert_quote_args(document):
2387 " Converts beamer quote style ERT args to native InsetArgs "
2389 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2390 if document.textclass not in beamer_classes:
2393 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2394 for lay in quote_layouts:
2397 i = find_token(document.body, "\\begin_layout " + lay, i)
2400 parent = get_containing_layout(document.body, i)
2402 document.warning("Wrong parent layout!")
2406 if document.body[parbeg] == "\\begin_inset ERT":
2407 if document.body[i + 6].startswith("<"):
2408 # This is an overlay specification
2410 document.body[i + 6] = document.body[i + 6][1:]
2411 if document.body[i + 6].endswith(">"):
2413 document.body[i + 6] = document.body[i + 6][:-1]
2414 # Convert to ArgInset
2415 document.body[i + 1] = "\\begin_inset Argument 1"
2419 def revert_beamerargs(document):
2420 " Reverts beamer arguments to old layout "
2422 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2423 if document.textclass not in beamer_classes:
2427 list_layouts = ["Itemize", "Enumerate", "Description"]
2428 headings = ["Part", "Section", "Section*", "Subsection", "Subsection*",
2429 "Subsubsection", "Subsubsection*", "FrameSubtitle", "NoteItem"]
2430 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2431 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2432 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2435 i = find_token(document.body, "\\begin_inset Argument", i)
2438 # Find containing paragraph layout
2439 parent = get_containing_layout(document.body, i)
2441 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2446 realparbeg = parent[3]
2447 layoutname = parent[0]
2449 for p in range(parbeg, parend):
2453 if layoutname in headings:
2454 m = rx.match(document.body[p])
2458 # Find containing paragraph layout
2459 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2460 endPlain = find_end_of_layout(document.body, beginPlain)
2461 endInset = find_end_of_inset(document.body, p)
2462 argcontent = document.body[beginPlain + 1 : endPlain]
2464 realparend = realparend - len(document.body[p : endInset + 1])
2466 del document.body[p : endInset + 1]
2467 if layoutname == "FrameSubtitle":
2468 pre = put_cmd_in_ert("\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2469 elif layoutname == "NoteItem":
2470 pre = put_cmd_in_ert("\\note<") + argcontent + put_cmd_in_ert(">[item]")
2471 elif layoutname.endswith('*'):
2472 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower()[:-1] + "<") + argcontent + put_cmd_in_ert(">*")
2474 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2475 secarg = find_token(document.body, "\\begin_inset Argument 2", parbeg, parend)
2477 # Find containing paragraph layout
2478 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", secarg)
2479 endPlain = find_end_of_layout(document.body, beginPlain)
2480 endInset = find_end_of_inset(document.body, secarg)
2481 argcontent = document.body[beginPlain + 1 : endPlain]
2483 realparend = realparend - len(document.body[secarg : endInset + 1])
2484 del document.body[secarg : endInset + 1]
2485 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2486 pre += put_cmd_in_ert("{")
2487 document.body[parbeg] = "\\begin_layout Standard"
2488 document.body[realparbeg : realparbeg] = pre
2489 pe = find_end_of_layout(document.body, parbeg)
2490 post = put_cmd_in_ert("}")
2491 document.body[pe : pe] = post
2492 realparend += len(pre) + len(post)
2493 if layoutname == "AgainFrame":
2494 m = rx.match(document.body[p])
2498 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2499 endPlain = find_end_of_layout(document.body, beginPlain)
2500 endInset = find_end_of_inset(document.body, p)
2501 content = document.body[beginPlain + 1 : endPlain]
2503 realparend = realparend - len(document.body[p : endInset + 1])
2505 del document.body[p : endInset + 1]
2506 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2507 document.body[realparbeg : realparbeg] = subst
2508 if layoutname == "Overprint":
2509 m = rx.match(document.body[p])
2513 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2514 endPlain = find_end_of_layout(document.body, beginPlain)
2515 endInset = find_end_of_inset(document.body, p)
2516 content = document.body[beginPlain + 1 : endPlain]
2518 realparend = realparend - len(document.body[p : endInset + 1])
2520 del document.body[p : endInset + 1]
2521 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2522 document.body[realparbeg : realparbeg] = subst
2523 if layoutname == "OverlayArea":
2524 m = rx.match(document.body[p])
2528 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2529 endPlain = find_end_of_layout(document.body, beginPlain)
2530 endInset = find_end_of_inset(document.body, p)
2531 content = document.body[beginPlain + 1 : endPlain]
2533 realparend = realparend - len(document.body[p : endInset + 1])
2535 del document.body[p : endInset + 1]
2536 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2537 document.body[realparbeg : realparbeg] = subst
2538 if layoutname in list_layouts:
2539 m = rx.match(document.body[p])
2543 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2544 endPlain = find_end_of_layout(document.body, beginPlain)
2545 endInset = find_end_of_inset(document.body, p)
2546 content = document.body[beginPlain + 1 : endPlain]
2547 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2548 realparend = realparend + len(subst) - len(content)
2549 document.body[beginPlain + 1 : endPlain] = subst
2550 elif argnr == "item:1":
2551 j = find_end_of_inset(document.body, i)
2552 # Find containing paragraph layout
2553 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2554 endPlain = find_end_of_layout(document.body, beginPlain)
2555 content = document.body[beginPlain + 1 : endPlain]
2556 del document.body[i:j+1]
2557 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2558 document.body[realparbeg : realparbeg] = subst
2559 elif argnr == "item:2":
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 if layoutname in quote_layouts:
2569 m = rx.match(document.body[p])
2573 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2574 endPlain = find_end_of_layout(document.body, beginPlain)
2575 endInset = find_end_of_inset(document.body, p)
2576 content = document.body[beginPlain + 1 : endPlain]
2578 realparend = realparend - len(document.body[p : endInset + 1])
2580 del document.body[p : endInset + 1]
2581 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2582 document.body[realparbeg : realparbeg] = subst
2583 if layoutname in corollary_layouts:
2584 m = rx.match(document.body[p])
2588 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2589 endPlain = find_end_of_layout(document.body, beginPlain)
2590 endInset = find_end_of_inset(document.body, p)
2591 content = document.body[beginPlain + 1 : endPlain]
2593 realparend = realparend - len(document.body[p : endInset + 1])
2595 del document.body[p : endInset + 1]
2596 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2597 document.body[realparbeg : realparbeg] = subst
2602 def revert_beamerargs2(document):
2603 " Reverts beamer arguments to old layout, step 2 "
2605 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2606 if document.textclass not in beamer_classes:
2610 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
2611 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2612 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2615 i = find_token(document.body, "\\begin_inset Argument", i)
2618 # Find containing paragraph layout
2619 parent = get_containing_layout(document.body, i)
2621 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2626 realparbeg = parent[3]
2627 layoutname = parent[0]
2629 for p in range(parbeg, parend):
2633 if layoutname in shifted_layouts:
2634 m = rx.match(document.body[p])
2638 document.body[p] = "\\begin_inset Argument 1"
2639 if layoutname in corollary_layouts:
2640 m = rx.match(document.body[p])
2644 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2645 endPlain = find_end_of_layout(document.body, beginPlain)
2646 endInset = find_end_of_inset(document.body, p)
2647 content = document.body[beginPlain + 1 : endPlain]
2649 realparend = realparend - len(document.body[p : endInset + 1])
2651 del document.body[p : endInset + 1]
2652 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2653 document.body[realparbeg : realparbeg] = subst
2654 if layoutname == "OverlayArea":
2655 m = rx.match(document.body[p])
2659 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2660 endPlain = find_end_of_layout(document.body, beginPlain)
2661 endInset = find_end_of_inset(document.body, p)
2662 content = document.body[beginPlain + 1 : endPlain]
2664 realparend = realparend - len(document.body[p : endInset + 1])
2666 del document.body[p : endInset + 1]
2667 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2668 document.body[realparbeg : realparbeg] = subst
2669 if layoutname == "AgainFrame":
2670 m = rx.match(document.body[p])
2674 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2675 endPlain = find_end_of_layout(document.body, beginPlain)
2676 endInset = find_end_of_inset(document.body, p)
2677 content = document.body[beginPlain + 1 : endPlain]
2679 realparend = realparend - len(document.body[p : endInset + 1])
2681 del document.body[p : endInset + 1]
2682 subst = put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
2683 document.body[realparbeg : realparbeg] = subst
2687 def revert_beamerargs3(document):
2688 " Reverts beamer arguments to old layout, step 3 "
2690 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2691 if document.textclass not in beamer_classes:
2694 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2697 i = find_token(document.body, "\\begin_inset Argument", i)
2700 # Find containing paragraph layout
2701 parent = get_containing_layout(document.body, i)
2703 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2708 realparbeg = parent[3]
2709 layoutname = parent[0]
2711 for p in range(parbeg, parend):
2715 if layoutname == "AgainFrame":
2716 m = rx.match(document.body[p])
2720 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2721 endPlain = find_end_of_layout(document.body, beginPlain)
2722 endInset = find_end_of_inset(document.body, p)
2723 content = document.body[beginPlain + 1 : endPlain]
2725 realparend = realparend - len(document.body[p : endInset + 1])
2727 del document.body[p : endInset + 1]
2728 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2729 document.body[realparbeg : realparbeg] = subst
2733 def revert_beamerflex(document):
2734 " Reverts beamer Flex insets "
2736 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2737 if document.textclass not in beamer_classes:
2740 new_flexes = {"Bold" : "\\textbf", "Emphasize" : "\\emph", "Only" : "\\only",
2741 "Uncover" : "\\uncover", "Visible" : "\\visible",
2742 "Invisible" : "\\invisible", "Alternative" : "\\alt",
2743 "Beamer_Note" : "\\note"}
2744 old_flexes = {"Alert" : "\\alert", "Structure" : "\\structure"}
2745 rx = re.compile(r'^\\begin_inset Flex (.+)$')
2749 i = find_token(document.body, "\\begin_inset Flex", i)
2752 m = rx.match(document.body[i])
2754 flextype = m.group(1)
2755 z = find_end_of_inset(document.body, i)
2757 document.warning("Can't find end of Flex " + flextype + " inset.")
2760 if flextype in new_flexes:
2761 pre = put_cmd_in_ert(new_flexes[flextype])
2762 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2764 argend = find_end_of_inset(document.body, arg)
2766 document.warning("Can't find end of Argument!")
2769 # Find containing paragraph layout
2770 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2771 endPlain = find_end_of_layout(document.body, beginPlain)
2772 argcontent = document.body[beginPlain + 1 : endPlain]
2774 z = z - len(document.body[arg : argend + 1])
2776 del document.body[arg : argend + 1]
2777 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2778 arg = find_token(document.body, "\\begin_inset Argument 2", i, z)
2780 argend = find_end_of_inset(document.body, arg)
2782 document.warning("Can't find end of Argument!")
2785 # Find containing paragraph layout
2786 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2787 endPlain = find_end_of_layout(document.body, beginPlain)
2788 argcontent = document.body[beginPlain + 1 : endPlain]
2790 z = z - len(document.body[arg : argend + 1])
2792 del document.body[arg : argend + 1]
2793 if flextype == "Alternative":
2794 pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
2796 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2797 pre += put_cmd_in_ert("{")
2798 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2799 endPlain = find_end_of_layout(document.body, beginPlain)
2801 z = z - len(document.body[i : beginPlain + 1])
2803 document.body[i : beginPlain + 1] = pre
2804 post = put_cmd_in_ert("}")
2805 document.body[z - 2 : z + 1] = post
2806 elif flextype in old_flexes:
2807 pre = put_cmd_in_ert(old_flexes[flextype])
2808 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2812 argend = find_end_of_inset(document.body, arg)
2814 document.warning("Can't find end of Argument!")
2817 # Find containing paragraph layout
2818 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2819 endPlain = find_end_of_layout(document.body, beginPlain)
2820 argcontent = document.body[beginPlain + 1 : endPlain]
2822 z = z - len(document.body[arg : argend + 1])
2824 del document.body[arg : argend + 1]
2825 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2826 pre += put_cmd_in_ert("{")
2827 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2828 endPlain = find_end_of_layout(document.body, beginPlain)
2830 z = z - len(document.body[i : beginPlain + 1])
2832 document.body[i : beginPlain + 1] = pre
2833 post = put_cmd_in_ert("}")
2834 document.body[z - 2 : z + 1] = post
2839 def revert_beamerblocks(document):
2840 " Reverts beamer block arguments to ERT "
2842 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2843 if document.textclass not in beamer_classes:
2846 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2848 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2851 i = find_token(document.body, "\\begin_inset Argument", i)
2854 # Find containing paragraph layout
2855 parent = get_containing_layout(document.body, i)
2857 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2862 realparbeg = parent[3]
2863 layoutname = parent[0]
2865 for p in range(parbeg, parend):
2869 if layoutname in blocks:
2870 m = rx.match(document.body[p])
2874 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2875 endPlain = find_end_of_layout(document.body, beginPlain)
2876 endInset = find_end_of_inset(document.body, p)
2877 content = document.body[beginPlain + 1 : endPlain]
2879 realparend = realparend - len(document.body[p : endInset + 1])
2881 del document.body[p : endInset + 1]
2882 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2883 document.body[realparbeg : realparbeg] = subst
2885 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2886 endPlain = find_end_of_layout(document.body, beginPlain)
2887 endInset = find_end_of_inset(document.body, p)
2888 content = document.body[beginPlain + 1 : endPlain]
2890 realparend = realparend - len(document.body[p : endInset + 1])
2892 del document.body[p : endInset + 1]
2893 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2894 document.body[realparbeg : realparbeg] = subst
2899 def convert_beamerblocks(document):
2900 " Converts beamer block ERT args to native InsetArgs "
2902 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2903 if document.textclass not in beamer_classes:
2906 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2910 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2913 parent = get_containing_layout(document.body, i)
2914 if parent == False or parent[1] != i:
2915 document.warning("Wrong parent layout!")
2922 if document.body[parbeg] == "\\begin_inset ERT":
2923 ertcontfirstline = parbeg + 5
2924 ertcontlastline = parend - 6
2926 if document.body[ertcontfirstline].startswith("<"):
2927 # This is an overlay specification
2929 document.body[ertcontfirstline] = document.body[ertcontfirstline][1:]
2930 if document.body[ertcontlastline].endswith(">"):
2932 document.body[ertcontlastline] = document.body[ertcontlastline][:-1]
2933 # Convert to ArgInset
2934 document.body[parbeg] = "\\begin_inset Argument 1"
2935 elif document.body[ertcontlastline].endswith("}"):
2937 document.body[ertcontlastline] = document.body[ertcontlastline][:-1]
2939 ertcontdivline = ertcontfirstline
2940 tok = document.body[ertcontdivline].find('>{')
2942 regexp = re.compile(r'.*>\{', re.IGNORECASE)
2943 ertcontdivline = find_re(document.body, regexp, ertcontfirstline, ertcontlastline)
2944 tok = document.body[ertcontdivline].find('>{')
2946 if ertcontfirstline < ertcontlastline:
2947 # Multiline ERT. Might contain TeX code. Embrace in ERT.
2948 document.body[ertcontlastline : ertcontlastline + 1] = [
2949 document.body[ertcontlastline], '\\end_layout', '', '\\end_inset']
2950 document.body[ertcontdivline : ertcontdivline + 1] = [document.body[ertcontdivline][:tok],
2951 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2952 'status collapsed', '', '\\begin_layout Plain Layout',
2953 '\\begin_inset ERT', '', 'status open' '', '\\begin_layout Plain Layout',
2954 document.body[ertcontdivline][tok + 2:]]
2956 document.body[ertcontdivline : ertcontdivline + 1] = [document.body[ertcontdivline][:tok],
2957 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2958 'status collapsed', '', '\\begin_layout Plain Layout',
2959 document.body[ertcontdivline][tok + 2:]]
2960 # Convert to ArgInset
2961 document.body[parbeg] = "\\begin_inset Argument 1"
2962 elif document.body[ertcontfirstline].startswith("{"):
2963 # This is the block title
2964 if document.body[ertcontlastline].endswith("}"):
2965 # strip off the braces
2966 document.body[ertcontfirstline] = document.body[ertcontfirstline][1:]
2967 document.body[ertcontlastline] = document.body[ertcontlastline][:-1]
2968 if ertcontfirstline < ertcontlastline:
2969 # Multiline ERT. Might contain TeX code. Embrace in ERT.
2970 document.body[parend : parend + 1] = [
2971 document.body[parend], '\\end_layout', '', '\\end_inset']
2972 document.body[parbeg : parbeg + 1] = ['\\begin_inset Argument 2',
2973 'status collapsed', '', '\\begin_layout Plain Layout',
2974 '\\begin_inset ERT', '']
2976 # Convert to ArgInset
2977 document.body[parbeg] = "\\begin_inset Argument 2"
2978 elif count_pars_in_inset(document.body, ertcontfirstline) > 1:
2979 # Multipar ERT. Skip this.
2982 convert_TeX_brace_to_Argument(document, i, 2, 2, False, True, False)
2985 j = find_end_of_layout(document.body, i)
2987 document.warning("end of layout not found!")
2988 k = find_token(document.body, "\\begin_inset Argument", i, j)
2990 document.warning("InsetArgument not found!")
2992 l = find_end_of_inset(document.body, k)
2993 m = find_token(document.body, "\\begin_inset ERT", l, j)
2996 ertcontfirstline = m + 5
3001 def convert_overprint(document):
3002 " Convert old beamer overprint layouts to ERT "
3004 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3005 if document.textclass not in beamer_classes:
3010 i = find_token(document.body, "\\begin_layout Overprint", i)
3013 # Find end of sequence
3014 j = find_end_of_sequence(document.body, i)
3016 document.warning("Malformed LyX document. Cannot find end of Overprint sequence!")
3020 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
3022 if document.body[j] == "\\end_deeper":
3023 esubst = ["", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
3025 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
3026 endseq = endseq + len(esubst) - len(document.body[j : j])
3027 document.body[j : j] = esubst
3028 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
3030 argend = find_end_of_layout(document.body, argbeg)
3032 document.warning("Malformed LyX document. Cannot find end of Overprint argument!")
3035 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3036 endPlain = find_end_of_layout(document.body, beginPlain)
3037 content = document.body[beginPlain + 1 : endPlain]
3039 endseq = endseq - len(document.body[argbeg : argend + 1])
3041 del document.body[argbeg : argend + 1]
3042 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3044 endseq = endseq - len(document.body[i : i])
3045 document.body[i : i] = subst + ["\\end_layout"]
3046 endseq += len(subst)
3048 for p in range(i, endseq):
3049 if document.body[p] == "\\begin_layout Overprint":
3050 document.body[p] = "\\begin_layout Standard"
3055 def revert_overprint(document):
3056 " Revert old beamer overprint layouts to ERT "
3058 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3059 if document.textclass not in beamer_classes:
3064 i = find_token(document.body, "\\begin_layout Overprint", i)
3067 # Find end of sequence
3068 j = find_end_of_sequence(document.body, i)
3070 document.warning("Malformed LyX document. Cannot find end of Overprint sequence!")
3074 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
3075 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}")
3076 endseq = endseq + len(esubst) - len(document.body[j : j])
3077 if document.body[j] == "\\end_deeper":
3078 document.body[j : j] = ["\\end_deeper", ""] + esubst
3080 document.body[j : j] = esubst
3083 if document.body[r] == "\\begin_deeper":
3084 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3086 document.body[r] = ""
3087 document.body[s] = ""
3091 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
3093 argend = find_end_of_inset(document.body, argbeg)
3095 document.warning("Malformed LyX document. Cannot find end of Overprint argument!")
3098 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3099 endPlain = find_end_of_layout(document.body, beginPlain)
3100 content = document.body[beginPlain + 1 : endPlain]
3102 endseq = endseq - len(document.body[argbeg : argend])
3104 del document.body[argbeg : argend + 1]
3105 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3107 endseq = endseq - len(document.body[i : i])
3108 document.body[i : i] = subst + ["\\end_layout"]
3109 endseq += len(subst)
3115 if document.body[p] == "\\begin_layout Overprint":
3116 q = find_end_of_layout(document.body, p)
3118 document.warning("Malformed LyX document. Cannot find end of Overprint layout!")
3121 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\onslide")
3122 argbeg = find_token(document.body, "\\begin_inset Argument item:1", p, q)
3124 argend = find_end_of_inset(document.body, argbeg)
3126 document.warning("Malformed LyX document. Cannot find end of Overprint item argument!")
3129 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3130 endPlain = find_end_of_layout(document.body, beginPlain)
3131 content = document.body[beginPlain + 1 : endPlain]
3133 endseq = endseq - len(document.body[argbeg : argend + 1])
3135 del document.body[argbeg : argend + 1]
3136 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3137 endseq = endseq - len(document.body[p : p + 1]) + len(subst)
3138 document.body[p : p + 1] = subst
3144 def revert_frametitle(document):
3145 " Reverts beamer frametitle layout to ERT "
3147 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3148 if document.textclass not in beamer_classes:
3151 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
3154 i = find_token(document.body, "\\begin_layout FrameTitle", i)
3157 j = find_end_of_layout(document.body, i)
3159 document.warning("Malformed LyX document: Can't find end of FrameTitle layout")
3163 document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
3164 endlay += len(put_cmd_in_ert("}"))
3165 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\frametitle")
3166 for p in range(i, j):
3169 m = rx.match(document.body[p])
3173 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3174 endPlain = find_end_of_layout(document.body, beginPlain)
3175 endInset = find_end_of_inset(document.body, p)
3176 content = document.body[beginPlain + 1 : endPlain]
3178 endlay = endlay - len(document.body[p : endInset + 1])
3180 del document.body[p : endInset + 1]
3181 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3183 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3184 endPlain = find_end_of_layout(document.body, beginPlain)
3185 endInset = find_end_of_inset(document.body, p)
3186 content = document.body[beginPlain + 1 : endPlain]
3188 endlay = endlay - len(document.body[p : endInset + 1])
3190 del document.body[p : endInset + 1]
3191 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3193 subst += put_cmd_in_ert("{")
3194 document.body[i : i + 1] = subst
3198 def convert_epigraph(document):
3199 " Converts memoir epigraph to new syntax "
3201 if document.textclass != "memoir":
3206 i = find_token(document.body, "\\begin_layout Epigraph", i)
3209 j = find_end_of_layout(document.body, i)
3211 document.warning("Malformed LyX document: Can't find end of Epigraph layout")
3216 ert = find_token(document.body, "\\begin_inset ERT", i, j)
3218 endInset = find_end_of_inset(document.body, ert)
3219 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", ert)
3220 endPlain = find_end_of_layout(document.body, beginPlain)
3221 ertcont = beginPlain + 2
3222 if document.body[ertcont] == "}{":
3224 # Convert to ArgInset
3225 endlay = endlay - 2 * len(document.body[j])
3226 begsubst = ['\\begin_inset Argument post:1', 'status collapsed', '',
3227 '\\begin_layout Plain Layout']
3228 endsubst = ['\\end_layout', '', '\\end_inset', '', document.body[j]]
3229 document.body[j : j + 1] = endsubst
3230 document.body[endInset + 1 : endInset + 1] = begsubst
3232 endlay += len(begsubst) + len(endsubst)
3233 endlay = endlay - len(document.body[ert : endInset + 1])
3234 del document.body[ert : endInset + 1]
3239 def revert_epigraph(document):
3240 " Reverts memoir epigraph argument to ERT "
3242 if document.textclass != "memoir":
3247 i = find_token(document.body, "\\begin_layout Epigraph", i)
3250 j = find_end_of_layout(document.body, i)
3252 document.warning("Malformed LyX document: Can't find end of Epigraph layout")
3257 p = find_token(document.body, "\\begin_layout Argument post:1", i, j)
3259 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3260 endPlain = find_end_of_layout(document.body, beginPlain)
3261 endInset = find_end_of_inset(document.body, p)
3262 content = document.body[beginPlain + 1 : endPlain]
3264 endlay = endlay - len(document.body[p : endInset + 1])
3266 del document.body[p : endInset + 1]
3267 subst += put_cmd_in_ert("}{") + content
3269 subst += put_cmd_in_ert("}{")
3271 document.body[j : j] = subst + document.body[j : j]
3275 def convert_captioninsets(document):
3276 " Converts caption insets to new syntax "
3280 i = find_token(document.body, "\\begin_inset Caption", i)
3283 document.body[i] = "\\begin_inset Caption Standard"
3287 def revert_captioninsets(document):
3288 " Reverts caption insets to old syntax "
3292 i = find_token(document.body, "\\begin_inset Caption Standard", i)
3295 document.body[i] = "\\begin_inset Caption"
3299 def convert_captionlayouts(document):
3300 " Convert caption layouts to caption insets. "
3303 "Captionabove": "Above",
3304 "Captionbelow": "Below",
3305 "FigCaption" : "FigCaption",
3306 "Table_Caption" : "Table",
3307 "CenteredCaption" : "Centered",
3308 "Bicaption" : "Bicaption",
3313 i = find_token(document.body, "\\begin_layout", i)
3316 val = get_value(document.body, "\\begin_layout", i)
3317 if val in caption_dict.keys():
3318 j = find_end_of_layout(document.body, i)
3320 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3323 document.body[j:j] = ["\\end_layout", "", "\\end_inset", "", ""]
3324 document.body[i:i+1] = ["\\begin_layout %s" % document.default_layout,
3325 "\\begin_inset Caption %s" % caption_dict[val], "",
3326 "\\begin_layout %s" % document.default_layout]
3330 def revert_captionlayouts(document):
3331 " Revert caption insets to caption layouts. "
3334 "Above" : "Captionabove",
3335 "Below" : "Captionbelow",
3336 "FigCaption" : "FigCaption",
3337 "Table" : "Table_Caption",
3338 "Centered" : "CenteredCaption",
3339 "Bicaption" : "Bicaption",
3343 rx = re.compile(r'^\\begin_inset Caption (\S+)$')
3345 i = find_token(document.body, "\\begin_inset Caption", i)
3349 m = rx.match(document.body[i])
3353 if val not in caption_dict.keys():
3357 # We either need to delete the previous \begin_layout line, or we
3358 # need to end the previous layout if this inset is not in the first
3359 # position of the paragraph.
3360 layout_before = find_token_backwards(document.body, "\\begin_layout", i)
3361 if layout_before == -1:
3362 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3364 layout_line = document.body[layout_before]
3365 del_layout_before = True
3366 l = layout_before + 1
3368 if document.body[l] != "":
3369 del_layout_before = False
3372 if del_layout_before:
3373 del document.body[layout_before:i]
3376 document.body[i:i] = ["\\end_layout", ""]
3379 # Find start of layout in the inset and end of inset
3380 j = find_token(document.body, "\\begin_layout", i)
3382 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3384 k = find_end_of_inset(document.body, i)
3386 document.warning("Malformed LyX document: Missing `\\end_inset'.")
3389 # We either need to delete the following \end_layout line, or we need
3390 # to restart the old layout if this inset is not at the paragraph end.
3391 layout_after = find_token(document.body, "\\end_layout", k)
3392 if layout_after == -1:
3393 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3395 del_layout_after = True
3397 while l < layout_after:
3398 if document.body[l] != "":
3399 del_layout_after = False
3402 if del_layout_after:
3403 del document.body[k+1:layout_after+1]
3405 document.body[k+1:k+1] = [layout_line, ""]
3407 # delete \begin_layout and \end_inset and replace \begin_inset with
3408 # "\begin_layout XXX". This works because we can only have one
3409 # paragraph in the caption inset: The old \end_layout will be recycled.
3410 del document.body[k]
3411 if document.body[k] == "":
3412 del document.body[k]
3413 del document.body[j]
3414 if document.body[j] == "":
3415 del document.body[j]
3416 document.body[i] = "\\begin_layout %s" % caption_dict[val]
3417 if document.body[i+1] == "":
3418 del document.body[i+1]
3422 def revert_fragileframe(document):
3423 " Reverts beamer FragileFrame layout to ERT "
3425 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3426 if document.textclass not in beamer_classes:
3431 i = find_token(document.body, "\\begin_layout FragileFrame", i)
3434 # Find end of sequence
3435 j = find_end_of_sequence(document.body, i)
3437 document.warning("Malformed LyX document. Cannot find end of FragileFrame sequence!")
3441 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{frame}")
3442 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{frame}")
3443 endseq = endseq + len(esubst) - len(document.body[j : j])
3444 if document.body[j] == "\\end_deeper":
3445 document.body[j : j] = ["\\end_deeper", ""] + esubst
3447 document.body[j : j] = esubst
3448 for q in range(i, j):
3449 if document.body[q] == "\\begin_layout FragileFrame":
3450 document.body[q] = "\\begin_layout %s" % document.default_layout
3453 if document.body[r] == "\\begin_deeper":
3454 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3456 document.body[r] = ""
3457 document.body[s] = ""
3461 for p in range(1, 5):
3462 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, j)
3465 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3466 endPlain = find_end_of_layout(document.body, beginPlain)
3467 endInset = find_end_of_inset(document.body, arg)
3468 content = document.body[beginPlain + 1 : endPlain]
3470 j = j - len(document.body[arg : endInset + 1])
3472 del document.body[arg : endInset + 1]
3473 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3475 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3476 endPlain = find_end_of_layout(document.body, beginPlain)
3477 endInset = find_end_of_inset(document.body, arg)
3478 content = document.body[beginPlain + 1 : endPlain]
3480 j = j - len(document.body[arg : endInset + 1])
3482 del document.body[arg : endInset + 1]
3483 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3485 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3486 endPlain = find_end_of_layout(document.body, beginPlain)
3487 endInset = find_end_of_inset(document.body, arg)
3488 content = document.body[beginPlain + 1 : endPlain]
3490 j = j - len(document.body[arg : endInset + 1])
3492 del document.body[arg : endInset + 1]
3493 subst += put_cmd_in_ert("[fragile,") + content + put_cmd_in_ert("]")
3495 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3496 endPlain = find_end_of_layout(document.body, beginPlain)
3497 endInset = find_end_of_inset(document.body, arg)
3498 content = document.body[beginPlain + 1 : endPlain]
3500 j = j - len(document.body[arg : endInset + 1])
3502 del document.body[arg : endInset + 1]
3503 subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
3505 subst += put_cmd_in_ert("[fragile]")
3507 document.body[i : i + 1] = subst
3511 def revert_newframes(document):
3512 " Reverts beamer Frame and PlainFrame layouts to old forms "
3514 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3515 if document.textclass not in beamer_classes:
3519 "Frame" : "BeginFrame",
3520 "PlainFrame" : "BeginPlainFrame",
3523 rx = re.compile(r'^\\begin_layout (\S+)$')
3526 i = find_token(document.body, "\\begin_layout", i)
3530 m = rx.match(document.body[i])
3534 if val not in frame_dict.keys():
3537 # Find end of sequence
3538 j = find_end_of_sequence(document.body, i)
3540 document.warning("Malformed LyX document. Cannot find end of Frame sequence!")
3544 subst = ["\\begin_layout %s" % frame_dict[val]]
3545 esubst = ["\\end_layout", "", "\\begin_layout EndFrame", "", "\\end_layout"]
3546 endseq = endseq + len(esubst) - len(document.body[j : j])
3547 if document.body[j] == "\\end_deeper":
3548 document.body[j : j] = ["\\end_deeper", ""] + esubst
3550 document.body[j : j] = esubst
3551 for q in range(i, j):
3552 if document.body[q] == "\\begin_layout %s" % val:
3553 document.body[q] = "\\begin_layout %s" % document.default_layout
3556 if document.body[r] == "\\begin_deeper":
3557 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3559 document.body[r] = ""
3560 document.body[s] = ""
3564 l = find_end_of_layout(document.body, i)
3565 for p in range(1, 5):
3566 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, l)
3569 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3570 endPlain = find_end_of_layout(document.body, beginPlain)
3571 endInset = find_end_of_inset(document.body, arg)
3572 content = document.body[beginPlain + 1 : endPlain]
3574 l = l - len(document.body[arg : endInset + 1])
3576 del document.body[arg : endInset + 1]
3577 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3579 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3580 endPlain = find_end_of_layout(document.body, beginPlain)
3581 endInset = find_end_of_inset(document.body, arg)
3582 content = document.body[beginPlain + 1 : endPlain]
3584 l = l - len(document.body[arg : endInset + 1])
3586 del document.body[arg : endInset + 1]
3587 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3589 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3590 endPlain = find_end_of_layout(document.body, beginPlain)
3591 endInset = find_end_of_inset(document.body, arg)
3592 content = document.body[beginPlain + 1 : endPlain]
3594 l = l - len(document.body[arg : endInset + 1])
3596 del document.body[arg : endInset + 1]
3597 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3599 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3600 endPlain = find_end_of_layout(document.body, beginPlain)
3601 endInset = find_end_of_inset(document.body, arg)
3602 content = document.body[beginPlain + 1 : endPlain]
3604 l = l - len(document.body[arg : endInset + 1])
3606 del document.body[arg : endInset + 1]
3609 document.body[i : i + 1] = subst
3612 # known encodings that do not change their names (same LyX and LaTeX names)
3613 known_enc_tuple = ("auto", "default", "ansinew", "applemac", "armscii8", "ascii",
3614 "cp437", "cp437de", "cp850", "cp852", "cp855", "cp858", "cp862", "cp865", "cp866",
3615 "cp1250", "cp1251", "cp1252", "cp1255", "cp1256", "cp1257", "koi8-r", "koi8-u",
3616 "pt154", "pt254", "tis620-0", "utf8", "utf8x", "utf8-plain")
3618 def convert_encodings(document):
3619 "Use the LyX names of the encodings instead of the LaTeX names."
3620 LaTeX2LyX_enc_dict = {
3621 "8859-6": "iso8859-6",
3622 "8859-8": "iso8859-8",
3624 "euc": "euc-jp-platex",
3629 "iso88595": "iso8859-5",
3630 "iso-8859-7": "iso8859-7",
3632 "jis": "jis-platex",
3634 "l7xenc": "iso8859-13",
3635 "latin1": "iso8859-1",
3636 "latin2": "iso8859-2",
3637 "latin3": "iso8859-3",
3638 "latin4": "iso8859-4",
3639 "latin5": "iso8859-9",
3640 "latin9": "iso8859-15",
3641 "latin10": "iso8859-16",
3642 "SJIS": "shift-jis",
3643 "sjis": "shift-jis-platex",
3646 i = find_token(document.header, "\\inputencoding" , 0)
3649 val = get_value(document.header, "\\inputencoding", i)
3650 if val in LaTeX2LyX_enc_dict.keys():
3651 document.header[i] = "\\inputencoding %s" % LaTeX2LyX_enc_dict[val]
3652 elif val not in known_enc_tuple:
3653 document.warning("Ignoring unknown input encoding: `%s'" % val)
3656 def revert_encodings(document):
3657 """Revert to using the LaTeX names of the encodings instead of the LyX names.
3658 Also revert utf8-platex to sjis, the language default when using Japanese.
3660 LyX2LaTeX_enc_dict = {
3665 "euc-jp-platex": "euc",
3668 "iso8859-1": "latin1",
3669 "iso8859-2": "latin2",
3670 "iso8859-3": "latin3",
3671 "iso8859-4": "latin4",
3672 "iso8859-5": "iso88595",
3673 "iso8859-6": "8859-6",
3674 "iso8859-7": "iso-8859-7",
3675 "iso8859-8": "8859-8",
3676 "iso8859-9": "latin5",
3677 "iso8859-13": "l7xenc",
3678 "iso8859-15": "latin9",
3679 "iso8859-16": "latin10",
3681 "jis-platex": "jis",
3682 "shift-jis": "SJIS",
3683 "shift-jis-platex": "sjis",
3685 "utf8-platex": "sjis"
3687 i = find_token(document.header, "\\inputencoding" , 0)
3690 val = get_value(document.header, "\\inputencoding", i)
3691 if val in LyX2LaTeX_enc_dict.keys():
3692 document.header[i] = "\\inputencoding %s" % LyX2LaTeX_enc_dict[val]
3693 elif val not in known_enc_tuple:
3694 document.warning("Ignoring unknown input encoding: `%s'" % val)
3697 def revert_IEEEtran_3(document):
3699 Reverts Flex Insets to TeX-code
3701 if document.textclass == "IEEEtran":
3707 h = find_token(document.body, "\\begin_inset Flex Author Mark", h)
3709 endh = find_end_of_inset(document.body, h)
3710 document.body[endh - 2 : endh + 1] = put_cmd_in_ert("}")
3711 document.body[h : h + 4] = put_cmd_in_ert("\\IEEEauthorrefmark{")
3714 i = find_token(document.body, "\\begin_inset Flex Author Name", i)
3716 endi = find_end_of_inset(document.body, i)
3717 document.body[endi - 2 : endi + 1] = put_cmd_in_ert("}")
3718 document.body[i : i + 4] = put_cmd_in_ert("\\IEEEauthorblockN{")
3721 j = find_token(document.body, "\\begin_inset Flex Author Affiliation", j)
3723 endj = find_end_of_inset(document.body, j)
3724 document.body[endj - 2 : endj + 1] = put_cmd_in_ert("}")
3725 document.body[j : j + 4] = put_cmd_in_ert("\\IEEEauthorblockA{")
3727 if i == -1 and j == -1 and h == -1:
3731 def revert_kurier_fonts(document):
3732 " Revert kurier font definition to LaTeX "
3734 i = find_token(document.header, "\\font_math", 0)
3736 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3737 val = get_value(document.header, "\\font_math", i)
3738 if val == "kurier-math":
3739 add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
3740 "\\usepackage[math]{kurier}\n" \
3741 "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
3742 document.header[i] = "\\font_math auto"
3744 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3745 kurier_fonts = ["kurier", "kurierc", "kurierl", "kurierlc"]
3746 k = find_token(document.header, "\\font_sans kurier", 0)
3748 sf = get_value(document.header, "\\font_sans", k)
3749 if sf in kurier_fonts:
3750 add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
3751 document.header[k] = "\\font_sans default"
3753 def revert_iwona_fonts(document):
3754 " Revert iwona font definition to LaTeX "
3756 i = find_token(document.header, "\\font_math", 0)
3758 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3759 val = get_value(document.header, "\\font_math", i)
3760 if val == "iwona-math":
3761 add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
3762 "\\usepackage[math]{iwona}\n" \
3763 "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
3764 document.header[i] = "\\font_math auto"
3766 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3767 iwona_fonts = ["iwona", "iwonac", "iwonal", "iwonalc"]
3768 k = find_token(document.header, "\\font_sans iwona", 0)
3770 sf = get_value(document.header, "\\font_sans", k)
3771 if sf in iwona_fonts:
3772 add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
3773 document.header[k] = "\\font_sans default"
3776 def revert_new_libertines(document):
3777 " Revert new libertine font definition to LaTeX "
3779 if find_token(document.header, "\\use_non_tex_fonts true", 0) != -1:
3782 i = find_token(document.header, "\\font_typewriter libertine-mono", 0)
3784 preamble = "\\usepackage"
3785 sc = find_token(document.header, "\\font_tt_scale", 0)
3787 scval = get_value(document.header, "\\font_tt_scale", sc)
3789 preamble += "[scale=%f]" % (float(scval) / 100)
3790 document.header[sc] = "\\font_tt_scale 100"
3791 preamble += "{libertineMono-type1}"
3792 add_to_preamble(document, [preamble])
3793 document.header[i] = "\\font_typewriter default"
3795 k = find_token(document.header, "\\font_sans biolinum", 0)
3797 preamble = "\\usepackage"
3799 j = find_token(document.header, "\\font_osf true", 0)
3804 sc = find_token(document.header, "\\font_sf_scale", 0)
3806 scval = get_value(document.header, "\\font_sf_scale", sc)
3808 options += ",scale=%f" % (float(scval) / 100)
3809 document.header[sc] = "\\font_sf_scale 100"
3811 preamble += "[" + options +"]"
3812 preamble += "{biolinum-type1}"
3813 add_to_preamble(document, [preamble])
3814 document.header[k] = "\\font_sans default"
3817 def convert_lyxframes(document):
3818 " Converts old beamer frames to new style "
3820 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3821 if document.textclass not in beamer_classes:
3824 framebeg = ["BeginFrame", "BeginPlainFrame"]
3825 frameend = ["Frame", "PlainFrame", "EndFrame", "BeginFrame", "BeginPlainFrame", "AgainFrame",
3826 "Section", "Section*", "Subsection", "Subsection*", "Subsubsection", "Subsubsection*"]
3827 for lay in framebeg:
3830 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
3833 parent = get_containing_layout(document.body, i)
3834 if parent == False or parent[1] != i:
3835 document.warning("Wrong parent layout!")
3838 frametype = parent[0]
3842 # Step I: Convert ERT arguments
3843 # FIXME: See restrictions in convert_beamerframeargs method
3844 ertend = convert_beamerframeargs(document, i, parbeg)
3847 # Step II: Now rename the layout and convert the title to an argument
3848 j = find_end_of_layout(document.body, i)
3849 document.body[j : j + 1] = ['\\end_layout', '', '\\end_inset', '', '\\end_layout']
3850 if lay == "BeginFrame":
3851 document.body[i] = "\\begin_layout Frame"
3853 document.body[i] = "\\begin_layout PlainFrame"
3854 document.body[ertend + 1 : ertend + 1] = ['\\begin_inset Argument 4',
3855 'status open', '', '\\begin_layout Plain Layout']
3856 # Step III: find real frame end
3860 fend = find_token(document.body, "\\begin_layout", jj)
3862 document.warning("Malformed LyX document: No real frame end!")
3864 val = get_value(document.body, "\\begin_layout", fend)
3865 if val not in frameend:
3868 old = document.body[fend]
3869 if val == frametype:
3870 document.body[fend : fend] = ['\\end_deeper', '', '\\begin_layout Separator', '', '\\end_layout']
3871 # consider explicit EndFrames between two identical frame types
3872 elif val == "EndFrame":
3873 nextlayout = find_token(document.body, "\\begin_layout", fend + 1)
3874 if nextlayout != -1 and get_value(document.body, "\\begin_layout", nextlayout) == frametype:
3875 document.body[fend : fend] = ['\\end_deeper', '', '\\begin_layout Separator', '', '\\end_layout']
3877 document.body[fend : fend] = ['\\end_deeper']
3879 document.body[fend : fend] = ['\\end_deeper']
3880 document.body[j + 1 : j + 1] = ['', '\\begin_deeper']
3885 def remove_endframes(document):
3886 " Remove deprecated beamer endframes "
3888 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3889 if document.textclass not in beamer_classes:
3894 i = find_token_exact(document.body, "\\begin_layout EndFrame", i)
3897 j = find_end_of_layout(document.body, i)
3899 document.warning("Malformed LyX document: Missing \\end_layout to EndFrame")
3902 del document.body[i : j + 1]
3905 def revert_powerdot_flexes(document):
3906 " Reverts powerdot flex insets "
3908 if document.textclass != "powerdot":
3911 flexes = {"Onslide" : "\\onslide",
3912 "Onslide*" : "\\onslide*",
3913 "Onslide+" : "\\onslide+"}
3914 rx = re.compile(r'^\\begin_inset Flex (.+)$')
3918 i = find_token(document.body, "\\begin_inset Flex", i)
3921 m = rx.match(document.body[i])
3923 flextype = m.group(1)
3924 z = find_end_of_inset(document.body, i)
3926 document.warning("Can't find end of Flex " + flextype + " inset.")
3929 if flextype in flexes:
3930 pre = put_cmd_in_ert(flexes[flextype])
3931 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
3933 argend = find_end_of_inset(document.body, arg)
3935 document.warning("Can't find end of Argument!")
3938 # Find containing paragraph layout
3939 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3940 endPlain = find_end_of_layout(document.body, beginPlain)
3941 argcontent = document.body[beginPlain + 1 : endPlain]
3943 z = z - len(document.body[arg : argend + 1])
3945 del document.body[arg : argend + 1]
3946 pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
3947 pre += put_cmd_in_ert("{")
3948 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
3949 endPlain = find_end_of_layout(document.body, beginPlain)
3951 z = z - len(document.body[i : beginPlain + 1])
3953 document.body[i : beginPlain + 1] = pre
3954 post = put_cmd_in_ert("}")
3955 document.body[z - 2 : z + 1] = post
3959 def revert_powerdot_pause(document):
3960 " Reverts powerdot pause layout to ERT "
3962 if document.textclass != "powerdot":
3967 i = find_token(document.body, "\\begin_layout Pause", i)
3970 j = find_end_of_layout(document.body, i)
3972 document.warning("Malformed LyX document: Can't find end of Pause layout")
3976 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\pause")
3977 for p in range(i, j):
3980 arg = find_token(document.body, "\\begin_inset Argument 1", i, j)
3982 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3983 endPlain = find_end_of_layout(document.body, beginPlain)
3984 endInset = find_end_of_inset(document.body, p)
3985 content = document.body[beginPlain + 1 : endPlain]
3987 endlay = endlay - len(document.body[p : endInset + 1])
3989 del document.body[p : endInset + 1]
3990 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3992 document.body[i : i + 1] = subst
3996 def revert_powerdot_itemargs(document):
3997 " Reverts powerdot item arguments to ERT "
3999 if document.textclass != "powerdot":
4003 list_layouts = ["Itemize", "ItemizeType1", "Enumerate", "EnumerateType1"]
4004 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
4007 i = find_token(document.body, "\\begin_inset Argument", i)
4010 # Find containing paragraph layout
4011 parent = get_containing_layout(document.body, i)
4013 document.warning("Malformed LyX document: Can't find parent paragraph layout")
4018 realparbeg = parent[3]
4019 layoutname = parent[0]
4021 for p in range(parbeg, parend):
4025 if layoutname in list_layouts:
4026 m = rx.match(document.body[p])
4029 if argnr == "item:1":
4030 j = find_end_of_inset(document.body, i)
4031 # Find containing paragraph layout
4032 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
4033 endPlain = find_end_of_layout(document.body, beginPlain)
4034 content = document.body[beginPlain + 1 : endPlain]
4035 del document.body[i:j+1]
4036 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
4037 document.body[realparbeg : realparbeg] = subst
4038 elif argnr == "item:2":
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
4051 def revert_powerdot_columns(document):
4052 " Reverts powerdot twocolumn to TeX-code "
4053 if document.textclass != "powerdot":
4056 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
4059 i = find_token(document.body, "\\begin_layout Twocolumn", i)
4062 j = find_end_of_layout(document.body, i)
4064 document.warning("Malformed LyX document: Can't find end of Twocolumn layout")
4068 document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
4069 endlay += len(put_cmd_in_ert("}"))
4070 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\twocolumn")
4071 for p in range(i, j):
4074 m = rx.match(document.body[p])
4078 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
4079 endPlain = find_end_of_layout(document.body, beginPlain)
4080 endInset = find_end_of_inset(document.body, p)
4081 content = document.body[beginPlain + 1 : endPlain]
4083 endlay = endlay - len(document.body[p : endInset + 1])
4085 del document.body[p : endInset + 1]
4086 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
4088 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
4089 endPlain = find_end_of_layout(document.body, beginPlain)
4090 endInset = find_end_of_inset(document.body, p)
4091 content = document.body[beginPlain + 1 : endPlain]
4093 endlay = endlay - len(document.body[p : endInset + 1])
4095 del document.body[p : endInset + 1]
4096 subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
4098 subst += put_cmd_in_ert("{")
4099 document.body[i : i + 1] = subst
4103 def revert_mbox_fbox(document):
4104 'Convert revert mbox/fbox boxes to TeX-code'
4107 i = find_token(document.body, "\\begin_inset Box", i)
4110 j = find_token(document.body, "width", i)
4112 document.warning("Malformed LyX document: Can't find box width")
4114 width = get_value(document.body, "width", j)
4115 k = find_end_of_inset(document.body, j)
4117 document.warning("Malformed LyX document: Can't find end of box inset")
4120 BeginLayout = find_token(document.body, "\\begin_layout Plain Layout", j)
4121 EndLayout = find_token(document.body, "\\end_layout", BeginLayout)
4122 # replace if width is ""
4124 document.body[EndLayout:k + 1] = put_cmd_in_ert("}")
4125 if document.body[i] == "\\begin_inset Box Frameless":
4126 document.body[i:BeginLayout + 1] = put_cmd_in_ert("\\mbox{")
4127 if document.body[i] == "\\begin_inset Box Boxed":
4128 document.body[i:BeginLayout + 1] = put_cmd_in_ert("\\fbox{")
4132 def revert_starred_caption(document):
4133 " Reverts unnumbered longtable caption insets "
4137 i = find_token(document.body, "\\begin_inset Caption LongTableNoNumber", i)
4140 # This is not equivalent, but since the caption inset is a full blown
4141 # text inset a true conversion to ERT is too difficult.
4142 document.body[i] = "\\begin_inset Caption Standard"
4146 def revert_forced_local_layout(document):
4149 i = find_token(document.header, "\\begin_forced_local_layout", i)
4152 j = find_end_of(document.header, i, "\\begin_forced_local_layout", "\\end_forced_local_layout")
4154 # this should not happen
4156 regexp = re.compile(r'\s*forcelocal', re.IGNORECASE)
4157 k = find_re(document.header, regexp, i, j)
4159 del document.header[k]
4161 k = find_re(document.header, regexp, i, j)
4162 k = find_token(document.header, "\\begin_local_layout", 0)
4164 document.header[i] = "\\begin_local_layout"
4165 document.header[j] = "\\end_local_layout"
4167 l = find_end_of(document.header, k, "\\begin_local_layout", "\\end_local_layout")
4169 # this should not happen
4171 lines = document.header[i+1 : j]
4173 document.header[k+1 : k+1] = lines
4174 document.header[i : j ] = []
4176 document.header[i : j ] = []
4177 document.header[k+1 : k+1] = lines
4180 def revert_aa1(document):
4181 " Reverts InsetArguments of aa to TeX-code "
4182 if document.textclass == "aa":
4186 i = find_token(document.body, "\\begin_layout Abstract (structured)", i)
4188 revert_Argument_to_TeX_brace(document, i, 0, 1, 4, False, False)
4194 def revert_aa2(document):
4195 " Reverts InsetArguments of aa to TeX-code "
4196 if document.textclass == "aa":
4200 i = find_token(document.body, "\\begin_layout Abstract (structured)", i)
4202 document.body[i] = "\\begin_layout Abstract"
4208 def revert_tibetan(document):
4209 "Set the document language for Tibetan to English"
4211 if document.language == "tibetan":
4212 document.language = "english"
4213 i = find_token(document.header, "\\language", 0)
4215 document.header[i] = "\\language english"
4217 while j < len(document.body):
4218 j = find_token(document.body, "\\lang tibetan", j)
4220 document.body[j] = document.body[j].replace("\\lang tibetan", "\\lang english")
4223 j = len(document.body)
4232 # The idea here is that we will have a sequence of chunk paragraphs.
4233 # We want to convert them to paragraphs in one or several chunk insets.
4234 # Individual chunks are terminated by the character @ on the last line.
4235 # This line will be discarded, and following lines are treated as new
4236 # chunks, which go into their own insets.
4237 # The first line of a chunk should look like: <<CONTENT>>=
4238 # We will discard the delimiters, and put the CONTENT into the
4239 # optional argument of the inset, if the CONTENT is non-empty.
4240 def convert_chunks(document):
4241 first_re = re.compile(r'<<(.*)>>=(.*)')
4244 # find start of a block of chunks
4245 i = find_token(document.body, "\\begin_layout Chunk", file_pos)
4251 chunk_started = False
4254 # process the one we just found
4255 j = find_end_of_layout(document.body, i)
4257 document.warning("Malformed LyX documents. Can't find end of Chunk layout!")
4258 # there is no point continuing, as we will run into the same error again.
4260 this_chunk = "".join(document.body[i + 1:j])
4262 # there may be empty lines between chunks
4263 # we just skip them.
4264 if not chunk_started:
4265 if this_chunk != "":
4267 chunk_started = True
4270 contents.append(document.body[i + 1:j])
4272 # look for potential chunk terminator
4273 # on the last line of the chunk paragraph
4274 if document.body[j - 1] == "@":
4277 # look for subsequent chunk paragraph
4278 i = find_token(document.body, "\\begin_layout", j)
4282 if get_value(document.body, "\\begin_layout", i) != "Chunk":
4285 file_pos = end = j + 1
4287 # The last chunk should simply have an "@" in it
4288 # or at least end with "@" (can happen if @ is
4289 # preceded by a newline)
4290 lastpar = ''.join(contents[-1])
4291 if not lastpar.endswith("@"):
4292 document.warning("Unexpected chunk content: chunk not terminated by '@'!")
4296 # chunk par only contains "@". Just drop it.
4299 # chunk par contains more. Only drop the "@".
4302 # The first line should look like: <<CONTENT>>=
4303 # We want the CONTENT
4304 optarg = ' '.join(contents[0])
4306 # We can already have real chunk content in
4307 # the first par (separated from the options by a newline).
4308 # We collect such stuff to re-insert it later.
4311 match = first_re.search(optarg)
4313 optarg = match.groups()[0]
4314 if match.groups()[1] != "":
4316 for c in contents[0]:
4317 if c.endswith(">>="):
4321 postoptstuff.append(c)
4322 # We have stripped everything. This can be deleted.
4325 newstuff = ['\\begin_layout Standard',
4326 '\\begin_inset Flex Chunk',
4328 '\\begin_layout Plain Layout', '']
4330 # If we have a non-empty optional argument, insert it.
4331 if match and optarg != "":
4333 ['\\begin_inset Argument 1',
4335 '\\begin_layout Plain Layout',
4340 # Since we already opened a Plain layout, the first paragraph
4341 # does not need to do that.
4344 newstuff.extend(postoptstuff)
4345 newstuff.append('\\end_layout')
4349 newstuff.extend(['', '\\begin_layout Plain Layout', ''])
4353 newstuff.append('\\end_layout')
4355 newstuff.extend(['', '\\end_inset', '', '\\end_layout', ''])
4357 document.body[start:end] = newstuff
4359 file_pos += len(newstuff) - (end - start)
4362 def revert_chunks(document):
4365 i = find_token(document.body, "\\begin_inset Flex Chunk", i)
4369 iend = find_end_of_inset(document.body, i)
4371 document.warning("Can't find end of Chunk!")
4375 # Look for optional argument
4377 ostart = find_token(document.body, "\\begin_inset Argument 1", i, iend)
4379 oend = find_end_of_inset(document.body, ostart)
4380 k = find_token(document.body, "\\begin_layout Plain Layout", ostart, oend)
4382 document.warning("Malformed LyX document: Can't find argument contents!")
4384 m = find_end_of_layout(document.body, k)
4385 optarg = "".join(document.body[k+1:m])
4388 # We now remove the optional argument, so we have something
4389 # uniform on which to work
4390 document.body[ostart : oend + 1] = []
4391 # iend is now invalid
4392 iend = find_end_of_inset(document.body, i)
4394 retval = get_containing_layout(document.body, i)
4396 document.warning("Can't find containing layout for Chunk!")
4399 (lname, lstart, lend, pstart) = retval
4400 # we now want to work through the various paragraphs, and collect their contents
4404 k = find_token(document.body, "\\begin_layout Plain Layout", k, lend)
4407 j = find_end_of_layout(document.body, k)
4409 document.warning("Can't find end of layout inside chunk!")
4411 parlist.append(document.body[k+1:j])
4413 # we now need to wrap all of these paragraphs in chunks
4416 newlines.extend(["\\begin_layout Chunk", "", "<<" + optarg + ">>=", "\\end_layout", ""])
4417 for stuff in parlist:
4418 newlines.extend(["\\begin_layout Chunk"] + stuff + ["\\end_layout", ""])
4419 newlines.extend(["\\begin_layout Chunk", "", "@", "\\end_layout", ""])
4420 # replace old content with new content
4421 document.body[lstart : lend + 1] = newlines
4422 i = lstart + len(newlines)
4429 supported_versions = ["2.1.0","2.1"]
4432 [415, [convert_undertilde]],
4434 [417, [convert_japanese_encodings]],
4435 [418, [convert_justification]],
4437 [420, [convert_biblio_style]],
4438 [421, [convert_longtable_captions]],
4439 [422, [convert_use_packages]],
4440 [423, [convert_use_mathtools]],
4441 [424, [convert_cite_engine_type]],
4445 [428, [convert_cell_rotation]],
4446 [429, [convert_table_rotation]],
4447 [430, [convert_listoflistings]],
4448 [431, [convert_use_amssymb]],
4450 [433, [convert_armenian]],
4458 [441, [convert_mdnomath]],
4463 [446, [convert_latexargs]],
4464 [447, [convert_IEEEtran, convert_AASTeX, convert_AGUTeX, convert_IJMP, convert_SIGPLAN, convert_SIGGRAPH, convert_EuropeCV, convert_Initials, convert_ModernCV]],
4465 [448, [convert_literate]],
4468 [451, [convert_beamerargs, convert_againframe_args, convert_corollary_args, convert_quote_args]],
4469 [452, [convert_beamerblocks]],
4470 [453, [convert_use_stmaryrd]],
4471 [454, [convert_overprint]],
4473 [456, [convert_epigraph]],
4474 [457, [convert_use_stackrel]],
4475 [458, [convert_captioninsets, convert_captionlayouts]],
4480 [463, [convert_encodings]],
4481 [464, [convert_use_cancel]],
4482 [465, [convert_lyxframes, remove_endframes]],
4488 [471, [convert_cite_engine_type_default]],
4491 [474, [convert_chunks]],
4495 [473, [revert_chunks]],
4496 [472, [revert_tibetan]],
4497 [471, [revert_aa1,revert_aa2]],
4498 [470, [revert_cite_engine_type_default]],
4499 [469, [revert_forced_local_layout]],
4500 [468, [revert_starred_caption]],
4501 [467, [revert_mbox_fbox]],
4502 [466, [revert_iwona_fonts]],
4503 [465, [revert_powerdot_flexes, revert_powerdot_pause, revert_powerdot_itemargs, revert_powerdot_columns]],
4505 [463, [revert_use_cancel]],
4506 [462, [revert_encodings]],
4507 [461, [revert_new_libertines]],
4508 [460, [revert_kurier_fonts]],
4509 [459, [revert_IEEEtran_3]],
4510 [458, [revert_fragileframe, revert_newframes]],
4511 [457, [revert_captioninsets, revert_captionlayouts]],
4512 [456, [revert_use_stackrel]],
4513 [455, [revert_epigraph]],
4514 [454, [revert_frametitle]],
4515 [453, [revert_overprint]],
4516 [452, [revert_use_stmaryrd]],
4517 [451, [revert_beamerblocks]],
4518 [450, [revert_beamerargs, revert_beamerargs2, revert_beamerargs3, revert_beamerflex]],
4519 [449, [revert_garamondx, revert_garamondx_newtxmath]],
4520 [448, [revert_itemargs]],
4521 [447, [revert_literate]],
4522 [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]],
4523 [445, [revert_latexargs]],
4524 [444, [revert_uop]],
4525 [443, [revert_biolinum]],
4527 [441, [revert_newtxmath]],
4528 [440, [revert_mdnomath]],
4529 [439, [revert_mathfonts]],
4530 [438, [revert_minionpro]],
4531 [437, [revert_ipadeco, revert_ipachar]],
4532 [436, [revert_texgyre]],
4533 [435, [revert_mathdesign]],
4534 [434, [revert_txtt]],
4535 [433, [revert_libertine]],
4536 [432, [revert_armenian]],
4537 [431, [revert_languages, revert_ancientgreek]],
4538 [430, [revert_use_amssymb]],
4539 [429, [revert_listoflistings]],
4540 [428, [revert_table_rotation]],
4541 [427, [revert_cell_rotation]],
4542 [426, [revert_tipa]],
4543 [425, [revert_verbatim]],
4544 [424, [revert_cancel]],
4545 [423, [revert_cite_engine_type]],
4546 [422, [revert_use_mathtools]],
4547 [421, [revert_use_packages]],
4548 [420, [revert_longtable_captions]],
4549 [419, [revert_biblio_style]],
4550 [418, [revert_australian]],
4551 [417, [revert_justification]],
4552 [416, [revert_japanese_encodings]],
4553 [415, [revert_negative_space, revert_math_spaces]],
4554 [414, [revert_undertilde]],
4555 [413, [revert_visible_space]]
4559 if __name__ == "__main__":