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 revert_justification(document):
391 " Revert the \\justification buffer param"
392 if not del_token(document.header, '\\justification', 0):
393 document.warning("Malformed LyX document: Missing \\justification.")
396 def revert_australian(document):
397 "Set English language variants Australian and Newzealand to English"
399 if document.language == "australian" or document.language == "newzealand":
400 document.language = "english"
401 i = find_token(document.header, "\\language", 0)
403 document.header[i] = "\\language english"
406 j = find_token(document.body, "\\lang australian", j)
408 j = find_token(document.body, "\\lang newzealand", 0)
412 document.body[j] = document.body[j].replace("\\lang newzealand", "\\lang english")
414 document.body[j] = document.body[j].replace("\\lang australian", "\\lang english")
418 def convert_biblio_style(document):
419 "Add a sensible default for \\biblio_style based on the citation engine."
420 i = find_token(document.header, "\\cite_engine", 0)
422 engine = get_value(document.header, "\\cite_engine", i).split("_")[0]
423 style = {"basic": "plain", "natbib": "plainnat", "jurabib": "jurabib"}
424 document.header.insert(i + 1, "\\biblio_style " + style[engine])
427 def revert_biblio_style(document):
428 "BibTeX insets with default option use the style defined by \\biblio_style."
429 i = find_token(document.header, "\\biblio_style" , 0)
431 document.warning("No \\biblio_style line. Nothing to do.")
434 default_style = get_value(document.header, "\\biblio_style", i)
435 del document.header[i]
437 # We are looking for bibtex insets having the default option
440 i = find_token(document.body, "\\begin_inset CommandInset bibtex", i)
443 j = find_end_of_inset(document.body, i)
445 document.warning("Malformed LyX document: Can't find end of bibtex inset at line " + str(i))
448 k = find_token(document.body, "options", i, j)
450 options = get_quoted_value(document.body, "options", k)
451 if "default" in options.split(","):
452 document.body[k] = 'options "%s"' \
453 % options.replace("default", default_style)
457 def handle_longtable_captions(document, forward):
460 begin_table = find_token(document.body, '<lyxtabular version=', begin_table)
461 if begin_table == -1:
463 end_table = find_end_of(document.body, begin_table, '<lyxtabular', '</lyxtabular>')
465 document.warning("Malformed LyX document: Could not find end of table.")
468 fline = find_token(document.body, "<features", begin_table, end_table)
470 document.warning("Can't find features for inset at line " + str(begin_table))
473 p = document.body[fline].find("islongtable")
478 numrows = get_option_value(document.body[begin_table], "rows")
480 numrows = int(numrows)
482 document.warning(document.body[begin_table])
483 document.warning("Unable to determine rows!")
484 begin_table = end_table
486 begin_row = begin_table
487 for row in range(numrows):
488 begin_row = find_token(document.body, '<row', begin_row, end_table)
490 document.warning("Can't find row " + str(row + 1))
492 end_row = find_end_of(document.body, begin_row, '<row', '</row>')
494 document.warning("Can't find end of row " + str(row + 1))
497 if (get_option_value(document.body[begin_row], 'caption') == 'true' and
498 get_option_value(document.body[begin_row], 'endfirsthead') != 'true' and
499 get_option_value(document.body[begin_row], 'endhead') != 'true' and
500 get_option_value(document.body[begin_row], 'endfoot') != 'true' and
501 get_option_value(document.body[begin_row], 'endlastfoot') != 'true'):
502 document.body[begin_row] = set_option_value(document.body[begin_row], 'caption', 'true", endfirsthead="true')
503 elif get_option_value(document.body[begin_row], 'caption') == 'true':
504 if get_option_value(document.body[begin_row], 'endfirsthead') == 'true':
505 document.body[begin_row] = set_option_value(document.body[begin_row], 'endfirsthead', 'false')
506 if get_option_value(document.body[begin_row], 'endhead') == 'true':
507 document.body[begin_row] = set_option_value(document.body[begin_row], 'endhead', 'false')
508 if get_option_value(document.body[begin_row], 'endfoot') == 'true':
509 document.body[begin_row] = set_option_value(document.body[begin_row], 'endfoot', 'false')
510 if get_option_value(document.body[begin_row], 'endlastfoot') == 'true':
511 document.body[begin_row] = set_option_value(document.body[begin_row], 'endlastfoot', 'false')
513 # since there could be a tabular inside this one, we
514 # cannot jump to end.
518 def convert_longtable_captions(document):
519 "Add a firsthead flag to caption rows"
520 handle_longtable_captions(document, True)
523 def revert_longtable_captions(document):
524 "remove head/foot flag from caption rows"
525 handle_longtable_captions(document, False)
528 def convert_use_packages(document):
529 "use_xxx yyy => use_package xxx yyy"
530 packages = ["amsmath", "esint", "mathdots", "mhchem", "undertilde"]
532 i = find_token(document.header, "\\use_%s" % p, 0)
534 value = get_value(document.header, "\\use_%s" % p, i)
535 document.header[i] = "\\use_package %s %s" % (p, value)
538 def revert_use_packages(document):
539 "use_package xxx yyy => use_xxx yyy"
540 packages = ["amsmath", "esint", "mathdots", "mhchem", "undertilde"]
541 # the order is arbitrary for the use_package version, and not all packages need to be given.
542 # Ensure a complete list and correct order (important for older LyX versions and especially lyx2lyx)
545 regexp = re.compile(r'(\\use_package\s+%s)' % p)
546 i = find_re(document.header, regexp, j)
548 value = get_value(document.header, "\\use_package %s" % p, i).split()[1]
549 del document.header[i]
551 document.header.insert(j, "\\use_%s %s" % (p, value))
555 def convert_use_package(document, pkg):
556 i = find_token(document.header, "\\use_package", 0)
558 document.warning("Malformed LyX document: Can't find \\use_package.")
560 j = find_token(document.preamble, "\\usepackage{" + pkg + "}", 0)
562 document.header.insert(i + 1, "\\use_package " + pkg + " 0")
564 document.header.insert(i + 1, "\\use_package " + pkg + " 2")
565 del document.preamble[j]
568 def revert_use_package(document, pkg, commands, oldauto):
569 # oldauto defines how the version we are reverting to behaves:
570 # if it is true, the old version uses the package automatically.
571 # if it is false, the old version never uses the package.
572 regexp = re.compile(r'(\\use_package\s+%s)' % pkg)
573 i = find_re(document.header, regexp, 0)
574 value = "1" # default is auto
576 value = get_value(document.header, "\\use_package" , i).split()[1]
577 del document.header[i]
578 if value == "2": # on
579 add_to_preamble(document, ["\\usepackage{" + pkg + "}"])
580 elif value == "1" and not oldauto: # auto
583 i = find_token(document.body, '\\begin_inset Formula', i)
586 j = find_end_of_inset(document.body, i)
588 document.warning("Malformed LyX document: Can't find end of Formula inset at line " + str(i))
591 code = "\n".join(document.body[i:j])
593 if code.find("\\%s" % c) != -1:
594 add_to_preamble(document, ["\\usepackage{" + pkg + "}"])
599 def convert_use_mathtools(document):
600 "insert use_package mathtools"
601 convert_use_package(document, "mathtools")
604 def revert_use_mathtools(document):
605 "remove use_package mathtools"
606 commands = ["mathclap", "mathllap", "mathrlap", \
607 "lgathered", "rgathered", "vcentcolon", "dblcolon", \
608 "coloneqq", "Coloneqq", "coloneq", "Coloneq", "eqqcolon", \
609 "Eqqcolon", "eqcolon", "Eqcolon", "colonapprox", \
610 "Colonapprox", "colonsim", "Colonsim"]
611 revert_use_package(document, "mathtools", commands, False)
614 def convert_use_stmaryrd(document):
615 "insert use_package stmaryrd"
616 convert_use_package(document, "stmaryrd")
619 def revert_use_stmaryrd(document):
620 "remove use_package stmaryrd"
621 # commands provided by stmaryrd.sty but LyX uses other packages:
622 # boxdot lightning, bigtriangledown, bigtriangleup
623 commands = ["shortleftarrow", "shortrightarrow", "shortuparrow", \
624 "shortdownarrow", "Yup", "Ydown", "Yleft", "Yright", \
625 "varcurlyvee", "varcurlywedge", "minuso", "baro", \
626 "sslash", "bbslash", "moo", "varotimes", "varoast", \
627 "varobar", "varodot", "varoslash", "varobslash", \
628 "varocircle", "varoplus", "varominus", "boxast", \
629 "boxbar", "boxslash", "boxbslash", "boxcircle", \
630 "boxbox", "boxempty", "merge", "vartimes", \
631 "fatsemi", "sswarrow", "ssearrow", "curlywedgeuparrow", \
632 "curlywedgedownarrow", "fatslash", "fatbslash", "lbag", \
633 "rbag", "varbigcirc", "leftrightarroweq", \
634 "curlyveedownarrow", "curlyveeuparrow", "nnwarrow", \
635 "nnearrow", "leftslice", "rightslice", "varolessthan", \
636 "varogreaterthan", "varovee", "varowedge", "talloblong", \
637 "interleave", "obar", "obslash", "olessthan", \
638 "ogreaterthan", "ovee", "owedge", "oblong", "inplus", \
639 "niplus", "nplus", "subsetplus", "supsetplus", \
640 "subsetpluseq", "supsetpluseq", "Lbag", "Rbag", \
641 "llbracket", "rrbracket", "llparenthesis", \
642 "rrparenthesis", "binampersand", "bindnasrepma", \
643 "trianglelefteqslant", "trianglerighteqslant", \
644 "ntrianglelefteqslant", "ntrianglerighteqslant", \
645 "llfloor", "rrfloor", "llceil", "rrceil", "arrownot", \
646 "Arrownot", "Mapstochar", "mapsfromchar", "Mapsfromchar", \
647 "leftrightarrowtriangle", "leftarrowtriangle", \
648 "rightarrowtriangle", \
649 "bigcurlyvee", "bigcurlywedge", "bigsqcap", "bigbox", \
650 "bigparallel", "biginterleave", "bignplus", \
651 "varcopyright", "longarrownot", "Longarrownot", \
652 "Mapsto", "mapsfrom", "Mapsfrom" "Longmapsto", \
653 "longmapsfrom", "Longmapsfrom"]
654 revert_use_package(document, "stmaryrd", commands, False)
658 def convert_use_stackrel(document):
659 "insert use_package stackrel"
660 convert_use_package(document, "stackrel")
663 def revert_use_stackrel(document):
664 "remove use_package stackrel"
665 commands = ["stackrel"]
666 revert_use_package(document, "stackrel", commands, False)
669 def convert_cite_engine_type(document):
670 "Determine the \\cite_engine_type from the citation engine."
671 i = find_token(document.header, "\\cite_engine", 0)
674 engine = get_value(document.header, "\\cite_engine", i)
676 engine, type = engine.split("_")
678 type = {"basic": "numerical", "jurabib": "authoryear"}[engine]
679 document.header[i] = "\\cite_engine " + engine
680 document.header.insert(i + 1, "\\cite_engine_type " + type)
683 def revert_cite_engine_type(document):
684 "Natbib had the type appended with an underscore."
685 engine_type = "numerical"
686 i = find_token(document.header, "\\cite_engine_type" , 0)
688 document.warning("No \\cite_engine_type line. Assuming numerical.")
690 engine_type = get_value(document.header, "\\cite_engine_type", i)
691 del document.header[i]
693 # We are looking for the natbib citation engine
694 i = find_token(document.header, "\\cite_engine natbib", 0)
697 document.header[i] = "\\cite_engine natbib_" + engine_type
700 def convert_cite_engine_type_default(document):
701 "Convert \\cite_engine_type to default for the basic citation engine."
702 i = find_token(document.header, "\\cite_engine basic", 0)
705 i = find_token(document.header, "\\cite_engine_type" , 0)
708 document.header[i] = "\\cite_engine_type default"
711 def revert_cite_engine_type_default(document):
712 """Revert \\cite_engine_type default.
714 Revert to numerical for the basic cite engine, otherwise to authoryear."""
715 engine_type = "authoryear"
716 i = find_token(document.header, "\\cite_engine_type default" , 0)
719 j = find_token(document.header, "\\cite_engine basic", 0)
721 engine_type = "numerical"
722 document.header[i] = "\\cite_engine_type " + engine_type
725 # this is the same, as revert_use_cancel() except for the default
726 def revert_cancel(document):
727 "add cancel to the preamble if necessary"
728 commands = ["cancelto", "cancel", "bcancel", "xcancel"]
729 revert_use_package(document, "cancel", commands, False)
732 def revert_verbatim(document):
733 " Revert verbatim einvironments completely to TeX-code. "
736 subst_end = ['\end_layout', '', '\\begin_layout Plain Layout',
738 '\\begin_layout Plain Layout', '', '',
741 '\\end_layout', '', '\\end_inset',
742 '', '', '\\end_layout']
743 subst_begin = ['\\begin_layout Standard', '\\noindent',
744 '\\begin_inset ERT', 'status open', '',
745 '\\begin_layout Plain Layout', '', '', '\\backslash',
747 '\\end_layout', '', '\\begin_layout Plain Layout', '']
750 i = find_token(document.body, "\\begin_layout Verbatim", i)
753 j = find_end_of_layout(document.body, i)
755 document.warning("Malformed LyX document: Can't find end of Verbatim layout")
758 # delete all line breaks insets (there are no other insets)
761 n = find_token(document.body, "\\begin_inset Newline newline", l, j)
763 n = find_token(document.body, "\\begin_inset Newline linebreak", l, j)
766 m = find_end_of_inset(document.body, n)
767 del(document.body[m:m+1])
768 document.body[n:n+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
770 # we deleted a line, so the end of the inset moved forward.
772 # consecutive verbatim environments need to be connected
773 k = find_token(document.body, "\\begin_layout Verbatim", j)
774 if k == j + 2 and consecutive == False:
776 document.body[j:j+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
777 document.body[i:i+1] = subst_begin
779 if k == j + 2 and consecutive == True:
780 document.body[j:j+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
781 del(document.body[i:i+1])
783 if k != j + 2 and consecutive == True:
784 document.body[j:j+1] = subst_end
785 # the next paragraph must not be indented
786 document.body[j+19:j+19] = ['\\noindent']
787 del(document.body[i:i+1])
791 document.body[j:j+1] = subst_end
792 # the next paragraph must not be indented
793 document.body[j+19:j+19] = ['\\noindent']
794 document.body[i:i+1] = subst_begin
797 def revert_tipa(document):
798 " Revert native TIPA insets to mathed or ERT. "
801 i = find_token(document.body, "\\begin_inset IPA", i)
804 j = find_end_of_inset(document.body, i)
806 document.warning("Malformed LyX document: Can't find end of IPA inset")
810 n = find_token(document.body, "\\begin_layout", i, j)
812 document.warning("Malformed LyX document: IPA inset has no embedded layout")
815 m = find_end_of_layout(document.body, n)
817 document.warning("Malformed LyX document: Can't find end of embedded layout")
820 content = document.body[n+1:m]
821 p = find_token(document.body, "\\begin_layout", m, j)
822 if p != -1 or len(content) > 1:
824 content = document.body[i+1:j]
826 # IPA insets with multiple pars need to be wrapped by \begin{IPA}...\end{IPA}
827 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}")
828 add_to_preamble(document, ["\\usepackage{tipa,tipx}"])
830 # single-par IPA insets can be reverted to mathed
831 document.body[i:j+1] = ["\\begin_inset Formula $\\text{\\textipa{" + content[0] + "}}$", "\\end_inset"]
835 def revert_cell_rotation(document):
836 "Revert cell rotations to TeX-code"
838 load_rotating = False
842 # first, let's find out if we need to do anything
843 i = find_token(document.body, '<cell ', i)
846 j = document.body[i].find('rotate="')
848 k = document.body[i].find('"', j + 8)
849 value = document.body[i][j + 8 : k]
851 rgx = re.compile(r' rotate="[^"]+?"')
852 # remove rotate option
853 document.body[i] = rgx.sub('', document.body[i])
855 rgx = re.compile(r' rotate="[^"]+?"')
856 document.body[i] = rgx.sub('rotate="true"', document.body[i])
858 rgx = re.compile(r' rotate="[^"]+?"')
860 # remove rotate option
861 document.body[i] = rgx.sub('', document.body[i])
863 document.body[i + 5 : i + 5] = \
864 put_cmd_in_ert("\\end{turn}")
865 document.body[i + 4 : i + 4] = \
866 put_cmd_in_ert("\\begin{turn}{" + value + "}")
872 add_to_preamble(document, ["\\@ifundefined{turnbox}{\usepackage{rotating}}{}"])
875 def convert_cell_rotation(document):
876 'Convert cell rotation statements from "true" to "90"'
880 # first, let's find out if we need to do anything
881 i = find_token(document.body, '<cell ', i)
884 j = document.body[i].find('rotate="true"')
886 rgx = re.compile(r'rotate="[^"]+?"')
887 # convert "true" to "90"
888 document.body[i] = rgx.sub('rotate="90"', document.body[i])
893 def revert_table_rotation(document):
894 "Revert table rotations to TeX-code"
896 load_rotating = False
900 # first, let's find out if we need to do anything
901 i = find_token(document.body, '<features ', i)
904 j = document.body[i].find('rotate="')
906 end_table = find_token(document.body, '</lyxtabular>', j)
907 k = document.body[i].find('"', j + 8)
908 value = document.body[i][j + 8 : k]
910 rgx = re.compile(r' rotate="[^"]+?"')
911 # remove rotate option
912 document.body[i] = rgx.sub('', document.body[i])
914 rgx = re.compile(r'rotate="[^"]+?"')
915 document.body[i] = rgx.sub('rotate="true"', document.body[i])
917 rgx = re.compile(r' rotate="[^"]+?"')
919 # remove rotate option
920 document.body[i] = rgx.sub('', document.body[i])
922 document.body[end_table + 3 : end_table + 3] = \
923 put_cmd_in_ert("\\end{turn}")
924 document.body[i - 2 : i - 2] = \
925 put_cmd_in_ert("\\begin{turn}{" + value + "}")
931 add_to_preamble(document, ["\\@ifundefined{turnbox}{\usepackage{rotating}}{}"])
934 def convert_table_rotation(document):
935 'Convert table rotation statements from "true" to "90"'
939 # first, let's find out if we need to do anything
940 i = find_token(document.body, '<features ', i)
943 j = document.body[i].find('rotate="true"')
945 rgx = re.compile(r'rotate="[^"]+?"')
946 # convert "true" to "90"
947 document.body[i] = rgx.sub('rotate="90"', document.body[i])
952 def convert_listoflistings(document):
953 'Convert ERT \lstlistoflistings to TOC lstlistoflistings inset'
954 # We can support roundtrip because the command is so simple
957 i = find_token(document.body, "\\begin_inset ERT", i)
960 j = find_end_of_inset(document.body, i)
962 document.warning("Malformed LyX document: Can't find end of ERT inset")
965 ert = get_ert(document.body, i)
966 if ert == "\\lstlistoflistings{}":
967 document.body[i:j] = ["\\begin_inset CommandInset toc", "LatexCommand lstlistoflistings", ""]
973 def revert_listoflistings(document):
974 'Convert TOC lstlistoflistings inset to ERT lstlistoflistings'
977 i = find_token(document.body, "\\begin_inset CommandInset toc", i)
980 if document.body[i+1] == "LatexCommand lstlistoflistings":
981 j = find_end_of_inset(document.body, i)
983 document.warning("Malformed LyX document: Can't find end of TOC inset")
986 subst = put_cmd_in_ert("\\lstlistoflistings{}")
987 document.body[i:j+1] = subst
988 add_to_preamble(document, ["\\usepackage{listings}"])
992 def convert_use_amssymb(document):
993 "insert use_package amssymb"
994 regexp = re.compile(r'(\\use_package\s+amsmath)')
995 i = find_re(document.header, regexp, 0)
997 document.warning("Malformed LyX document: Can't find \\use_package amsmath.")
999 value = get_value(document.header, "\\use_package" , i).split()[1]
1002 useamsmath = int(value)
1004 document.warning("Invalid \\use_package amsmath: " + value + ". Assuming auto.")
1006 j = find_token(document.preamble, "\\usepackage{amssymb}", 0)
1008 document.header.insert(i + 1, "\\use_package amssymb %d" % useamsmath)
1010 document.header.insert(i + 1, "\\use_package amssymb 2")
1011 del document.preamble[j]
1014 def revert_use_amssymb(document):
1015 "remove use_package amssymb"
1016 regexp1 = re.compile(r'(\\use_package\s+amsmath)')
1017 regexp2 = re.compile(r'(\\use_package\s+amssymb)')
1018 i = find_re(document.header, regexp1, 0)
1019 j = find_re(document.header, regexp2, 0)
1020 value1 = "1" # default is auto
1021 value2 = "1" # default is auto
1023 value1 = get_value(document.header, "\\use_package" , i).split()[1]
1025 value2 = get_value(document.header, "\\use_package" , j).split()[1]
1026 del document.header[j]
1027 if value1 != value2 and value2 == "2": # on
1028 add_to_preamble(document, ["\\usepackage{amssymb}"])
1031 def convert_use_cancel(document):
1032 "insert use_package cancel"
1033 convert_use_package(document, "cancel")
1036 def revert_use_cancel(document):
1037 "remove use_package cancel"
1038 commands = ["cancel", "bcancel", "xcancel", "cancelto"]
1039 revert_use_package(document, "cancel", commands, True)
1042 def revert_ancientgreek(document):
1043 "Set the document language for ancientgreek to greek"
1045 if document.language == "ancientgreek":
1046 document.language = "greek"
1047 i = find_token(document.header, "\\language", 0)
1049 document.header[i] = "\\language greek"
1052 j = find_token(document.body, "\\lang ancientgreek", j)
1056 document.body[j] = document.body[j].replace("\\lang ancientgreek", "\\lang greek")
1060 def revert_languages(document):
1061 "Set the document language for new supported languages to English"
1064 "coptic", "divehi", "hindi", "kurmanji", "lao", "marathi", "occitan", "sanskrit",
1065 "syriac", "tamil", "telugu", "urdu"
1067 for n in range(len(languages)):
1068 if document.language == languages[n]:
1069 document.language = "english"
1070 i = find_token(document.header, "\\language", 0)
1072 document.header[i] = "\\language english"
1074 while j < len(document.body):
1075 j = find_token(document.body, "\\lang " + languages[n], j)
1077 document.body[j] = document.body[j].replace("\\lang " + languages[n], "\\lang english")
1080 j = len(document.body)
1083 def convert_armenian(document):
1084 "Use polyglossia and thus non-TeX fonts for Armenian"
1086 if document.language == "armenian":
1087 i = find_token(document.header, "\\use_non_tex_fonts", 0)
1089 document.header[i] = "\\use_non_tex_fonts true"
1092 def revert_armenian(document):
1093 "Use ArmTeX and thus 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 false"
1101 def revert_libertine(document):
1102 " Revert native libertine font definition to LaTeX "
1104 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1105 i = find_token(document.header, "\\font_roman libertine", 0)
1108 j = find_token(document.header, "\\font_osf true", 0)
1111 preamble = "\\usepackage"
1113 document.header[j] = "\\font_osf false"
1116 preamble += "[lining]"
1117 preamble += "{libertine-type1}"
1118 add_to_preamble(document, [preamble])
1119 document.header[i] = "\\font_roman default"
1122 def revert_txtt(document):
1123 " Revert native txtt font definition to LaTeX "
1125 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1126 i = find_token(document.header, "\\font_typewriter txtt", 0)
1128 preamble = "\\renewcommand{\\ttdefault}{txtt}"
1129 add_to_preamble(document, [preamble])
1130 document.header[i] = "\\font_typewriter default"
1133 def revert_mathdesign(document):
1134 " Revert native mathdesign font definition to LaTeX "
1136 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1142 i = find_token(document.header, "\\font_roman", 0)
1145 val = get_value(document.header, "\\font_roman", i)
1146 if val in mathdesign_dict.keys():
1147 preamble = "\\usepackage[%s" % mathdesign_dict[val]
1149 j = find_token(document.header, "\\font_osf true", 0)
1152 document.header[j] = "\\font_osf false"
1153 l = find_token(document.header, "\\font_sc true", 0)
1156 document.header[l] = "\\font_sc false"
1158 preamble += ",expert"
1159 preamble += "]{mathdesign}"
1160 add_to_preamble(document, [preamble])
1161 document.header[i] = "\\font_roman default"
1164 def revert_texgyre(document):
1165 " Revert native TeXGyre font definition to LaTeX "
1167 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1168 texgyre_fonts = ["tgadventor", "tgbonum", "tgchorus", "tgcursor", \
1169 "tgheros", "tgpagella", "tgschola", "tgtermes"]
1170 i = find_token(document.header, "\\font_roman", 0)
1172 val = get_value(document.header, "\\font_roman", i)
1173 if val in texgyre_fonts:
1174 preamble = "\\usepackage{%s}" % val
1175 add_to_preamble(document, [preamble])
1176 document.header[i] = "\\font_roman default"
1177 i = find_token(document.header, "\\font_sans", 0)
1179 val = get_value(document.header, "\\font_sans", i)
1180 if val in texgyre_fonts:
1181 preamble = "\\usepackage{%s}" % val
1182 add_to_preamble(document, [preamble])
1183 document.header[i] = "\\font_sans default"
1184 i = find_token(document.header, "\\font_typewriter", 0)
1186 val = get_value(document.header, "\\font_typewriter", i)
1187 if val in texgyre_fonts:
1188 preamble = "\\usepackage{%s}" % val
1189 add_to_preamble(document, [preamble])
1190 document.header[i] = "\\font_typewriter default"
1193 def revert_ipadeco(document):
1194 " Revert IPA decorations to ERT "
1197 i = find_token(document.body, "\\begin_inset IPADeco", i)
1200 end = find_end_of_inset(document.body, i)
1202 document.warning("Can't find end of inset at line " + str(i))
1205 line = document.body[i]
1206 rx = re.compile(r'\\begin_inset IPADeco (.*)$')
1208 decotype = m.group(1)
1209 if decotype != "toptiebar" and decotype != "bottomtiebar":
1210 document.warning("Invalid IPADeco type: " + decotype)
1213 blay = find_token(document.body, "\\begin_layout Plain Layout", i, end)
1215 document.warning("Can't find layout for inset at line " + str(i))
1218 bend = find_end_of_layout(document.body, blay)
1220 document.warning("Malformed LyX document: Could not find end of IPADeco inset's layout.")
1223 substi = ["\\begin_inset ERT", "status collapsed", "",
1224 "\\begin_layout Plain Layout", "", "", "\\backslash",
1225 decotype + "{", "\\end_layout", "", "\\end_inset"]
1226 substj = ["\\size default", "", "\\begin_inset ERT", "status collapsed", "",
1227 "\\begin_layout Plain Layout", "", "}", "\\end_layout", "", "\\end_inset"]
1228 # do the later one first so as not to mess up the numbering
1229 document.body[bend:end + 1] = substj
1230 document.body[i:blay + 1] = substi
1231 i = end + len(substi) + len(substj) - (end - bend) - (blay - i) - 2
1232 add_to_preamble(document, "\\usepackage{tipa}")
1235 def revert_ipachar(document):
1236 ' Revert \\IPAChar to ERT '
1239 while i < len(document.body):
1240 m = re.match(r'(.*)\\IPAChar \\(\w+\{\w+\})(.*)', document.body[i])
1244 ipachar = m.group(2)
1247 '\\begin_inset ERT',
1248 'status collapsed', '',
1249 '\\begin_layout Standard',
1250 '', '', '\\backslash',
1255 document.body[i: i+1] = subst
1260 add_to_preamble(document, "\\usepackage{tone}")
1263 def revert_minionpro(document):
1264 " Revert native MinionPro font definition to LaTeX "
1266 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1267 i = find_token(document.header, "\\font_roman minionpro", 0)
1270 j = find_token(document.header, "\\font_osf true", 0)
1273 preamble = "\\usepackage"
1275 document.header[j] = "\\font_osf false"
1278 preamble += "{MinionPro}"
1279 add_to_preamble(document, [preamble])
1280 document.header[i] = "\\font_roman default"
1283 def revert_mathfonts(document):
1284 " Revert native math font definitions to LaTeX "
1286 i = find_token(document.header, "\\font_math", 0)
1289 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1290 val = get_value(document.header, "\\font_math", i)
1291 if val == "eulervm":
1292 add_to_preamble(document, "\\usepackage{eulervm}")
1293 elif val == "default":
1295 "lmodern": "\\renewcommand{\\rmdefault}{lmr}",
1296 "minionpro": "\\usepackage[onlytext,lf]{MinionPro}",
1297 "minionpro-osf": "\\usepackage[onlytext]{MinionPro}",
1298 "palatino": "\\renewcommand{\\rmdefault}{ppl}",
1299 "palatino-osf": "\\renewcommand{\\rmdefault}{pplj}",
1300 "times": "\\renewcommand{\\rmdefault}{ptm}",
1301 "utopia": "\\renewcommand{\\rmdefault}{futs}",
1302 "utopia-osf": "\\renewcommand{\\rmdefault}{futj}",
1304 j = find_token(document.header, "\\font_roman", 0)
1306 rm = get_value(document.header, "\\font_roman", j)
1307 k = find_token(document.header, "\\font_osf true", 0)
1310 if rm in mathfont_dict.keys():
1311 add_to_preamble(document, mathfont_dict[rm])
1312 document.header[j] = "\\font_roman default"
1314 document.header[k] = "\\font_osf false"
1315 del document.header[i]
1318 def revert_mdnomath(document):
1319 " Revert mathdesign and fourier without math "
1321 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1323 "md-charter": "mdbch",
1324 "md-utopia": "mdput",
1325 "md-garamond": "mdugm"
1327 i = find_token(document.header, "\\font_roman", 0)
1330 val = get_value(document.header, "\\font_roman", i)
1331 if val in mathdesign_dict.keys():
1332 j = find_token(document.header, "\\font_math", 0)
1334 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1335 mval = get_value(document.header, "\\font_math", j)
1336 if mval == "default":
1337 document.header[i] = "\\font_roman default"
1338 add_to_preamble(document, "\\renewcommand{\\rmdefault}{%s}" % mathdesign_dict[val])
1340 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1343 def convert_mdnomath(document):
1344 " Change mathdesign font name "
1346 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1348 "mdbch": "md-charter",
1349 "mdput": "md-utopia",
1350 "mdugm": "md-garamond"
1352 i = find_token(document.header, "\\font_roman", 0)
1355 val = get_value(document.header, "\\font_roman", i)
1356 if val in mathdesign_dict.keys():
1357 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1360 def revert_newtxmath(document):
1361 " Revert native newtxmath definitions to LaTeX "
1363 i = find_token(document.header, "\\font_math", 0)
1366 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1367 val = get_value(document.header, "\\font_math", i)
1369 "libertine-ntxm": "\\usepackage[libertine]{newtxmath}",
1370 "minion-ntxm": "\\usepackage[minion]{newtxmath}",
1371 "newtxmath": "\\usepackage{newtxmath}",
1373 if val in mathfont_dict.keys():
1374 add_to_preamble(document, mathfont_dict[val])
1375 document.header[i] = "\\font_math auto"
1378 def revert_biolinum(document):
1379 " Revert native biolinum font definition to LaTeX "
1381 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1382 i = find_token(document.header, "\\font_sans biolinum", 0)
1385 j = find_token(document.header, "\\font_osf true", 0)
1388 preamble = "\\usepackage"
1391 preamble += "{biolinum-type1}"
1392 add_to_preamble(document, [preamble])
1393 document.header[i] = "\\font_sans default"
1396 def revert_uop(document):
1397 " Revert native URW Classico (Optima) font definition to LaTeX "
1399 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1400 i = find_token(document.header, "\\font_sans uop", 0)
1402 preamble = "\\renewcommand{\\sfdefault}{uop}"
1403 add_to_preamble(document, [preamble])
1404 document.header[i] = "\\font_sans default"
1407 def convert_latexargs(document):
1408 " Convert InsetArgument to new syntax "
1410 if find_token(document.body, "\\begin_inset Argument", 0) == -1:
1414 # A list of layouts (document classes) with only optional or no arguments.
1415 # These can be safely converted to the new syntax
1416 # (I took the liberty to add some of my personal layouts/modules here; JSP)
1417 safe_layouts = ["aa", "aapaper", "aastex", "achemso", "acmsiggraph", "AEA",
1418 "agu-dtd", "agums", "agutex", "amsart", "amsbook", "apa",
1419 "arab-article", "armenian-article", "article-beamer", "article",
1420 "beamer", "book", "broadway", "chess", "cl2emult", "ctex-article",
1421 "ctex-book", "ctex-report", "dinbrief", "docbook-book", "docbook-chapter",
1422 "docbook", "docbook-section", "doublecol-new", "dtk", "ectaart", "egs",
1423 "elsarticle", "elsart", "entcs", "europecv", "extarticle", "extbook",
1424 "extletter", "extreport", "foils", "frletter", "g-brief2", "g-brief",
1425 "heb-article", "heb-letter", "hollywood", "IEEEtran", "ijmpc", "ijmpd",
1426 "iopart", "isprs", "jarticle", "jasatex", "jbook", "jgrga", "jreport",
1427 "jsarticle", "jsbeamer", "jsbook", "jss", "kluwer", "latex8", "letter", "lettre",
1428 "literate-article", "literate-book", "literate-report", "llncs", "ltugboat",
1429 "memoir", "moderncv", "mwart", "mwbk", "mwrep", "paper", "powerdot",
1430 "recipebook", "report", "revtex4", "revtex", "scrartcl", "scrarticle-beamer",
1431 "scrbook", "scrlettr", "scrlttr2", "scrreprt", "seminar", "siamltex",
1432 "sigplanconf", "simplecv", "singlecol", "singlecol-new", "slides", "spie",
1433 "svglobal3", "svglobal", "svjog", "svmono", "svmult", "svprobth", "tarticle",
1434 "tbook", "treport", "tufte-book", "tufte-handout"]
1435 # A list of "safe" modules, same as above
1436 safe_modules = ["biblatex", "beameraddons", "beamersession", "braille", "customHeadersFooters",
1437 "endnotes", "enumitem", "eqs-within-sections", "figs-within-sections", "fix-cm",
1438 "fixltx2e", "foottoend", "hanging", "jscharstyles", "knitr", "lilypond",
1439 "linguistics", "linguisticx", "logicalmkup", "minimalistic", "nomindex", "noweb",
1440 "pdfcomment", "sweave", "tabs-within-sections", "theorems-ams-bytype",
1441 "theorems-ams-extended-bytype", "theorems-ams-extended", "theorems-ams", "theorems-bytype",
1442 "theorems-chap-bytype", "theorems-chap", "theorems-named", "theorems-sec-bytype",
1443 "theorems-sec", "theorems-starred", "theorems-std", "todonotes"]
1444 # Modules we need to take care of
1445 caveat_modules = ["initials"]
1446 # information about the relevant styles in caveat_modules (number of opt and req args)
1447 # use this if we get more caveat_modules. For now, use hard coding (see below).
1448 # initials = [{'Layout' : 'Initial', 'opt' : 1, 'req' : 1}]
1450 # Is this a known safe layout?
1451 safe_layout = document.textclass in safe_layouts
1453 document.warning("Lyx2lyx knows nothing about textclass '%s'. "
1454 "Please check if short title insets have been converted correctly."
1455 % document.textclass)
1456 # Do we use unsafe or unknown modules
1457 mods = document.get_module_list()
1458 unknown_modules = False
1459 used_caveat_modules = list()
1461 if mod in safe_modules:
1463 if mod in caveat_modules:
1464 used_caveat_modules.append(mod)
1466 unknown_modules = True
1467 document.warning("Lyx2lyx knows nothing about module '%s'. "
1468 "Please check if short title insets have been converted correctly."
1473 i = find_token(document.body, "\\begin_inset Argument", i)
1477 if not safe_layout or unknown_modules:
1478 # We cannot do more here since we have no access to this layout.
1479 # InsetArgument itself will do the real work
1480 # (see InsetArgument::updateBuffer())
1481 document.body[i] = "\\begin_inset Argument 999"
1485 # Find containing paragraph layout
1486 parent = get_containing_layout(document.body, i)
1488 document.warning("Malformed LyX document: Can't find parent paragraph layout")
1495 if len(used_caveat_modules) > 0:
1496 # We know for now that this must be the initials module with the Initial layout
1497 # If we get more such modules, we need some automating.
1498 if parent[0] == "Initial":
1499 # Layout has 1 opt and 1 req arg.
1500 # Count the actual arguments
1502 for p in range(parbeg, parend):
1503 if document.body[p] == "\\begin_inset Argument":
1508 # Collect all arguments in this paragraph
1510 for p in range(parbeg, parend):
1511 if document.body[p] == "\\begin_inset Argument":
1513 if allowed_opts != -1:
1514 # We have less arguments than opt + required.
1515 # required must take precedence.
1516 if argnr > allowed_opts and argnr < first_req:
1518 document.body[p] = "\\begin_inset Argument %d" % argnr
1522 def revert_latexargs(document):
1523 " Revert InsetArgument to old syntax "
1526 rx = re.compile(r'^\\begin_inset Argument (\d+)$')
1529 # Search for Argument insets
1530 i = find_token(document.body, "\\begin_inset Argument", i)
1533 m = rx.match(document.body[i])
1535 # No ID: inset already reverted
1538 # Find containing paragraph layout
1539 parent = get_containing_layout(document.body, i)
1541 document.warning("Malformed LyX document: Can't find parent paragraph layout")
1546 realparbeg = parent[3]
1547 # Collect all arguments in this paragraph
1549 for p in range(parbeg, parend):
1550 m = rx.match(document.body[p])
1552 val = int(m.group(1))
1553 j = find_end_of_inset(document.body, p)
1554 # Revert to old syntax
1555 document.body[p] = "\\begin_inset Argument"
1557 document.warning("Malformed LyX document: Can't find end of Argument inset")
1560 args[val] = document.body[p : j + 1]
1562 realparend = realparend - len(document.body[p : j + 1])
1563 # Remove arg inset at this position
1564 del document.body[p : j + 1]
1567 # Now sort the arg insets
1569 for f in sorted(args):
1572 # Insert the sorted arg insets at paragraph begin
1573 document.body[realparbeg : realparbeg] = subst
1575 i = realparbeg + 1 + len(subst)
1578 def revert_IEEEtran(document):
1580 Reverts InsetArgument of
1583 Biography without photo
1586 if document.textclass == "IEEEtran":
1593 i = find_token(document.body, "\\begin_layout Page headings", i)
1595 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1598 i2 = find_token(document.body, "\\begin_inset Flex Paragraph Start", i2)
1600 revert_Argument_to_TeX_brace(document, i2, 0, 1, 1, False, False)
1603 j = find_token(document.body, "\\begin_layout Biography without photo", j)
1605 revert_Argument_to_TeX_brace(document, j, 0, 1, 1, True, False)
1608 k = find_token(document.body, "\\begin_layout Biography", k)
1609 kA = find_token(document.body, "\\begin_layout Biography without photo", k)
1610 if k == kA and k != -1:
1614 # start with the second argument, therefore 2
1615 revert_Argument_to_TeX_brace(document, k, 0, 2, 2, True, False)
1617 if i == -1 and i2 == -1 and j == -1 and k == -1:
1621 def revert_IEEEtran_2(document):
1623 Reverts Flex Paragraph Start to TeX-code
1625 if document.textclass == "IEEEtran":
1628 begin = find_token(document.body, "\\begin_inset Flex Paragraph Start", begin)
1631 end1 = find_end_of_inset(document.body, begin)
1632 document.body[end1 - 2 : end1 + 1] = put_cmd_in_ert("}")
1633 document.body[begin : begin + 4] = put_cmd_in_ert("\\IEEEPARstart{")
1637 def convert_IEEEtran(document):
1642 Biography without photo
1645 if document.textclass == "IEEEtran":
1651 i = find_token(document.body, "\\begin_layout Page headings", i)
1653 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
1656 j = find_token(document.body, "\\begin_layout Biography without photo", j)
1658 convert_TeX_brace_to_Argument(document, j, 1, 1, False, True, False)
1661 # assure that we don't handle Biography Biography without photo
1662 k = find_token(document.body, "\\begin_layout Biography", k)
1663 kA = find_token(document.body, "\\begin_layout Biography without photo", k - 1)
1664 if k == kA and k != -1:
1668 # the argument we want to convert is the second one
1669 convert_TeX_brace_to_Argument(document, k, 2, 2, False, True, False)
1671 if i == -1 and j == -1 and k == -1:
1675 def revert_AASTeX(document):
1676 " Reverts InsetArgument of Altaffilation to TeX-code "
1677 if document.textclass == "aastex":
1680 i = find_token(document.body, "\\begin_layout Altaffilation", i)
1683 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1687 def convert_AASTeX(document):
1688 " Converts ERT of Altaffilation to InsetArgument "
1689 if document.textclass == "aastex":
1692 i = find_token(document.body, "\\begin_layout Altaffilation", i)
1695 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
1699 def revert_AGUTeX(document):
1700 " Reverts InsetArgument of Author affiliation to TeX-code "
1701 if document.textclass == "agutex":
1704 i = find_token(document.body, "\\begin_layout Author affiliation", i)
1707 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1711 def convert_AGUTeX(document):
1712 " Converts ERT of Author affiliation to InsetArgument "
1713 if document.textclass == "agutex":
1716 i = find_token(document.body, "\\begin_layout Author affiliation", i)
1719 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
1723 def revert_IJMP(document):
1724 " Reverts InsetArgument of MarkBoth to TeX-code "
1725 if document.textclass == "ijmpc" or document.textclass == "ijmpd":
1728 i = find_token(document.body, "\\begin_layout MarkBoth", i)
1731 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1735 def convert_IJMP(document):
1736 " Converts ERT of MarkBoth to InsetArgument "
1737 if document.textclass == "ijmpc" or document.textclass == "ijmpd":
1740 i = find_token(document.body, "\\begin_layout MarkBoth", i)
1743 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
1747 def revert_SIGPLAN(document):
1748 " Reverts InsetArguments of SIGPLAN to TeX-code "
1749 if document.textclass == "sigplanconf":
1754 i = find_token(document.body, "\\begin_layout Conference", i)
1756 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1759 j = find_token(document.body, "\\begin_layout Author", j)
1761 revert_Argument_to_TeX_brace(document, j, 0, 1, 2, False, False)
1763 if i == -1 and j == -1:
1767 def convert_SIGPLAN(document):
1768 " Converts ERT of SIGPLAN to InsetArgument "
1769 if document.textclass == "sigplanconf":
1774 i = find_token(document.body, "\\begin_layout Conference", i)
1776 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
1779 j = find_token(document.body, "\\begin_layout Author", j)
1781 convert_TeX_brace_to_Argument(document, j, 1, 2, False, False, False)
1783 if i == -1 and j == -1:
1787 def revert_SIGGRAPH(document):
1788 " Reverts InsetArgument of Flex CRcat to TeX-code "
1789 if document.textclass == "acmsiggraph":
1792 i = find_token(document.body, "\\begin_inset Flex CRcat", i)
1795 revert_Argument_to_TeX_brace(document, i, 0, 1, 3, False, False)
1799 def convert_SIGGRAPH(document):
1800 " Converts ERT of Flex CRcat to InsetArgument "
1801 if document.textclass == "acmsiggraph":
1804 i = find_token(document.body, "\\begin_inset Flex CRcat", i)
1807 convert_TeX_brace_to_Argument(document, i, 1, 3, True, False, False)
1811 def revert_EuropeCV(document):
1812 " Reverts InsetArguments of europeCV to TeX-code "
1813 if document.textclass == "europecv":
1820 i = find_token(document.body, "\\begin_layout Item", i)
1822 revert_Argument_to_TeX_brace(document, i, 0, 2, 2, False, False)
1825 j = find_token(document.body, "\\begin_layout BulletedItem", j)
1827 revert_Argument_to_TeX_brace(document, j, 0, 2, 2, False, False)
1830 k = find_token(document.body, "\\begin_layout Language", k)
1832 revert_Argument_to_TeX_brace(document, k, 0, 2, 6, False, False)
1835 m = find_token(document.body, "\\begin_layout LastLanguage", m)
1837 revert_Argument_to_TeX_brace(document, m, 0, 2, 6, False, False)
1839 if i == -1 and j == -1 and k == -1 and m == -1:
1843 def convert_EuropeCV(document):
1844 " Converts ERT of europeCV to InsetArgument "
1845 if document.textclass == "europecv":
1852 i = find_token(document.body, "\\begin_layout Item", i)
1854 convert_TeX_brace_to_Argument(document, i, 2, 2, False, False, False)
1857 j = find_token(document.body, "\\begin_layout BulletedItem", j)
1859 convert_TeX_brace_to_Argument(document, j, 2, 2, False, False, False)
1862 k = find_token(document.body, "\\begin_layout Language", k)
1864 convert_TeX_brace_to_Argument(document, k, 2, 6, False, False, False)
1867 m = find_token(document.body, "\\begin_layout LastLanguage", m)
1869 convert_TeX_brace_to_Argument(document, m, 2, 6, False, False, False)
1871 if i == -1 and j == -1 and k == -1 and m == -1:
1875 def revert_ModernCV(document):
1876 " Reverts InsetArguments of modernCV to TeX-code "
1877 if document.textclass == "moderncv":
1885 j = find_token(document.body, "\\begin_layout Entry", j)
1887 revert_Argument_to_TeX_brace(document, j, 0, 1, 5, False, False)
1890 k = find_token(document.body, "\\begin_layout Item", k)
1892 revert_Argument_to_TeX_brace(document, k, 0, 1, 1, False, False)
1895 m = find_token(document.body, "\\begin_layout ItemWithComment", m)
1897 revert_Argument_to_TeX_brace(document, m, 0, 1, 2, False, False)
1898 document.body[m] = document.body[m].replace("\\begin_layout ItemWithComment", "\\begin_layout Language")
1901 o = find_token(document.body, "\\begin_layout DoubleItem", o)
1903 revert_Argument_to_TeX_brace(document, o, 0, 1, 3, False, False)
1904 document.body[o] = document.body[o].replace("\\begin_layout DoubleItem", "\\begin_layout Computer")
1907 p = find_token(document.body, "\\begin_layout Social", p)
1909 revert_Argument_to_TeX_brace(document, p, 0, 1, 1, False, True)
1911 if j == -1 and k == -1 and m == -1 and o == -1 and p == -1:
1915 def revert_ModernCV_2(document):
1916 " Reverts the Flex:Column inset of modernCV to TeX-code "
1917 if document.textclass == "moderncv":
1921 flex = find_token(document.body, "\\begin_inset Flex Column", flex)
1924 flexEnd = find_end_of_inset(document.body, flex)
1925 wasOpt = revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, False, True)
1926 revert_Argument_to_TeX_brace(document, flex, 0, 2, 2, False, False)
1927 flexEnd = find_end_of_inset(document.body, flex)
1929 document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\cvcolumn")
1931 document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\cvcolumn{")
1932 document.body[flexEnd + 4 : flexEnd + 7] = put_cmd_in_ert("}")
1936 def revert_ModernCV_3(document):
1937 " Reverts the Column style of modernCV to TeX-code "
1938 if document.textclass == "moderncv":
1939 # revert the layouts
1940 revert_ModernCV(document)
1942 # get the position of the end of the last column inset
1943 LastFlexEnd = revert_ModernCV_2(document)
1945 p = find_token(document.body, "\\begin_layout Columns", p)
1948 pEnd = find_end_of_layout(document.body, p)
1949 document.body[p] = document.body[p].replace("\\begin_layout Columns", "\\begin_layout Standard")
1950 if LastFlexEnd != -1:
1951 document.body[p + 1 : p + 1] = put_cmd_in_ert("\\begin{cvcolumns}")
1952 document.body[LastFlexEnd + 24 : LastFlexEnd + 24] = put_cmd_in_ert("\\end{cvcolumns}")
1956 def revert_ModernCV_4(document):
1957 " Reverts the style Social to TeX-code "
1958 if document.textclass == "moderncv":
1959 # revert the layouts
1960 revert_ModernCV(document)
1963 p = find_token(document.body, "\\begin_layout Social", p)
1966 pEnd = find_end_of_layout(document.body, p)
1967 document.body[p] = document.body[p].replace("\\begin_layout Social", "\\begin_layout Standard")
1968 document.body[p + 1 : p + 1] = put_cmd_in_ert("\\social")
1969 hasOpt = find_token(document.body, "[", p + 9)
1971 document.body[p + 30 : p + 30] = put_cmd_in_ert("{")
1972 document.body[p + 41 : p + 41] = put_cmd_in_ert("}")
1974 document.body[p + 11 : p + 11] = put_cmd_in_ert("{")
1975 document.body[p + 21 : p + 21] = put_cmd_in_ert("}")
1979 def convert_ModernCV(document):
1980 " Converts ERT of modernCV to InsetArgument "
1981 if document.textclass == "moderncv":
1989 i = find_token(document.body, "\\begin_layout DoubleItem", i)
1991 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
1992 document.body[o] = document.body[o].replace("\\begin_layout DoubleItem", "\\begin_layout DoubleListItem")
1995 j = find_token(document.body, "\\begin_layout Entry", j)
1997 convert_TeX_brace_to_Argument(document, j, 1, 5, False, False, False)
2000 k = find_token(document.body, "\\begin_layout Item", k)
2002 convert_TeX_brace_to_Argument(document, k, 1, 1, False, False, False)
2005 m = find_token(document.body, "\\begin_layout Language", m)
2007 convert_TeX_brace_to_Argument(document, m, 1, 2, False, False, False)
2009 if i == -1 and j == -1 and k == -1 and m == -1:
2013 def revert_Initials(document):
2014 " Reverts InsetArgument of Initial to TeX-code "
2017 i = find_token(document.body, "\\begin_layout Initial", i)
2020 # first arg (optional) and second arg (first mandatory) are supported in LyX 2.0.x
2021 revert_Argument_to_TeX_brace(document, i, 0, 3, 3, False, False)
2025 def convert_Initials(document):
2026 " Converts ERT of Initial to InsetArgument "
2029 i = find_token(document.body, "\\begin_layout Initial", i)
2032 convert_TeX_brace_to_Argument(document, i, 3, 3, False, False, False)
2036 def revert_literate(document):
2037 " Revert Literate document to old format "
2038 if del_token(document.header, "noweb", 0):
2039 document.textclass = "literate-" + document.textclass
2042 i = find_token(document.body, "\\begin_layout Chunk", i)
2045 document.body[i] = "\\begin_layout Scrap"
2049 def convert_literate(document):
2050 " Convert Literate document to new format"
2051 i = find_token(document.header, "\\textclass", 0)
2052 if (i != -1) and "literate-" in document.header[i]:
2053 document.textclass = document.header[i].replace("\\textclass literate-", "")
2054 j = find_token(document.header, "\\begin_modules", 0)
2056 document.header.insert(j + 1, "noweb")
2058 document.header.insert(i + 1, "\\end_modules")
2059 document.header.insert(i + 1, "noweb")
2060 document.header.insert(i + 1, "\\begin_modules")
2063 i = find_token(document.body, "\\begin_layout Scrap", i)
2066 document.body[i] = "\\begin_layout Chunk"
2070 def revert_itemargs(document):
2071 " Reverts \\item arguments to TeX-code "
2074 i = find_token(document.body, "\\begin_inset Argument item:", i)
2077 j = find_end_of_inset(document.body, i)
2078 # Find containing paragraph layout
2079 parent = get_containing_layout(document.body, i)
2081 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2085 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2086 endPlain = find_end_of_layout(document.body, beginPlain)
2087 content = document.body[beginPlain + 1 : endPlain]
2088 del document.body[i:j+1]
2089 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2090 document.body[parbeg : parbeg] = subst
2094 def revert_garamondx_newtxmath(document):
2095 " Revert native garamond newtxmath definition to LaTeX "
2097 i = find_token(document.header, "\\font_math", 0)
2100 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
2101 val = get_value(document.header, "\\font_math", i)
2102 if val == "garamondx-ntxm":
2103 add_to_preamble(document, "\\usepackage[garamondx]{newtxmath}")
2104 document.header[i] = "\\font_math auto"
2107 def revert_garamondx(document):
2108 " Revert native garamond font definition to LaTeX "
2110 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
2111 i = find_token(document.header, "\\font_roman garamondx", 0)
2114 j = find_token(document.header, "\\font_osf true", 0)
2117 preamble = "\\usepackage"
2119 preamble += "[osfI]"
2120 preamble += "{garamondx}"
2121 add_to_preamble(document, [preamble])
2122 document.header[i] = "\\font_roman default"
2125 def convert_beamerargs(document):
2126 " Converts beamer arguments to new layout "
2128 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2129 if document.textclass not in beamer_classes:
2132 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
2133 list_layouts = ["Itemize", "Enumerate", "Description"]
2134 rx = re.compile(r'^\\begin_inset Argument (\d+)$')
2138 i = find_token(document.body, "\\begin_inset Argument", i)
2141 # Find containing paragraph layout
2142 parent = get_containing_layout(document.body, i)
2144 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2149 layoutname = parent[0]
2150 for p in range(parbeg, parend):
2151 if layoutname in shifted_layouts:
2152 m = rx.match(document.body[p])
2154 argnr = int(m.group(1))
2156 document.body[p] = "\\begin_inset Argument %d" % argnr
2157 if layoutname == "AgainFrame":
2158 m = rx.match(document.body[p])
2160 document.body[p] = "\\begin_inset Argument 3"
2161 if document.body[p + 4] == "\\begin_inset ERT":
2162 if document.body[p + 9].startswith("<"):
2163 # This is an overlay specification
2165 document.body[p + 9] = document.body[p + 9][1:]
2166 if document.body[p + 9].endswith(">"):
2168 document.body[p + 9] = document.body[p + 9][:-1]
2170 document.body[p] = "\\begin_inset Argument 2"
2171 if layoutname in list_layouts:
2172 m = rx.match(document.body[p])
2174 if m.group(1) == "1":
2175 if document.body[p + 4] == "\\begin_inset ERT":
2176 if document.body[p + 9].startswith("<"):
2177 # This is an overlay specification
2179 document.body[p + 9] = document.body[p + 9][1:]
2180 if document.body[p + 9].endswith(">"):
2182 document.body[p + 9] = document.body[p + 9][:-1]
2183 elif document.body[p + 4].startswith("<"):
2184 # This is an overlay specification (without ERT)
2186 document.body[p + 4] = document.body[p + 4][1:]
2187 if document.body[p + 4].endswith(">"):
2189 document.body[p + 4] = document.body[p + 4][:-1]
2190 elif layoutname != "Itemize":
2192 document.body[p] = "\\begin_inset Argument 2"
2197 # Helper function for the frame conversion routines
2199 # FIXME: This method currently requires the arguments to be either
2200 # * In one (whole) ERT each: <ERT>[<arg1>]</ERT><ERT><arg2></ERT><ERT>[arg3]</ERT>
2201 # * Altogether in one whole ERT: <ERT>[<arg1>]<arg2>[arg3]</ERT>
2202 # If individual arguments mix ERT and non-ERT or are splitted
2203 # over several ERTs, the parsing fails.
2204 def convert_beamerframeargs(document, i, parbeg):
2207 if document.body[parbeg] != "\\begin_inset ERT":
2209 ertend = find_end_of_inset(document.body, parbeg)
2211 document.warning("Malformed LyX document: missing ERT \\end_inset")
2213 ertcont = parbeg + 5
2214 if document.body[ertcont].startswith("[<"):
2215 # This is a default overlay specification
2217 document.body[ertcont] = document.body[ertcont][2:]
2218 if document.body[ertcont].endswith(">]"):
2220 document.body[ertcont] = document.body[ertcont][:-2]
2221 elif document.body[ertcont].endswith("]"):
2223 tok = document.body[ertcont].find('>][')
2225 subst = [document.body[ertcont][:tok],
2226 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2227 'status collapsed', '', '\\begin_layout Plain Layout',
2228 document.body[ertcont][tok + 3:-1]]
2229 document.body[ertcont : ertcont + 1] = subst
2231 # Convert to ArgInset
2232 document.body[parbeg] = "\\begin_inset Argument 2"
2233 elif document.body[ertcont].startswith("<"):
2234 # This is an overlay specification
2236 document.body[ertcont] = document.body[ertcont][1:]
2237 if document.body[ertcont].endswith(">"):
2239 document.body[ertcont] = document.body[ertcont][:-1]
2240 # Convert to ArgInset
2241 document.body[parbeg] = "\\begin_inset Argument 1"
2242 elif document.body[ertcont].endswith(">]"):
2244 tok = document.body[ertcont].find('>[<')
2246 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2247 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2248 'status collapsed', '', '\\begin_layout Plain Layout',
2249 document.body[ertcont][tok + 3:-2]]
2250 # Convert to ArgInset
2251 document.body[parbeg] = "\\begin_inset Argument 1"
2253 elif document.body[ertcont].endswith("]"):
2255 tok = document.body[ertcont].find('>[<')
2258 tokk = document.body[ertcont].find('>][')
2260 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2261 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2262 'status collapsed', '', '\\begin_layout Plain Layout',
2263 document.body[ertcont][tok + 3:tokk],
2264 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2265 'status collapsed', '', '\\begin_layout Plain Layout',
2266 document.body[ertcont][tokk + 3:-1]]
2269 tokk = document.body[ertcont].find('>[')
2271 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tokk],
2272 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2273 'status collapsed', '', '\\begin_layout Plain Layout',
2274 document.body[ertcont][tokk + 2:-1]]
2276 # Convert to ArgInset
2277 document.body[parbeg] = "\\begin_inset Argument 1"
2278 elif document.body[ertcont].startswith("["):
2279 # This is an ERT option
2281 document.body[ertcont] = document.body[ertcont][1:]
2282 if document.body[ertcont].endswith("]"):
2284 document.body[ertcont] = document.body[ertcont][:-1]
2285 # Convert to ArgInset
2286 document.body[parbeg] = "\\begin_inset Argument 3"
2292 def convert_againframe_args(document):
2293 " Converts beamer AgainFrame to new layout "
2295 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2296 if document.textclass not in beamer_classes:
2301 i = find_token(document.body, "\\begin_layout AgainFrame", i)
2304 parent = get_containing_layout(document.body, i)
2306 document.warning("Wrong parent layout!")
2310 # Convert ERT arguments
2311 # FIXME: See restrictions in convert_beamerframeargs method
2312 ertend = convert_beamerframeargs(document, i, parbeg)
2318 def convert_corollary_args(document):
2319 " Converts beamer corrolary-style ERT arguments native InsetArgs "
2321 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2322 if document.textclass not in beamer_classes:
2325 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2326 for lay in corollary_layouts:
2329 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2332 parent = get_containing_layout(document.body, i)
2334 document.warning("Wrong parent layout!")
2338 if document.body[parbeg] == "\\begin_inset ERT":
2339 ertcont = parbeg + 5
2340 if document.body[ertcont].startswith("<"):
2341 # This is an overlay specification
2343 document.body[ertcont] = document.body[ertcont][1:]
2344 if document.body[ertcont].endswith(">"):
2346 document.body[ertcont] = document.body[ertcont][:-1]
2347 elif document.body[ertcont].endswith("]"):
2349 tok = document.body[ertcont].find('>[')
2351 subst = [document.body[ertcont][:tok],
2352 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2353 'status collapsed', '', '\\begin_layout Plain Layout',
2354 document.body[ertcont][tok + 2:-1]]
2355 document.body[ertcont : ertcont + 1] = subst
2356 # Convert to ArgInset
2357 document.body[parbeg] = "\\begin_inset Argument 1"
2360 elif document.body[ertcont].startswith("["):
2361 if document.body[ertcont].endswith("]"):
2362 # This is an ERT option
2364 document.body[ertcont] = document.body[ertcont][1:]
2366 document.body[ertcont] = document.body[ertcont][:-1]
2367 # Convert to ArgInset
2368 document.body[parbeg] = "\\begin_inset Argument 2"
2370 convert_TeX_brace_to_Argument(document, i, 2, 2, False, True, True)
2377 def convert_quote_args(document):
2378 " Converts beamer quote style ERT args to native InsetArgs "
2380 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2381 if document.textclass not in beamer_classes:
2384 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2385 for lay in quote_layouts:
2388 i = find_token(document.body, "\\begin_layout " + lay, i)
2391 parent = get_containing_layout(document.body, i)
2393 document.warning("Wrong parent layout!")
2397 if document.body[parbeg] == "\\begin_inset ERT":
2398 if document.body[i + 6].startswith("<"):
2399 # This is an overlay specification
2401 document.body[i + 6] = document.body[i + 6][1:]
2402 if document.body[i + 6].endswith(">"):
2404 document.body[i + 6] = document.body[i + 6][:-1]
2405 # Convert to ArgInset
2406 document.body[i + 1] = "\\begin_inset Argument 1"
2410 def revert_beamerargs(document):
2411 " Reverts beamer arguments to old layout "
2413 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2414 if document.textclass not in beamer_classes:
2418 list_layouts = ["Itemize", "Enumerate", "Description"]
2419 headings = ["Part", "Section", "Section*", "Subsection", "Subsection*",
2420 "Subsubsection", "Subsubsection*", "FrameSubtitle", "NoteItem"]
2421 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2422 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2423 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2426 i = find_token(document.body, "\\begin_inset Argument", i)
2429 # Find containing paragraph layout
2430 parent = get_containing_layout(document.body, i)
2432 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2437 realparbeg = parent[3]
2438 layoutname = parent[0]
2440 for p in range(parbeg, parend):
2444 if layoutname in headings:
2445 m = rx.match(document.body[p])
2449 # Find containing paragraph layout
2450 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2451 endPlain = find_end_of_layout(document.body, beginPlain)
2452 endInset = find_end_of_inset(document.body, p)
2453 argcontent = document.body[beginPlain + 1 : endPlain]
2455 realparend = realparend - len(document.body[p : endInset + 1])
2457 del document.body[p : endInset + 1]
2458 if layoutname == "FrameSubtitle":
2459 pre = put_cmd_in_ert("\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2460 elif layoutname == "NoteItem":
2461 pre = put_cmd_in_ert("\\note<") + argcontent + put_cmd_in_ert(">[item]")
2462 elif layoutname.endswith('*'):
2463 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower()[:-1] + "<") + argcontent + put_cmd_in_ert(">*")
2465 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2466 secarg = find_token(document.body, "\\begin_inset Argument 2", parbeg, parend)
2468 # Find containing paragraph layout
2469 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", secarg)
2470 endPlain = find_end_of_layout(document.body, beginPlain)
2471 endInset = find_end_of_inset(document.body, secarg)
2472 argcontent = document.body[beginPlain + 1 : endPlain]
2474 realparend = realparend - len(document.body[secarg : endInset + 1])
2475 del document.body[secarg : endInset + 1]
2476 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2477 pre += put_cmd_in_ert("{")
2478 document.body[parbeg] = "\\begin_layout Standard"
2479 document.body[realparbeg : realparbeg] = pre
2480 pe = find_end_of_layout(document.body, parbeg)
2481 post = put_cmd_in_ert("}")
2482 document.body[pe : pe] = post
2483 realparend += len(pre) + len(post)
2484 if layoutname == "AgainFrame":
2485 m = rx.match(document.body[p])
2489 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2490 endPlain = find_end_of_layout(document.body, beginPlain)
2491 endInset = find_end_of_inset(document.body, p)
2492 content = document.body[beginPlain + 1 : endPlain]
2494 realparend = realparend - len(document.body[p : endInset + 1])
2496 del document.body[p : endInset + 1]
2497 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2498 document.body[realparbeg : realparbeg] = subst
2499 if layoutname == "Overprint":
2500 m = rx.match(document.body[p])
2504 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2505 endPlain = find_end_of_layout(document.body, beginPlain)
2506 endInset = find_end_of_inset(document.body, p)
2507 content = document.body[beginPlain + 1 : endPlain]
2509 realparend = realparend - len(document.body[p : endInset + 1])
2511 del document.body[p : endInset + 1]
2512 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2513 document.body[realparbeg : realparbeg] = subst
2514 if layoutname == "OverlayArea":
2515 m = rx.match(document.body[p])
2519 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2520 endPlain = find_end_of_layout(document.body, beginPlain)
2521 endInset = find_end_of_inset(document.body, p)
2522 content = document.body[beginPlain + 1 : endPlain]
2524 realparend = realparend - len(document.body[p : endInset + 1])
2526 del document.body[p : endInset + 1]
2527 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2528 document.body[realparbeg : realparbeg] = subst
2529 if layoutname in list_layouts:
2530 m = rx.match(document.body[p])
2534 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2535 endPlain = find_end_of_layout(document.body, beginPlain)
2536 endInset = find_end_of_inset(document.body, p)
2537 content = document.body[beginPlain + 1 : endPlain]
2538 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2539 realparend = realparend + len(subst) - len(content)
2540 document.body[beginPlain + 1 : endPlain] = subst
2541 elif argnr == "item:1":
2542 j = find_end_of_inset(document.body, i)
2543 # Find containing paragraph layout
2544 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2545 endPlain = find_end_of_layout(document.body, beginPlain)
2546 content = document.body[beginPlain + 1 : endPlain]
2547 del document.body[i:j+1]
2548 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2549 document.body[realparbeg : realparbeg] = subst
2550 elif argnr == "item:2":
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 if layoutname in quote_layouts:
2560 m = rx.match(document.body[p])
2564 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2565 endPlain = find_end_of_layout(document.body, beginPlain)
2566 endInset = find_end_of_inset(document.body, p)
2567 content = document.body[beginPlain + 1 : endPlain]
2569 realparend = realparend - len(document.body[p : endInset + 1])
2571 del document.body[p : endInset + 1]
2572 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2573 document.body[realparbeg : realparbeg] = subst
2574 if layoutname in corollary_layouts:
2575 m = rx.match(document.body[p])
2579 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2580 endPlain = find_end_of_layout(document.body, beginPlain)
2581 endInset = find_end_of_inset(document.body, p)
2582 content = document.body[beginPlain + 1 : endPlain]
2584 realparend = realparend - len(document.body[p : endInset + 1])
2586 del document.body[p : endInset + 1]
2587 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2588 document.body[realparbeg : realparbeg] = subst
2593 def revert_beamerargs2(document):
2594 " Reverts beamer arguments to old layout, step 2 "
2596 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2597 if document.textclass not in beamer_classes:
2601 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
2602 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2603 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2606 i = find_token(document.body, "\\begin_inset Argument", i)
2609 # Find containing paragraph layout
2610 parent = get_containing_layout(document.body, i)
2612 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2617 realparbeg = parent[3]
2618 layoutname = parent[0]
2620 for p in range(parbeg, parend):
2624 if layoutname in shifted_layouts:
2625 m = rx.match(document.body[p])
2629 document.body[p] = "\\begin_inset Argument 1"
2630 if layoutname in corollary_layouts:
2631 m = rx.match(document.body[p])
2635 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2636 endPlain = find_end_of_layout(document.body, beginPlain)
2637 endInset = find_end_of_inset(document.body, p)
2638 content = document.body[beginPlain + 1 : endPlain]
2640 realparend = realparend - len(document.body[p : endInset + 1])
2642 del document.body[p : endInset + 1]
2643 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2644 document.body[realparbeg : realparbeg] = subst
2645 if layoutname == "OverlayArea":
2646 m = rx.match(document.body[p])
2650 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2651 endPlain = find_end_of_layout(document.body, beginPlain)
2652 endInset = find_end_of_inset(document.body, p)
2653 content = document.body[beginPlain + 1 : endPlain]
2655 realparend = realparend - len(document.body[p : endInset + 1])
2657 del document.body[p : endInset + 1]
2658 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2659 document.body[realparbeg : realparbeg] = subst
2660 if layoutname == "AgainFrame":
2661 m = rx.match(document.body[p])
2665 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2666 endPlain = find_end_of_layout(document.body, beginPlain)
2667 endInset = find_end_of_inset(document.body, p)
2668 content = document.body[beginPlain + 1 : endPlain]
2670 realparend = realparend - len(document.body[p : endInset + 1])
2672 del document.body[p : endInset + 1]
2673 subst = put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
2674 document.body[realparbeg : realparbeg] = subst
2678 def revert_beamerargs3(document):
2679 " Reverts beamer arguments to old layout, step 3 "
2681 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2682 if document.textclass not in beamer_classes:
2685 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2688 i = find_token(document.body, "\\begin_inset Argument", i)
2691 # Find containing paragraph layout
2692 parent = get_containing_layout(document.body, i)
2694 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2699 realparbeg = parent[3]
2700 layoutname = parent[0]
2702 for p in range(parbeg, parend):
2706 if layoutname == "AgainFrame":
2707 m = rx.match(document.body[p])
2711 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2712 endPlain = find_end_of_layout(document.body, beginPlain)
2713 endInset = find_end_of_inset(document.body, p)
2714 content = document.body[beginPlain + 1 : endPlain]
2716 realparend = realparend - len(document.body[p : endInset + 1])
2718 del document.body[p : endInset + 1]
2719 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2720 document.body[realparbeg : realparbeg] = subst
2724 def revert_beamerflex(document):
2725 " Reverts beamer Flex insets "
2727 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2728 if document.textclass not in beamer_classes:
2731 new_flexes = {"Bold" : "\\textbf", "Emphasize" : "\\emph", "Only" : "\\only",
2732 "Uncover" : "\\uncover", "Visible" : "\\visible",
2733 "Invisible" : "\\invisible", "Alternative" : "\\alt",
2734 "Beamer_Note" : "\\note"}
2735 old_flexes = {"Alert" : "\\alert", "Structure" : "\\structure"}
2736 rx = re.compile(r'^\\begin_inset Flex (.+)$')
2740 i = find_token(document.body, "\\begin_inset Flex", i)
2743 m = rx.match(document.body[i])
2745 flextype = m.group(1)
2746 z = find_end_of_inset(document.body, i)
2748 document.warning("Can't find end of Flex " + flextype + " inset.")
2751 if flextype in new_flexes:
2752 pre = put_cmd_in_ert(new_flexes[flextype])
2753 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2755 argend = find_end_of_inset(document.body, arg)
2757 document.warning("Can't find end of Argument!")
2760 # Find containing paragraph layout
2761 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2762 endPlain = find_end_of_layout(document.body, beginPlain)
2763 argcontent = document.body[beginPlain + 1 : endPlain]
2765 z = z - len(document.body[arg : argend + 1])
2767 del document.body[arg : argend + 1]
2768 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2769 arg = find_token(document.body, "\\begin_inset Argument 2", i, z)
2771 argend = find_end_of_inset(document.body, arg)
2773 document.warning("Can't find end of Argument!")
2776 # Find containing paragraph layout
2777 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2778 endPlain = find_end_of_layout(document.body, beginPlain)
2779 argcontent = document.body[beginPlain + 1 : endPlain]
2781 z = z - len(document.body[arg : argend + 1])
2783 del document.body[arg : argend + 1]
2784 if flextype == "Alternative":
2785 pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
2787 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2788 pre += put_cmd_in_ert("{")
2789 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2790 endPlain = find_end_of_layout(document.body, beginPlain)
2792 z = z - len(document.body[i : beginPlain + 1])
2794 document.body[i : beginPlain + 1] = pre
2795 post = put_cmd_in_ert("}")
2796 document.body[z - 2 : z + 1] = post
2797 elif flextype in old_flexes:
2798 pre = put_cmd_in_ert(old_flexes[flextype])
2799 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2803 argend = find_end_of_inset(document.body, arg)
2805 document.warning("Can't find end of Argument!")
2808 # Find containing paragraph layout
2809 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2810 endPlain = find_end_of_layout(document.body, beginPlain)
2811 argcontent = document.body[beginPlain + 1 : endPlain]
2813 z = z - len(document.body[arg : argend + 1])
2815 del document.body[arg : argend + 1]
2816 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2817 pre += put_cmd_in_ert("{")
2818 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2819 endPlain = find_end_of_layout(document.body, beginPlain)
2821 z = z - len(document.body[i : beginPlain + 1])
2823 document.body[i : beginPlain + 1] = pre
2824 post = put_cmd_in_ert("}")
2825 document.body[z - 2 : z + 1] = post
2830 def revert_beamerblocks(document):
2831 " Reverts beamer block arguments to ERT "
2833 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2834 if document.textclass not in beamer_classes:
2837 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2839 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2842 i = find_token(document.body, "\\begin_inset Argument", i)
2845 # Find containing paragraph layout
2846 parent = get_containing_layout(document.body, i)
2848 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2853 realparbeg = parent[3]
2854 layoutname = parent[0]
2856 for p in range(parbeg, parend):
2860 if layoutname in blocks:
2861 m = rx.match(document.body[p])
2865 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2866 endPlain = find_end_of_layout(document.body, beginPlain)
2867 endInset = find_end_of_inset(document.body, p)
2868 content = document.body[beginPlain + 1 : endPlain]
2870 realparend = realparend - len(document.body[p : endInset + 1])
2872 del document.body[p : endInset + 1]
2873 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2874 document.body[realparbeg : realparbeg] = subst
2876 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2877 endPlain = find_end_of_layout(document.body, beginPlain)
2878 endInset = find_end_of_inset(document.body, p)
2879 content = document.body[beginPlain + 1 : endPlain]
2881 realparend = realparend - len(document.body[p : endInset + 1])
2883 del document.body[p : endInset + 1]
2884 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2885 document.body[realparbeg : realparbeg] = subst
2890 def convert_beamerblocks(document):
2891 " Converts beamer block ERT args to native InsetArgs "
2893 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2894 if document.textclass not in beamer_classes:
2897 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2901 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2904 parent = get_containing_layout(document.body, i)
2905 if parent == False or parent[1] != i:
2906 document.warning("Wrong parent layout!")
2913 if document.body[parbeg] == "\\begin_inset ERT":
2914 ertcontfirstline = parbeg + 5
2915 ertcontlastline = parend - 6
2917 if document.body[ertcontfirstline].startswith("<"):
2918 # This is an overlay specification
2920 document.body[ertcontfirstline] = document.body[ertcontfirstline][1:]
2921 if document.body[ertcontlastline].endswith(">"):
2923 document.body[ertcontlastline] = document.body[ertcontlastline][:-1]
2924 # Convert to ArgInset
2925 document.body[parbeg] = "\\begin_inset Argument 1"
2926 elif document.body[ertcontlastline].endswith("}"):
2928 document.body[ertcontlastline] = document.body[ertcontlastline][:-1]
2930 ertcontdivline = ertcontfirstline
2931 tok = document.body[ertcontdivline].find('>{')
2933 regexp = re.compile(r'.*>\{', re.IGNORECASE)
2934 ertcontdivline = find_re(document.body, regexp, ertcontfirstline, ertcontlastline)
2935 tok = document.body[ertcontdivline].find('>{')
2937 if ertcontfirstline < ertcontlastline:
2938 # Multiline ERT. Might contain TeX code. Embrace in ERT.
2939 document.body[ertcontlastline : ertcontlastline + 1] = [
2940 document.body[ertcontlastline], '\\end_layout', '', '\\end_inset']
2941 document.body[ertcontdivline : ertcontdivline + 1] = [document.body[ertcontdivline][:tok],
2942 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2943 'status collapsed', '', '\\begin_layout Plain Layout',
2944 '\\begin_inset ERT', '', 'status open' '', '\\begin_layout Plain Layout',
2945 document.body[ertcontdivline][tok + 2:]]
2947 document.body[ertcontdivline : ertcontdivline + 1] = [document.body[ertcontdivline][:tok],
2948 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2949 'status collapsed', '', '\\begin_layout Plain Layout',
2950 document.body[ertcontdivline][tok + 2:]]
2951 # Convert to ArgInset
2952 document.body[parbeg] = "\\begin_inset Argument 1"
2953 elif document.body[ertcontfirstline].startswith("{"):
2954 # This is the block title
2955 if document.body[ertcontlastline].endswith("}"):
2956 # strip off the braces
2957 document.body[ertcontfirstline] = document.body[ertcontfirstline][1:]
2958 document.body[ertcontlastline] = document.body[ertcontlastline][:-1]
2959 if ertcontfirstline < ertcontlastline:
2960 # Multiline ERT. Might contain TeX code. Embrace in ERT.
2961 document.body[parend : parend + 1] = [
2962 document.body[parend], '\\end_layout', '', '\\end_inset']
2963 document.body[parbeg : parbeg + 1] = ['\\begin_inset Argument 2',
2964 'status collapsed', '', '\\begin_layout Plain Layout',
2965 '\\begin_inset ERT', '']
2967 # Convert to ArgInset
2968 document.body[parbeg] = "\\begin_inset Argument 2"
2969 elif count_pars_in_inset(document.body, ertcontfirstline) > 1:
2970 # Multipar ERT. Skip this.
2973 convert_TeX_brace_to_Argument(document, i, 2, 2, False, True, False)
2976 j = find_end_of_layout(document.body, i)
2978 document.warning("end of layout not found!")
2979 k = find_token(document.body, "\\begin_inset Argument", i, j)
2981 document.warning("InsetArgument not found!")
2983 l = find_end_of_inset(document.body, k)
2984 m = find_token(document.body, "\\begin_inset ERT", l, j)
2987 ertcontfirstline = m + 5
2992 def convert_overprint(document):
2993 " Convert old beamer overprint layouts to ERT "
2995 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2996 if document.textclass not in beamer_classes:
3001 i = find_token(document.body, "\\begin_layout Overprint", i)
3004 # Find end of sequence
3005 j = find_end_of_sequence(document.body, i)
3007 document.warning("Malformed LyX document. Cannot find end of Overprint sequence!")
3011 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
3013 if document.body[j] == "\\end_deeper":
3014 esubst = ["", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
3016 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
3017 endseq = endseq + len(esubst) - len(document.body[j : j])
3018 document.body[j : j] = esubst
3019 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
3021 argend = find_end_of_layout(document.body, argbeg)
3023 document.warning("Malformed LyX document. Cannot find end of Overprint argument!")
3026 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3027 endPlain = find_end_of_layout(document.body, beginPlain)
3028 content = document.body[beginPlain + 1 : endPlain]
3030 endseq = endseq - len(document.body[argbeg : argend + 1])
3032 del document.body[argbeg : argend + 1]
3033 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3035 endseq = endseq - len(document.body[i : i])
3036 document.body[i : i] = subst + ["\\end_layout"]
3037 endseq += len(subst)
3039 for p in range(i, endseq):
3040 if document.body[p] == "\\begin_layout Overprint":
3041 document.body[p] = "\\begin_layout Standard"
3046 def revert_overprint(document):
3047 " Revert old beamer overprint layouts to ERT "
3049 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3050 if document.textclass not in beamer_classes:
3055 i = find_token(document.body, "\\begin_layout Overprint", i)
3058 # Find end of sequence
3059 j = find_end_of_sequence(document.body, i)
3061 document.warning("Malformed LyX document. Cannot find end of Overprint sequence!")
3065 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
3066 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}")
3067 endseq = endseq + len(esubst) - len(document.body[j : j])
3068 if document.body[j] == "\\end_deeper":
3069 document.body[j : j] = ["\\end_deeper", ""] + esubst
3071 document.body[j : j] = esubst
3074 if document.body[r] == "\\begin_deeper":
3075 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3077 document.body[r] = ""
3078 document.body[s] = ""
3082 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
3084 argend = find_end_of_inset(document.body, argbeg)
3086 document.warning("Malformed LyX document. Cannot find end of Overprint argument!")
3089 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3090 endPlain = find_end_of_layout(document.body, beginPlain)
3091 content = document.body[beginPlain + 1 : endPlain]
3093 endseq = endseq - len(document.body[argbeg : argend])
3095 del document.body[argbeg : argend + 1]
3096 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3098 endseq = endseq - len(document.body[i : i])
3099 document.body[i : i] = subst + ["\\end_layout"]
3100 endseq += len(subst)
3106 if document.body[p] == "\\begin_layout Overprint":
3107 q = find_end_of_layout(document.body, p)
3109 document.warning("Malformed LyX document. Cannot find end of Overprint layout!")
3112 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\onslide")
3113 argbeg = find_token(document.body, "\\begin_inset Argument item:1", p, q)
3115 argend = find_end_of_inset(document.body, argbeg)
3117 document.warning("Malformed LyX document. Cannot find end of Overprint item argument!")
3120 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3121 endPlain = find_end_of_layout(document.body, beginPlain)
3122 content = document.body[beginPlain + 1 : endPlain]
3124 endseq = endseq - len(document.body[argbeg : argend + 1])
3126 del document.body[argbeg : argend + 1]
3127 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3128 endseq = endseq - len(document.body[p : p + 1]) + len(subst)
3129 document.body[p : p + 1] = subst
3135 def revert_frametitle(document):
3136 " Reverts beamer frametitle layout to ERT "
3138 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3139 if document.textclass not in beamer_classes:
3142 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
3145 i = find_token(document.body, "\\begin_layout FrameTitle", i)
3148 j = find_end_of_layout(document.body, i)
3150 document.warning("Malformed LyX document: Can't find end of FrameTitle layout")
3154 document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
3155 endlay += len(put_cmd_in_ert("}"))
3156 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\frametitle")
3157 for p in range(i, j):
3160 m = rx.match(document.body[p])
3164 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3165 endPlain = find_end_of_layout(document.body, beginPlain)
3166 endInset = find_end_of_inset(document.body, p)
3167 content = document.body[beginPlain + 1 : endPlain]
3169 endlay = endlay - len(document.body[p : endInset + 1])
3171 del document.body[p : endInset + 1]
3172 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3174 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3175 endPlain = find_end_of_layout(document.body, beginPlain)
3176 endInset = find_end_of_inset(document.body, p)
3177 content = document.body[beginPlain + 1 : endPlain]
3179 endlay = endlay - len(document.body[p : endInset + 1])
3181 del document.body[p : endInset + 1]
3182 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3184 subst += put_cmd_in_ert("{")
3185 document.body[i : i + 1] = subst
3189 def convert_epigraph(document):
3190 " Converts memoir epigraph to new syntax "
3192 if document.textclass != "memoir":
3197 i = find_token(document.body, "\\begin_layout Epigraph", i)
3200 j = find_end_of_layout(document.body, i)
3202 document.warning("Malformed LyX document: Can't find end of Epigraph layout")
3207 ert = find_token(document.body, "\\begin_inset ERT", i, j)
3209 endInset = find_end_of_inset(document.body, ert)
3210 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", ert)
3211 endPlain = find_end_of_layout(document.body, beginPlain)
3212 ertcont = beginPlain + 2
3213 if document.body[ertcont] == "}{":
3215 # Convert to ArgInset
3216 endlay = endlay - 2 * len(document.body[j])
3217 begsubst = ['\\begin_inset Argument post:1', 'status collapsed', '',
3218 '\\begin_layout Plain Layout']
3219 endsubst = ['\\end_layout', '', '\\end_inset', '', document.body[j]]
3220 document.body[j : j + 1] = endsubst
3221 document.body[endInset + 1 : endInset + 1] = begsubst
3223 endlay += len(begsubst) + len(endsubst)
3224 endlay = endlay - len(document.body[ert : endInset + 1])
3225 del document.body[ert : endInset + 1]
3230 def revert_epigraph(document):
3231 " Reverts memoir epigraph argument to ERT "
3233 if document.textclass != "memoir":
3238 i = find_token(document.body, "\\begin_layout Epigraph", i)
3241 j = find_end_of_layout(document.body, i)
3243 document.warning("Malformed LyX document: Can't find end of Epigraph layout")
3248 p = find_token(document.body, "\\begin_layout Argument post:1", i, j)
3250 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3251 endPlain = find_end_of_layout(document.body, beginPlain)
3252 endInset = find_end_of_inset(document.body, p)
3253 content = document.body[beginPlain + 1 : endPlain]
3255 endlay = endlay - len(document.body[p : endInset + 1])
3257 del document.body[p : endInset + 1]
3258 subst += put_cmd_in_ert("}{") + content
3260 subst += put_cmd_in_ert("}{")
3262 document.body[j : j] = subst + document.body[j : j]
3266 def convert_captioninsets(document):
3267 " Converts caption insets to new syntax "
3271 i = find_token(document.body, "\\begin_inset Caption", i)
3274 document.body[i] = "\\begin_inset Caption Standard"
3278 def revert_captioninsets(document):
3279 " Reverts caption insets to old syntax "
3283 i = find_token(document.body, "\\begin_inset Caption Standard", i)
3286 document.body[i] = "\\begin_inset Caption"
3290 def convert_captionlayouts(document):
3291 " Convert caption layouts to caption insets. "
3294 "Captionabove": "Above",
3295 "Captionbelow": "Below",
3296 "FigCaption" : "FigCaption",
3297 "Table_Caption" : "Table",
3298 "CenteredCaption" : "Centered",
3299 "Bicaption" : "Bicaption",
3304 i = find_token(document.body, "\\begin_layout", i)
3307 val = get_value(document.body, "\\begin_layout", i)
3308 if val in caption_dict.keys():
3309 j = find_end_of_layout(document.body, i)
3311 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3314 document.body[j:j] = ["\\end_layout", "", "\\end_inset", "", ""]
3315 document.body[i:i+1] = ["\\begin_layout %s" % document.default_layout,
3316 "\\begin_inset Caption %s" % caption_dict[val], "",
3317 "\\begin_layout %s" % document.default_layout]
3321 def revert_captionlayouts(document):
3322 " Revert caption insets to caption layouts. "
3325 "Above" : "Captionabove",
3326 "Below" : "Captionbelow",
3327 "FigCaption" : "FigCaption",
3328 "Table" : "Table_Caption",
3329 "Centered" : "CenteredCaption",
3330 "Bicaption" : "Bicaption",
3334 rx = re.compile(r'^\\begin_inset Caption (\S+)$')
3336 i = find_token(document.body, "\\begin_inset Caption", i)
3340 m = rx.match(document.body[i])
3344 if val not in caption_dict.keys():
3348 # We either need to delete the previous \begin_layout line, or we
3349 # need to end the previous layout if this inset is not in the first
3350 # position of the paragraph.
3351 layout_before = find_token_backwards(document.body, "\\begin_layout", i)
3352 if layout_before == -1:
3353 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3355 layout_line = document.body[layout_before]
3356 del_layout_before = True
3357 l = layout_before + 1
3359 if document.body[l] != "":
3360 del_layout_before = False
3363 if del_layout_before:
3364 del document.body[layout_before:i]
3367 document.body[i:i] = ["\\end_layout", ""]
3370 # Find start of layout in the inset and end of inset
3371 j = find_token(document.body, "\\begin_layout", i)
3373 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3375 k = find_end_of_inset(document.body, i)
3377 document.warning("Malformed LyX document: Missing `\\end_inset'.")
3380 # We either need to delete the following \end_layout line, or we need
3381 # to restart the old layout if this inset is not at the paragraph end.
3382 layout_after = find_token(document.body, "\\end_layout", k)
3383 if layout_after == -1:
3384 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3386 del_layout_after = True
3388 while l < layout_after:
3389 if document.body[l] != "":
3390 del_layout_after = False
3393 if del_layout_after:
3394 del document.body[k+1:layout_after+1]
3396 document.body[k+1:k+1] = [layout_line, ""]
3398 # delete \begin_layout and \end_inset and replace \begin_inset with
3399 # "\begin_layout XXX". This works because we can only have one
3400 # paragraph in the caption inset: The old \end_layout will be recycled.
3401 del document.body[k]
3402 if document.body[k] == "":
3403 del document.body[k]
3404 del document.body[j]
3405 if document.body[j] == "":
3406 del document.body[j]
3407 document.body[i] = "\\begin_layout %s" % caption_dict[val]
3408 if document.body[i+1] == "":
3409 del document.body[i+1]
3413 def revert_fragileframe(document):
3414 " Reverts beamer FragileFrame layout to ERT "
3416 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3417 if document.textclass not in beamer_classes:
3422 i = find_token(document.body, "\\begin_layout FragileFrame", i)
3425 # Find end of sequence
3426 j = find_end_of_sequence(document.body, i)
3428 document.warning("Malformed LyX document. Cannot find end of FragileFrame sequence!")
3432 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{frame}")
3433 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{frame}")
3434 endseq = endseq + len(esubst) - len(document.body[j : j])
3435 if document.body[j] == "\\end_deeper":
3436 document.body[j : j] = ["\\end_deeper", ""] + esubst
3438 document.body[j : j] = esubst
3439 for q in range(i, j):
3440 if document.body[q] == "\\begin_layout FragileFrame":
3441 document.body[q] = "\\begin_layout %s" % document.default_layout
3444 if document.body[r] == "\\begin_deeper":
3445 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3447 document.body[r] = ""
3448 document.body[s] = ""
3452 for p in range(1, 5):
3453 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, j)
3456 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3457 endPlain = find_end_of_layout(document.body, beginPlain)
3458 endInset = find_end_of_inset(document.body, arg)
3459 content = document.body[beginPlain + 1 : endPlain]
3461 j = j - len(document.body[arg : endInset + 1])
3463 del document.body[arg : endInset + 1]
3464 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3466 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3467 endPlain = find_end_of_layout(document.body, beginPlain)
3468 endInset = find_end_of_inset(document.body, arg)
3469 content = document.body[beginPlain + 1 : endPlain]
3471 j = j - len(document.body[arg : endInset + 1])
3473 del document.body[arg : endInset + 1]
3474 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3476 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3477 endPlain = find_end_of_layout(document.body, beginPlain)
3478 endInset = find_end_of_inset(document.body, arg)
3479 content = document.body[beginPlain + 1 : endPlain]
3481 j = j - len(document.body[arg : endInset + 1])
3483 del document.body[arg : endInset + 1]
3484 subst += put_cmd_in_ert("[fragile,") + content + put_cmd_in_ert("]")
3486 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3487 endPlain = find_end_of_layout(document.body, beginPlain)
3488 endInset = find_end_of_inset(document.body, arg)
3489 content = document.body[beginPlain + 1 : endPlain]
3491 j = j - len(document.body[arg : endInset + 1])
3493 del document.body[arg : endInset + 1]
3494 subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
3496 subst += put_cmd_in_ert("[fragile]")
3498 document.body[i : i + 1] = subst
3502 def revert_newframes(document):
3503 " Reverts beamer Frame and PlainFrame layouts to old forms "
3505 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3506 if document.textclass not in beamer_classes:
3510 "Frame" : "BeginFrame",
3511 "PlainFrame" : "BeginPlainFrame",
3514 rx = re.compile(r'^\\begin_layout (\S+)$')
3517 i = find_token(document.body, "\\begin_layout", i)
3521 m = rx.match(document.body[i])
3525 if val not in frame_dict.keys():
3528 # Find end of sequence
3529 j = find_end_of_sequence(document.body, i)
3531 document.warning("Malformed LyX document. Cannot find end of Frame sequence!")
3535 subst = ["\\begin_layout %s" % frame_dict[val]]
3536 esubst = ["\\end_layout", "", "\\begin_layout EndFrame", "", "\\end_layout"]
3537 endseq = endseq + len(esubst) - len(document.body[j : j])
3538 if document.body[j] == "\\end_deeper":
3539 document.body[j : j] = ["\\end_deeper", ""] + esubst
3541 document.body[j : j] = esubst
3542 for q in range(i, j):
3543 if document.body[q] == "\\begin_layout %s" % val:
3544 document.body[q] = "\\begin_layout %s" % document.default_layout
3547 if document.body[r] == "\\begin_deeper":
3548 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3550 document.body[r] = ""
3551 document.body[s] = ""
3555 l = find_end_of_layout(document.body, i)
3556 for p in range(1, 5):
3557 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, l)
3560 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3561 endPlain = find_end_of_layout(document.body, beginPlain)
3562 endInset = find_end_of_inset(document.body, arg)
3563 content = document.body[beginPlain + 1 : endPlain]
3565 l = l - len(document.body[arg : endInset + 1])
3567 del document.body[arg : endInset + 1]
3568 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3570 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3571 endPlain = find_end_of_layout(document.body, beginPlain)
3572 endInset = find_end_of_inset(document.body, arg)
3573 content = document.body[beginPlain + 1 : endPlain]
3575 l = l - len(document.body[arg : endInset + 1])
3577 del document.body[arg : endInset + 1]
3578 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3580 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3581 endPlain = find_end_of_layout(document.body, beginPlain)
3582 endInset = find_end_of_inset(document.body, arg)
3583 content = document.body[beginPlain + 1 : endPlain]
3585 l = l - len(document.body[arg : endInset + 1])
3587 del document.body[arg : endInset + 1]
3588 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3590 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3591 endPlain = find_end_of_layout(document.body, beginPlain)
3592 endInset = find_end_of_inset(document.body, arg)
3593 content = document.body[beginPlain + 1 : endPlain]
3595 l = l - len(document.body[arg : endInset + 1])
3597 del document.body[arg : endInset + 1]
3600 document.body[i : i + 1] = subst
3603 # known encodings that do not change their names (same LyX and LaTeX names)
3604 known_enc_tuple = ("auto", "default", "ansinew", "applemac", "armscii8", "ascii",
3605 "cp437", "cp437de", "cp850", "cp852", "cp855", "cp858", "cp862", "cp865", "cp866",
3606 "cp1250", "cp1251", "cp1252", "cp1255", "cp1256", "cp1257", "koi8-r", "koi8-u",
3607 "pt154", "pt254", "tis620-0", "utf8", "utf8x", "utf8-plain")
3609 def convert_encodings(document):
3610 "Use the LyX names of the encodings instead of the LaTeX names."
3611 LaTeX2LyX_enc_dict = {
3612 "8859-6": "iso8859-6",
3613 "8859-8": "iso8859-8",
3615 "euc": "euc-jp-platex",
3620 "iso88595": "iso8859-5",
3621 "iso-8859-7": "iso8859-7",
3623 "jis": "jis-platex",
3625 "l7xenc": "iso8859-13",
3626 "latin1": "iso8859-1",
3627 "latin2": "iso8859-2",
3628 "latin3": "iso8859-3",
3629 "latin4": "iso8859-4",
3630 "latin5": "iso8859-9",
3631 "latin9": "iso8859-15",
3632 "latin10": "iso8859-16",
3633 "SJIS": "shift-jis",
3634 "sjis": "shift-jis-platex",
3637 i = find_token(document.header, "\\inputencoding" , 0)
3640 val = get_value(document.header, "\\inputencoding", i)
3641 if val in LaTeX2LyX_enc_dict.keys():
3642 document.header[i] = "\\inputencoding %s" % LaTeX2LyX_enc_dict[val]
3643 elif val not in known_enc_tuple:
3644 document.warning("Ignoring unknown input encoding: `%s'" % val)
3647 def revert_encodings(document):
3648 """Revert to using the LaTeX names of the encodings instead of the LyX names.
3649 Also revert utf8-platex to sjis, the language default when using Japanese.
3651 LyX2LaTeX_enc_dict = {
3656 "euc-jp-platex": "euc",
3659 "iso8859-1": "latin1",
3660 "iso8859-2": "latin2",
3661 "iso8859-3": "latin3",
3662 "iso8859-4": "latin4",
3663 "iso8859-5": "iso88595",
3664 "iso8859-6": "8859-6",
3665 "iso8859-7": "iso-8859-7",
3666 "iso8859-8": "8859-8",
3667 "iso8859-9": "latin5",
3668 "iso8859-13": "l7xenc",
3669 "iso8859-15": "latin9",
3670 "iso8859-16": "latin10",
3672 "jis-platex": "jis",
3673 "shift-jis": "SJIS",
3674 "shift-jis-platex": "sjis",
3676 "utf8-platex": "sjis"
3678 i = find_token(document.header, "\\inputencoding" , 0)
3681 val = get_value(document.header, "\\inputencoding", i)
3682 if val in LyX2LaTeX_enc_dict.keys():
3683 document.header[i] = "\\inputencoding %s" % LyX2LaTeX_enc_dict[val]
3684 elif val not in known_enc_tuple:
3685 document.warning("Ignoring unknown input encoding: `%s'" % val)
3688 def revert_IEEEtran_3(document):
3690 Reverts Flex Insets to TeX-code
3692 if document.textclass == "IEEEtran":
3698 h = find_token(document.body, "\\begin_inset Flex Author Mark", h)
3700 endh = find_end_of_inset(document.body, h)
3701 document.body[endh - 2 : endh + 1] = put_cmd_in_ert("}")
3702 document.body[h : h + 4] = put_cmd_in_ert("\\IEEEauthorrefmark{")
3705 i = find_token(document.body, "\\begin_inset Flex Author Name", i)
3707 endi = find_end_of_inset(document.body, i)
3708 document.body[endi - 2 : endi + 1] = put_cmd_in_ert("}")
3709 document.body[i : i + 4] = put_cmd_in_ert("\\IEEEauthorblockN{")
3712 j = find_token(document.body, "\\begin_inset Flex Author Affiliation", j)
3714 endj = find_end_of_inset(document.body, j)
3715 document.body[endj - 2 : endj + 1] = put_cmd_in_ert("}")
3716 document.body[j : j + 4] = put_cmd_in_ert("\\IEEEauthorblockA{")
3718 if i == -1 and j == -1 and h == -1:
3722 def revert_kurier_fonts(document):
3723 " Revert kurier font definition to LaTeX "
3725 i = find_token(document.header, "\\font_math", 0)
3727 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3728 val = get_value(document.header, "\\font_math", i)
3729 if val == "kurier-math":
3730 add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
3731 "\\usepackage[math]{kurier}\n" \
3732 "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
3733 document.header[i] = "\\font_math auto"
3735 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3736 kurier_fonts = ["kurier", "kurierc", "kurierl", "kurierlc"]
3737 k = find_token(document.header, "\\font_sans kurier", 0)
3739 sf = get_value(document.header, "\\font_sans", k)
3740 if sf in kurier_fonts:
3741 add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
3742 document.header[k] = "\\font_sans default"
3744 def revert_iwona_fonts(document):
3745 " Revert iwona font definition to LaTeX "
3747 i = find_token(document.header, "\\font_math", 0)
3749 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3750 val = get_value(document.header, "\\font_math", i)
3751 if val == "iwona-math":
3752 add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
3753 "\\usepackage[math]{iwona}\n" \
3754 "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
3755 document.header[i] = "\\font_math auto"
3757 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3758 iwona_fonts = ["iwona", "iwonac", "iwonal", "iwonalc"]
3759 k = find_token(document.header, "\\font_sans iwona", 0)
3761 sf = get_value(document.header, "\\font_sans", k)
3762 if sf in iwona_fonts:
3763 add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
3764 document.header[k] = "\\font_sans default"
3767 def revert_new_libertines(document):
3768 " Revert new libertine font definition to LaTeX "
3770 if find_token(document.header, "\\use_non_tex_fonts true", 0) != -1:
3773 i = find_token(document.header, "\\font_typewriter libertine-mono", 0)
3775 preamble = "\\usepackage"
3776 sc = find_token(document.header, "\\font_tt_scale", 0)
3778 scval = get_value(document.header, "\\font_tt_scale", sc)
3780 preamble += "[scale=%f]" % (float(scval) / 100)
3781 document.header[sc] = "\\font_tt_scale 100"
3782 preamble += "{libertineMono-type1}"
3783 add_to_preamble(document, [preamble])
3784 document.header[i] = "\\font_typewriter default"
3786 k = find_token(document.header, "\\font_sans biolinum", 0)
3788 preamble = "\\usepackage"
3790 j = find_token(document.header, "\\font_osf true", 0)
3795 sc = find_token(document.header, "\\font_sf_scale", 0)
3797 scval = get_value(document.header, "\\font_sf_scale", sc)
3799 options += ",scale=%f" % (float(scval) / 100)
3800 document.header[sc] = "\\font_sf_scale 100"
3802 preamble += "[" + options +"]"
3803 preamble += "{biolinum-type1}"
3804 add_to_preamble(document, [preamble])
3805 document.header[k] = "\\font_sans default"
3808 def convert_lyxframes(document):
3809 " Converts old beamer frames to new style "
3811 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3812 if document.textclass not in beamer_classes:
3815 framebeg = ["BeginFrame", "BeginPlainFrame"]
3816 frameend = ["Frame", "PlainFrame", "EndFrame", "BeginFrame", "BeginPlainFrame", "AgainFrame",
3817 "Section", "Section*", "Subsection", "Subsection*", "Subsubsection", "Subsubsection*"]
3818 for lay in framebeg:
3821 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
3824 parent = get_containing_layout(document.body, i)
3825 if parent == False or parent[1] != i:
3826 document.warning("Wrong parent layout!")
3829 frametype = parent[0]
3833 # Step I: Convert ERT arguments
3834 # FIXME: See restrictions in convert_beamerframeargs method
3835 ertend = convert_beamerframeargs(document, i, parbeg)
3838 # Step II: Now rename the layout and convert the title to an argument
3839 j = find_end_of_layout(document.body, i)
3840 document.body[j : j + 1] = ['\\end_layout', '', '\\end_inset', '', '\\end_layout']
3841 if lay == "BeginFrame":
3842 document.body[i] = "\\begin_layout Frame"
3844 document.body[i] = "\\begin_layout PlainFrame"
3845 document.body[ertend + 1 : ertend + 1] = ['\\begin_inset Argument 4',
3846 'status open', '', '\\begin_layout Plain Layout']
3847 # Step III: find real frame end
3851 fend = find_token(document.body, "\\begin_layout", jj)
3853 document.warning("Malformed LyX document: No real frame end!")
3855 val = get_value(document.body, "\\begin_layout", fend)
3856 if val not in frameend:
3859 old = document.body[fend]
3860 if val == frametype:
3861 document.body[fend : fend] = ['\\end_deeper', '', '\\begin_layout Separator', '', '\\end_layout']
3862 # consider explicit EndFrames between two identical frame types
3863 elif val == "EndFrame":
3864 nextlayout = find_token(document.body, "\\begin_layout", fend + 1)
3865 if nextlayout != -1 and get_value(document.body, "\\begin_layout", nextlayout) == frametype:
3866 document.body[fend : fend] = ['\\end_deeper', '', '\\begin_layout Separator', '', '\\end_layout']
3868 document.body[fend : fend] = ['\\end_deeper']
3870 document.body[fend : fend] = ['\\end_deeper']
3871 document.body[j + 1 : j + 1] = ['', '\\begin_deeper']
3876 def remove_endframes(document):
3877 " Remove deprecated beamer endframes "
3879 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3880 if document.textclass not in beamer_classes:
3885 i = find_token_exact(document.body, "\\begin_layout EndFrame", i)
3888 j = find_end_of_layout(document.body, i)
3890 document.warning("Malformed LyX document: Missing \\end_layout to EndFrame")
3893 del document.body[i : j + 1]
3896 def revert_powerdot_flexes(document):
3897 " Reverts powerdot flex insets "
3899 if document.textclass != "powerdot":
3902 flexes = {"Onslide" : "\\onslide",
3903 "Onslide*" : "\\onslide*",
3904 "Onslide+" : "\\onslide+"}
3905 rx = re.compile(r'^\\begin_inset Flex (.+)$')
3909 i = find_token(document.body, "\\begin_inset Flex", i)
3912 m = rx.match(document.body[i])
3914 flextype = m.group(1)
3915 z = find_end_of_inset(document.body, i)
3917 document.warning("Can't find end of Flex " + flextype + " inset.")
3920 if flextype in flexes:
3921 pre = put_cmd_in_ert(flexes[flextype])
3922 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
3924 argend = find_end_of_inset(document.body, arg)
3926 document.warning("Can't find end of Argument!")
3929 # Find containing paragraph layout
3930 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3931 endPlain = find_end_of_layout(document.body, beginPlain)
3932 argcontent = document.body[beginPlain + 1 : endPlain]
3934 z = z - len(document.body[arg : argend + 1])
3936 del document.body[arg : argend + 1]
3937 pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
3938 pre += put_cmd_in_ert("{")
3939 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
3940 endPlain = find_end_of_layout(document.body, beginPlain)
3942 z = z - len(document.body[i : beginPlain + 1])
3944 document.body[i : beginPlain + 1] = pre
3945 post = put_cmd_in_ert("}")
3946 document.body[z - 2 : z + 1] = post
3950 def revert_powerdot_pause(document):
3951 " Reverts powerdot pause layout to ERT "
3953 if document.textclass != "powerdot":
3958 i = find_token(document.body, "\\begin_layout Pause", i)
3961 j = find_end_of_layout(document.body, i)
3963 document.warning("Malformed LyX document: Can't find end of Pause layout")
3967 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\pause")
3968 for p in range(i, j):
3971 arg = find_token(document.body, "\\begin_inset Argument 1", i, j)
3973 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3974 endPlain = find_end_of_layout(document.body, beginPlain)
3975 endInset = find_end_of_inset(document.body, p)
3976 content = document.body[beginPlain + 1 : endPlain]
3978 endlay = endlay - len(document.body[p : endInset + 1])
3980 del document.body[p : endInset + 1]
3981 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3983 document.body[i : i + 1] = subst
3987 def revert_powerdot_itemargs(document):
3988 " Reverts powerdot item arguments to ERT "
3990 if document.textclass != "powerdot":
3994 list_layouts = ["Itemize", "ItemizeType1", "Enumerate", "EnumerateType1"]
3995 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
3998 i = find_token(document.body, "\\begin_inset Argument", i)
4001 # Find containing paragraph layout
4002 parent = get_containing_layout(document.body, i)
4004 document.warning("Malformed LyX document: Can't find parent paragraph layout")
4009 realparbeg = parent[3]
4010 layoutname = parent[0]
4012 for p in range(parbeg, parend):
4016 if layoutname in list_layouts:
4017 m = rx.match(document.body[p])
4020 if argnr == "item:1":
4021 j = find_end_of_inset(document.body, i)
4022 # Find containing paragraph layout
4023 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
4024 endPlain = find_end_of_layout(document.body, beginPlain)
4025 content = document.body[beginPlain + 1 : endPlain]
4026 del document.body[i:j+1]
4027 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
4028 document.body[realparbeg : realparbeg] = subst
4029 elif argnr == "item:2":
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
4042 def revert_powerdot_columns(document):
4043 " Reverts powerdot twocolumn to TeX-code "
4044 if document.textclass != "powerdot":
4047 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
4050 i = find_token(document.body, "\\begin_layout Twocolumn", i)
4053 j = find_end_of_layout(document.body, i)
4055 document.warning("Malformed LyX document: Can't find end of Twocolumn layout")
4059 document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
4060 endlay += len(put_cmd_in_ert("}"))
4061 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\twocolumn")
4062 for p in range(i, j):
4065 m = rx.match(document.body[p])
4069 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
4070 endPlain = find_end_of_layout(document.body, beginPlain)
4071 endInset = find_end_of_inset(document.body, p)
4072 content = document.body[beginPlain + 1 : endPlain]
4074 endlay = endlay - len(document.body[p : endInset + 1])
4076 del document.body[p : endInset + 1]
4077 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
4079 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
4080 endPlain = find_end_of_layout(document.body, beginPlain)
4081 endInset = find_end_of_inset(document.body, p)
4082 content = document.body[beginPlain + 1 : endPlain]
4084 endlay = endlay - len(document.body[p : endInset + 1])
4086 del document.body[p : endInset + 1]
4087 subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
4089 subst += put_cmd_in_ert("{")
4090 document.body[i : i + 1] = subst
4094 def revert_mbox_fbox(document):
4095 'Convert revert mbox/fbox boxes to TeX-code'
4098 i = find_token(document.body, "\\begin_inset Box", i)
4101 j = find_token(document.body, "width", i)
4103 document.warning("Malformed LyX document: Can't find box width")
4105 width = get_value(document.body, "width", j)
4106 k = find_end_of_inset(document.body, j)
4108 document.warning("Malformed LyX document: Can't find end of box inset")
4111 BeginLayout = find_token(document.body, "\\begin_layout Plain Layout", j)
4112 EndLayout = find_token(document.body, "\\end_layout", BeginLayout)
4113 # replace if width is ""
4115 document.body[EndLayout:k + 1] = put_cmd_in_ert("}")
4116 if document.body[i] == "\\begin_inset Box Frameless":
4117 document.body[i:BeginLayout + 1] = put_cmd_in_ert("\\mbox{")
4118 if document.body[i] == "\\begin_inset Box Boxed":
4119 document.body[i:BeginLayout + 1] = put_cmd_in_ert("\\fbox{")
4123 def revert_starred_caption(document):
4124 " Reverts unnumbered longtable caption insets "
4128 i = find_token(document.body, "\\begin_inset Caption LongTableNoNumber", i)
4131 # This is not equivalent, but since the caption inset is a full blown
4132 # text inset a true conversion to ERT is too difficult.
4133 document.body[i] = "\\begin_inset Caption Standard"
4137 def revert_forced_local_layout(document):
4140 i = find_token(document.header, "\\begin_forced_local_layout", i)
4143 j = find_end_of(document.header, i, "\\begin_forced_local_layout", "\\end_forced_local_layout")
4145 # this should not happen
4147 regexp = re.compile(r'\s*forcelocal', re.IGNORECASE)
4148 k = find_re(document.header, regexp, i, j)
4150 del document.header[k]
4152 k = find_re(document.header, regexp, i, j)
4153 k = find_token(document.header, "\\begin_local_layout", 0)
4155 document.header[i] = "\\begin_local_layout"
4156 document.header[j] = "\\end_local_layout"
4158 l = find_end_of(document.header, k, "\\begin_local_layout", "\\end_local_layout")
4160 # this should not happen
4162 lines = document.header[i+1 : j]
4164 document.header[k+1 : k+1] = lines
4165 document.header[i : j ] = []
4167 document.header[i : j ] = []
4168 document.header[k+1 : k+1] = lines
4171 def revert_aa1(document):
4172 " Reverts InsetArguments of aa to TeX-code "
4173 if document.textclass == "aa":
4177 i = find_token(document.body, "\\begin_layout Abstract (structured)", i)
4179 revert_Argument_to_TeX_brace(document, i, 0, 1, 4, False, False)
4185 def revert_aa2(document):
4186 " Reverts InsetArguments of aa to TeX-code "
4187 if document.textclass == "aa":
4191 i = find_token(document.body, "\\begin_layout Abstract (structured)", i)
4193 document.body[i] = "\\begin_layout Abstract"
4199 def revert_tibetan(document):
4200 "Set the document language for Tibetan to English"
4202 if document.language == "tibetan":
4203 document.language = "english"
4204 i = find_token(document.header, "\\language", 0)
4206 document.header[i] = "\\language english"
4208 while j < len(document.body):
4209 j = find_token(document.body, "\\lang tibetan", j)
4211 document.body[j] = document.body[j].replace("\\lang tibetan", "\\lang english")
4214 j = len(document.body)
4223 # The idea here is that we will have a sequence of chunk paragraphs.
4224 # We want to convert them to paragraphs in one or several chunk insets.
4225 # Individual chunks are terminated by the character @ on the last line.
4226 # This line will be discarded, and following lines are treated as new
4227 # chunks, which go into their own insets.
4228 # The first line of a chunk should look like: <<CONTENT>>=
4229 # We will discard the delimiters, and put the CONTENT into the
4230 # optional argument of the inset, if the CONTENT is non-empty.
4231 def convert_chunks(document):
4232 first_re = re.compile(r'<<(.*)>>=(.*)')
4235 # find start of a block of chunks
4236 i = find_token(document.body, "\\begin_layout Chunk", file_pos)
4242 chunk_started = False
4245 # process the one we just found
4246 j = find_end_of_layout(document.body, i)
4248 document.warning("Malformed LyX documents. Can't find end of Chunk layout!")
4249 # there is no point continuing, as we will run into the same error again.
4251 this_chunk = "".join(document.body[i + 1:j])
4253 # there may be empty lines between chunks
4254 # we just skip them.
4255 if not chunk_started:
4256 if this_chunk != "":
4258 chunk_started = True
4261 contents.append(document.body[i + 1:j])
4263 # look for potential chunk terminator
4264 # on the last line of the chunk paragraph
4265 if document.body[j - 1] == "@":
4268 # look for subsequent chunk paragraph
4269 i = find_token(document.body, "\\begin_layout", j)
4273 if get_value(document.body, "\\begin_layout", i) != "Chunk":
4276 file_pos = end = j + 1
4278 # The last chunk should simply have an "@" in it
4279 # or at least end with "@" (can happen if @ is
4280 # preceded by a newline)
4281 lastpar = ''.join(contents[-1])
4282 if not lastpar.endswith("@"):
4283 document.warning("Unexpected chunk content: chunk not terminated by '@'!")
4287 # chunk par only contains "@". Just drop it.
4290 # chunk par contains more. Only drop the "@".
4293 # The first line should look like: <<CONTENT>>=
4294 # We want the CONTENT
4295 optarg = ' '.join(contents[0])
4297 # We can already have real chunk content in
4298 # the first par (separated from the options by a newline).
4299 # We collect such stuff to re-insert it later.
4302 match = first_re.search(optarg)
4304 optarg = match.groups()[0]
4305 if match.groups()[1] != "":
4307 for c in contents[0]:
4308 if c.endswith(">>="):
4312 postoptstuff.append(c)
4313 # We have stripped everything. This can be deleted.
4316 newstuff = ['\\begin_layout Standard',
4317 '\\begin_inset Flex Chunk',
4319 '\\begin_layout Plain Layout', '']
4321 # If we have a non-empty optional argument, insert it.
4322 if match and optarg != "":
4324 ['\\begin_inset Argument 1',
4326 '\\begin_layout Plain Layout',
4331 # Since we already opened a Plain layout, the first paragraph
4332 # does not need to do that.
4335 newstuff.extend(postoptstuff)
4336 newstuff.append('\\end_layout')
4340 newstuff.extend(['', '\\begin_layout Plain Layout', ''])
4344 newstuff.append('\\end_layout')
4346 newstuff.extend(['', '\\end_inset', '', '\\end_layout', ''])
4348 document.body[start:end] = newstuff
4350 file_pos += len(newstuff) - (end - start)
4353 def revert_chunks(document):
4356 i = find_token(document.body, "\\begin_inset Flex Chunk", i)
4360 iend = find_end_of_inset(document.body, i)
4362 document.warning("Can't find end of Chunk!")
4366 # Look for optional argument
4368 ostart = find_token(document.body, "\\begin_inset Argument 1", i, iend)
4370 oend = find_end_of_inset(document.body, ostart)
4371 k = find_token(document.body, "\\begin_layout Plain Layout", ostart, oend)
4373 document.warning("Malformed LyX document: Can't find argument contents!")
4375 m = find_end_of_layout(document.body, k)
4376 optarg = "".join(document.body[k+1:m])
4379 # We now remove the optional argument, so we have something
4380 # uniform on which to work
4381 document.body[ostart : oend + 1] = []
4382 # iend is now invalid
4383 iend = find_end_of_inset(document.body, i)
4385 retval = get_containing_layout(document.body, i)
4387 document.warning("Can't find containing layout for Chunk!")
4390 (lname, lstart, lend, pstart) = retval
4391 # we now want to work through the various paragraphs, and collect their contents
4395 k = find_token(document.body, "\\begin_layout Plain Layout", k, lend)
4398 j = find_end_of_layout(document.body, k)
4400 document.warning("Can't find end of layout inside chunk!")
4402 parlist.append(document.body[k+1:j])
4404 # we now need to wrap all of these paragraphs in chunks
4407 newlines.extend(["\\begin_layout Chunk", "", "<<" + optarg + ">>=", "\\end_layout", ""])
4408 for stuff in parlist:
4409 newlines.extend(["\\begin_layout Chunk"] + stuff + ["\\end_layout", ""])
4410 newlines.extend(["\\begin_layout Chunk", "", "@", "\\end_layout", ""])
4411 # replace old content with new content
4412 document.body[lstart : lend + 1] = newlines
4413 i = lstart + len(newlines)
4420 supported_versions = ["2.1.0","2.1"]
4423 [415, [convert_undertilde]],
4425 [417, [convert_japanese_encodings]],
4428 [420, [convert_biblio_style]],
4429 [421, [convert_longtable_captions]],
4430 [422, [convert_use_packages]],
4431 [423, [convert_use_mathtools]],
4432 [424, [convert_cite_engine_type]],
4436 [428, [convert_cell_rotation]],
4437 [429, [convert_table_rotation]],
4438 [430, [convert_listoflistings]],
4439 [431, [convert_use_amssymb]],
4441 [433, [convert_armenian]],
4449 [441, [convert_mdnomath]],
4454 [446, [convert_latexargs]],
4455 [447, [convert_IEEEtran, convert_AASTeX, convert_AGUTeX, convert_IJMP, convert_SIGPLAN, convert_SIGGRAPH, convert_EuropeCV, convert_Initials, convert_ModernCV]],
4456 [448, [convert_literate]],
4459 [451, [convert_beamerargs, convert_againframe_args, convert_corollary_args, convert_quote_args]],
4460 [452, [convert_beamerblocks]],
4461 [453, [convert_use_stmaryrd]],
4462 [454, [convert_overprint]],
4464 [456, [convert_epigraph]],
4465 [457, [convert_use_stackrel]],
4466 [458, [convert_captioninsets, convert_captionlayouts]],
4471 [463, [convert_encodings]],
4472 [464, [convert_use_cancel]],
4473 [465, [convert_lyxframes, remove_endframes]],
4479 [471, [convert_cite_engine_type_default]],
4482 [474, [convert_chunks]],
4486 [473, [revert_chunks]],
4487 [472, [revert_tibetan]],
4488 [471, [revert_aa1,revert_aa2]],
4489 [470, [revert_cite_engine_type_default]],
4490 [469, [revert_forced_local_layout]],
4491 [468, [revert_starred_caption]],
4492 [467, [revert_mbox_fbox]],
4493 [466, [revert_iwona_fonts]],
4494 [465, [revert_powerdot_flexes, revert_powerdot_pause, revert_powerdot_itemargs, revert_powerdot_columns]],
4496 [463, [revert_use_cancel]],
4497 [462, [revert_encodings]],
4498 [461, [revert_new_libertines]],
4499 [460, [revert_kurier_fonts]],
4500 [459, [revert_IEEEtran_3]],
4501 [458, [revert_fragileframe, revert_newframes]],
4502 [457, [revert_captioninsets, revert_captionlayouts]],
4503 [456, [revert_use_stackrel]],
4504 [455, [revert_epigraph]],
4505 [454, [revert_frametitle]],
4506 [453, [revert_overprint]],
4507 [452, [revert_use_stmaryrd]],
4508 [451, [revert_beamerblocks]],
4509 [450, [revert_beamerargs, revert_beamerargs2, revert_beamerargs3, revert_beamerflex]],
4510 [449, [revert_garamondx, revert_garamondx_newtxmath]],
4511 [448, [revert_itemargs]],
4512 [447, [revert_literate]],
4513 [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]],
4514 [445, [revert_latexargs]],
4515 [444, [revert_uop]],
4516 [443, [revert_biolinum]],
4518 [441, [revert_newtxmath]],
4519 [440, [revert_mdnomath]],
4520 [439, [revert_mathfonts]],
4521 [438, [revert_minionpro]],
4522 [437, [revert_ipadeco, revert_ipachar]],
4523 [436, [revert_texgyre]],
4524 [435, [revert_mathdesign]],
4525 [434, [revert_txtt]],
4526 [433, [revert_libertine]],
4527 [432, [revert_armenian]],
4528 [431, [revert_languages, revert_ancientgreek]],
4529 [430, [revert_use_amssymb]],
4530 [429, [revert_listoflistings]],
4531 [428, [revert_table_rotation]],
4532 [427, [revert_cell_rotation]],
4533 [426, [revert_tipa]],
4534 [425, [revert_verbatim]],
4535 [424, [revert_cancel]],
4536 [423, [revert_cite_engine_type]],
4537 [422, [revert_use_mathtools]],
4538 [421, [revert_use_packages]],
4539 [420, [revert_longtable_captions]],
4540 [419, [revert_biblio_style]],
4541 [418, [revert_australian]],
4542 [417, [revert_justification]],
4543 [416, [revert_japanese_encodings]],
4544 [415, [revert_negative_space, revert_math_spaces]],
4545 [414, [revert_undertilde]],
4546 [413, [revert_visible_space]]
4550 if __name__ == "__main__":