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 collapsed', '',
745 '\\begin_layout Plain Layout', '', '', '\\backslash',
747 '\\end_layout', '', '\\begin_layout Plain Layout', '']
749 i = find_token(document.body, "\\begin_layout Verbatim", i)
752 j = find_end_of_layout(document.body, i)
754 document.warning("Malformed LyX document: Can't find end of Verbatim layout")
757 # delete all line breaks insets (there are no other insets)
760 n = find_token(document.body, "\\begin_inset Newline newline", l)
762 n = find_token(document.body, "\\begin_inset Newline linebreak", l)
765 m = find_end_of_inset(document.body, n)
766 del(document.body[m:m+1])
767 document.body[n:n+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
770 # consecutive verbatim environments need to be connected
771 k = find_token(document.body, "\\begin_layout Verbatim", j)
772 if k == j + 2 and consecutive == False:
774 document.body[j:j+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
775 document.body[i:i+1] = subst_begin
777 if k == j + 2 and consecutive == True:
778 document.body[j:j+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
779 del(document.body[i:i+1])
781 if k != j + 2 and consecutive == True:
782 document.body[j:j+1] = subst_end
783 # the next paragraph must not be indented
784 document.body[j+19:j+19] = ['\\noindent']
785 del(document.body[i:i+1])
789 document.body[j:j+1] = subst_end
790 # the next paragraph must not be indented
791 document.body[j+19:j+19] = ['\\noindent']
792 document.body[i:i+1] = subst_begin
795 def revert_tipa(document):
796 " Revert native TIPA insets to mathed or ERT. "
799 i = find_token(document.body, "\\begin_inset IPA", i)
802 j = find_end_of_inset(document.body, i)
804 document.warning("Malformed LyX document: Can't find end of IPA inset")
808 n = find_token(document.body, "\\begin_layout", i, j)
810 document.warning("Malformed LyX document: IPA inset has no embedded layout")
813 m = find_end_of_layout(document.body, n)
815 document.warning("Malformed LyX document: Can't find end of embedded layout")
818 content = document.body[n+1:m]
819 p = find_token(document.body, "\\begin_layout", m, j)
820 if p != -1 or len(content) > 1:
822 content = document.body[i+1:j]
824 # IPA insets with multiple pars need to be wrapped by \begin{IPA}...\end{IPA}
825 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}")
826 add_to_preamble(document, ["\\usepackage{tipa,tipx}"])
828 # single-par IPA insets can be reverted to mathed
829 document.body[i:j+1] = ["\\begin_inset Formula $\\text{\\textipa{" + content[0] + "}}$", "\\end_inset"]
833 def revert_cell_rotation(document):
834 "Revert cell rotations to TeX-code"
836 load_rotating = False
840 # first, let's find out if we need to do anything
841 i = find_token(document.body, '<cell ', i)
844 j = document.body[i].find('rotate="')
846 k = document.body[i].find('"', j + 8)
847 value = document.body[i][j + 8 : k]
849 rgx = re.compile(r' rotate="[^"]+?"')
850 # remove rotate option
851 document.body[i] = rgx.sub('', document.body[i])
853 rgx = re.compile(r' rotate="[^"]+?"')
854 document.body[i] = rgx.sub('rotate="true"', document.body[i])
856 rgx = re.compile(r' rotate="[^"]+?"')
858 # remove rotate option
859 document.body[i] = rgx.sub('', document.body[i])
861 document.body[i + 5 : i + 5] = \
862 put_cmd_in_ert("\\end{turn}")
863 document.body[i + 4 : i + 4] = \
864 put_cmd_in_ert("\\begin{turn}{" + value + "}")
870 add_to_preamble(document, ["\\@ifundefined{turnbox}{\usepackage{rotating}}{}"])
873 def convert_cell_rotation(document):
874 'Convert cell rotation statements from "true" to "90"'
878 # first, let's find out if we need to do anything
879 i = find_token(document.body, '<cell ', i)
882 j = document.body[i].find('rotate="true"')
884 rgx = re.compile(r'rotate="[^"]+?"')
885 # convert "true" to "90"
886 document.body[i] = rgx.sub('rotate="90"', document.body[i])
891 def revert_table_rotation(document):
892 "Revert table rotations to TeX-code"
894 load_rotating = False
898 # first, let's find out if we need to do anything
899 i = find_token(document.body, '<features ', i)
902 j = document.body[i].find('rotate="')
904 end_table = find_token(document.body, '</lyxtabular>', j)
905 k = document.body[i].find('"', j + 8)
906 value = document.body[i][j + 8 : k]
908 rgx = re.compile(r' rotate="[^"]+?"')
909 # remove rotate option
910 document.body[i] = rgx.sub('', document.body[i])
912 rgx = re.compile(r'rotate="[^"]+?"')
913 document.body[i] = rgx.sub('rotate="true"', document.body[i])
915 rgx = re.compile(r' rotate="[^"]+?"')
917 # remove rotate option
918 document.body[i] = rgx.sub('', document.body[i])
920 document.body[end_table + 3 : end_table + 3] = \
921 put_cmd_in_ert("\\end{turn}")
922 document.body[i - 2 : i - 2] = \
923 put_cmd_in_ert("\\begin{turn}{" + value + "}")
929 add_to_preamble(document, ["\\@ifundefined{turnbox}{\usepackage{rotating}}{}"])
932 def convert_table_rotation(document):
933 'Convert table rotation statements from "true" to "90"'
937 # first, let's find out if we need to do anything
938 i = find_token(document.body, '<features ', i)
941 j = document.body[i].find('rotate="true"')
943 rgx = re.compile(r'rotate="[^"]+?"')
944 # convert "true" to "90"
945 document.body[i] = rgx.sub('rotate="90"', document.body[i])
950 def convert_listoflistings(document):
951 'Convert ERT \lstlistoflistings to TOC lstlistoflistings inset'
952 # We can support roundtrip because the command is so simple
955 i = find_token(document.body, "\\begin_inset ERT", i)
958 j = find_end_of_inset(document.body, i)
960 document.warning("Malformed LyX document: Can't find end of ERT inset")
963 ert = get_ert(document.body, i)
964 if ert == "\\lstlistoflistings{}":
965 document.body[i:j] = ["\\begin_inset CommandInset toc", "LatexCommand lstlistoflistings", ""]
971 def revert_listoflistings(document):
972 'Convert TOC lstlistoflistings inset to ERT lstlistoflistings'
975 i = find_token(document.body, "\\begin_inset CommandInset toc", i)
978 if document.body[i+1] == "LatexCommand lstlistoflistings":
979 j = find_end_of_inset(document.body, i)
981 document.warning("Malformed LyX document: Can't find end of TOC inset")
984 subst = put_cmd_in_ert("\\lstlistoflistings{}")
985 document.body[i:j+1] = subst
986 add_to_preamble(document, ["\\usepackage{listings}"])
990 def convert_use_amssymb(document):
991 "insert use_package amssymb"
992 regexp = re.compile(r'(\\use_package\s+amsmath)')
993 i = find_re(document.header, regexp, 0)
995 document.warning("Malformed LyX document: Can't find \\use_package amsmath.")
997 value = get_value(document.header, "\\use_package" , i).split()[1]
1000 useamsmath = int(value)
1002 document.warning("Invalid \\use_package amsmath: " + value + ". Assuming auto.")
1004 j = find_token(document.preamble, "\\usepackage{amssymb}", 0)
1006 document.header.insert(i + 1, "\\use_package amssymb %d" % useamsmath)
1008 document.header.insert(i + 1, "\\use_package amssymb 2")
1009 del document.preamble[j]
1012 def revert_use_amssymb(document):
1013 "remove use_package amssymb"
1014 regexp1 = re.compile(r'(\\use_package\s+amsmath)')
1015 regexp2 = re.compile(r'(\\use_package\s+amssymb)')
1016 i = find_re(document.header, regexp1, 0)
1017 j = find_re(document.header, regexp2, 0)
1018 value1 = "1" # default is auto
1019 value2 = "1" # default is auto
1021 value1 = get_value(document.header, "\\use_package" , i).split()[1]
1023 value2 = get_value(document.header, "\\use_package" , j).split()[1]
1024 del document.header[j]
1025 if value1 != value2 and value2 == "2": # on
1026 add_to_preamble(document, ["\\usepackage{amssymb}"])
1029 def convert_use_cancel(document):
1030 "insert use_package cancel"
1031 convert_use_package(document, "cancel")
1034 def revert_use_cancel(document):
1035 "remove use_package cancel"
1036 commands = ["cancel", "bcancel", "xcancel", "cancelto"]
1037 revert_use_package(document, "cancel", commands, True)
1040 def revert_ancientgreek(document):
1041 "Set the document language for ancientgreek to greek"
1043 if document.language == "ancientgreek":
1044 document.language = "greek"
1045 i = find_token(document.header, "\\language", 0)
1047 document.header[i] = "\\language greek"
1050 j = find_token(document.body, "\\lang ancientgreek", j)
1054 document.body[j] = document.body[j].replace("\\lang ancientgreek", "\\lang greek")
1058 def revert_languages(document):
1059 "Set the document language for new supported languages to English"
1062 "coptic", "divehi", "hindi", "kurmanji", "lao", "marathi", "occitan", "sanskrit",
1063 "syriac", "tamil", "telugu", "urdu"
1065 for n in range(len(languages)):
1066 if document.language == languages[n]:
1067 document.language = "english"
1068 i = find_token(document.header, "\\language", 0)
1070 document.header[i] = "\\language english"
1072 while j < len(document.body):
1073 j = find_token(document.body, "\\lang " + languages[n], j)
1075 document.body[j] = document.body[j].replace("\\lang " + languages[n], "\\lang english")
1078 j = len(document.body)
1081 def convert_armenian(document):
1082 "Use polyglossia and thus non-TeX fonts for Armenian"
1084 if document.language == "armenian":
1085 i = find_token(document.header, "\\use_non_tex_fonts", 0)
1087 document.header[i] = "\\use_non_tex_fonts true"
1090 def revert_armenian(document):
1091 "Use ArmTeX and thus TeX fonts for Armenian"
1093 if document.language == "armenian":
1094 i = find_token(document.header, "\\use_non_tex_fonts", 0)
1096 document.header[i] = "\\use_non_tex_fonts false"
1099 def revert_libertine(document):
1100 " Revert native libertine font definition to LaTeX "
1102 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1103 i = find_token(document.header, "\\font_roman libertine", 0)
1106 j = find_token(document.header, "\\font_osf true", 0)
1109 preamble = "\\usepackage"
1111 document.header[j] = "\\font_osf false"
1114 preamble += "[lining]"
1115 preamble += "{libertine-type1}"
1116 add_to_preamble(document, [preamble])
1117 document.header[i] = "\\font_roman default"
1120 def revert_txtt(document):
1121 " Revert native txtt font definition to LaTeX "
1123 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1124 i = find_token(document.header, "\\font_typewriter txtt", 0)
1126 preamble = "\\renewcommand{\\ttdefault}{txtt}"
1127 add_to_preamble(document, [preamble])
1128 document.header[i] = "\\font_typewriter default"
1131 def revert_mathdesign(document):
1132 " Revert native mathdesign font definition to LaTeX "
1134 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1140 i = find_token(document.header, "\\font_roman", 0)
1143 val = get_value(document.header, "\\font_roman", i)
1144 if val in mathdesign_dict.keys():
1145 preamble = "\\usepackage[%s" % mathdesign_dict[val]
1147 j = find_token(document.header, "\\font_osf true", 0)
1150 document.header[j] = "\\font_osf false"
1151 l = find_token(document.header, "\\font_sc true", 0)
1154 document.header[l] = "\\font_sc false"
1156 preamble += ",expert"
1157 preamble += "]{mathdesign}"
1158 add_to_preamble(document, [preamble])
1159 document.header[i] = "\\font_roman default"
1162 def revert_texgyre(document):
1163 " Revert native TeXGyre font definition to LaTeX "
1165 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1166 texgyre_fonts = ["tgadventor", "tgbonum", "tgchorus", "tgcursor", \
1167 "tgheros", "tgpagella", "tgschola", "tgtermes"]
1168 i = find_token(document.header, "\\font_roman", 0)
1170 val = get_value(document.header, "\\font_roman", i)
1171 if val in texgyre_fonts:
1172 preamble = "\\usepackage{%s}" % val
1173 add_to_preamble(document, [preamble])
1174 document.header[i] = "\\font_roman default"
1175 i = find_token(document.header, "\\font_sans", 0)
1177 val = get_value(document.header, "\\font_sans", i)
1178 if val in texgyre_fonts:
1179 preamble = "\\usepackage{%s}" % val
1180 add_to_preamble(document, [preamble])
1181 document.header[i] = "\\font_sans default"
1182 i = find_token(document.header, "\\font_typewriter", 0)
1184 val = get_value(document.header, "\\font_typewriter", i)
1185 if val in texgyre_fonts:
1186 preamble = "\\usepackage{%s}" % val
1187 add_to_preamble(document, [preamble])
1188 document.header[i] = "\\font_typewriter default"
1191 def revert_ipadeco(document):
1192 " Revert IPA decorations to ERT "
1195 i = find_token(document.body, "\\begin_inset IPADeco", i)
1198 end = find_end_of_inset(document.body, i)
1200 document.warning("Can't find end of inset at line " + str(i))
1203 line = document.body[i]
1204 rx = re.compile(r'\\begin_inset IPADeco (.*)$')
1206 decotype = m.group(1)
1207 if decotype != "toptiebar" and decotype != "bottomtiebar":
1208 document.warning("Invalid IPADeco type: " + decotype)
1211 blay = find_token(document.body, "\\begin_layout Plain Layout", i, end)
1213 document.warning("Can't find layout for inset at line " + str(i))
1216 bend = find_end_of_layout(document.body, blay)
1218 document.warning("Malformed LyX document: Could not find end of IPADeco inset's layout.")
1221 substi = ["\\begin_inset ERT", "status collapsed", "",
1222 "\\begin_layout Plain Layout", "", "", "\\backslash",
1223 decotype + "{", "\\end_layout", "", "\\end_inset"]
1224 substj = ["\\size default", "", "\\begin_inset ERT", "status collapsed", "",
1225 "\\begin_layout Plain Layout", "", "}", "\\end_layout", "", "\\end_inset"]
1226 # do the later one first so as not to mess up the numbering
1227 document.body[bend:end + 1] = substj
1228 document.body[i:blay + 1] = substi
1229 i = end + len(substi) + len(substj) - (end - bend) - (blay - i) - 2
1230 add_to_preamble(document, "\\usepackage{tipa}")
1233 def revert_ipachar(document):
1234 ' Revert \\IPAChar to ERT '
1237 while i < len(document.body):
1238 m = re.match(r'(.*)\\IPAChar \\(\w+\{\w+\})(.*)', document.body[i])
1242 ipachar = m.group(2)
1245 '\\begin_inset ERT',
1246 'status collapsed', '',
1247 '\\begin_layout Standard',
1248 '', '', '\\backslash',
1253 document.body[i: i+1] = subst
1258 add_to_preamble(document, "\\usepackage{tone}")
1261 def revert_minionpro(document):
1262 " Revert native MinionPro font definition to LaTeX "
1264 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1265 i = find_token(document.header, "\\font_roman minionpro", 0)
1268 j = find_token(document.header, "\\font_osf true", 0)
1271 preamble = "\\usepackage"
1273 document.header[j] = "\\font_osf false"
1276 preamble += "{MinionPro}"
1277 add_to_preamble(document, [preamble])
1278 document.header[i] = "\\font_roman default"
1281 def revert_mathfonts(document):
1282 " Revert native math font definitions to LaTeX "
1284 i = find_token(document.header, "\\font_math", 0)
1287 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1288 val = get_value(document.header, "\\font_math", i)
1289 if val == "eulervm":
1290 add_to_preamble(document, "\\usepackage{eulervm}")
1291 elif val == "default":
1293 "lmodern": "\\renewcommand{\\rmdefault}{lmr}",
1294 "minionpro": "\\usepackage[onlytext,lf]{MinionPro}",
1295 "minionpro-osf": "\\usepackage[onlytext]{MinionPro}",
1296 "palatino": "\\renewcommand{\\rmdefault}{ppl}",
1297 "palatino-osf": "\\renewcommand{\\rmdefault}{pplj}",
1298 "times": "\\renewcommand{\\rmdefault}{ptm}",
1299 "utopia": "\\renewcommand{\\rmdefault}{futs}",
1300 "utopia-osf": "\\renewcommand{\\rmdefault}{futj}",
1302 j = find_token(document.header, "\\font_roman", 0)
1304 rm = get_value(document.header, "\\font_roman", j)
1305 k = find_token(document.header, "\\font_osf true", 0)
1308 if rm in mathfont_dict.keys():
1309 add_to_preamble(document, mathfont_dict[rm])
1310 document.header[j] = "\\font_roman default"
1312 document.header[k] = "\\font_osf false"
1313 del document.header[i]
1316 def revert_mdnomath(document):
1317 " Revert mathdesign and fourier without math "
1319 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1321 "md-charter": "mdbch",
1322 "md-utopia": "mdput",
1323 "md-garamond": "mdugm"
1325 i = find_token(document.header, "\\font_roman", 0)
1328 val = get_value(document.header, "\\font_roman", i)
1329 if val in mathdesign_dict.keys():
1330 j = find_token(document.header, "\\font_math", 0)
1332 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1333 mval = get_value(document.header, "\\font_math", j)
1334 if mval == "default":
1335 document.header[i] = "\\font_roman default"
1336 add_to_preamble(document, "\\renewcommand{\\rmdefault}{%s}" % mathdesign_dict[val])
1338 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1341 def convert_mdnomath(document):
1342 " Change mathdesign font name "
1344 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1346 "mdbch": "md-charter",
1347 "mdput": "md-utopia",
1348 "mdugm": "md-garamond"
1350 i = find_token(document.header, "\\font_roman", 0)
1353 val = get_value(document.header, "\\font_roman", i)
1354 if val in mathdesign_dict.keys():
1355 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1358 def revert_newtxmath(document):
1359 " Revert native newtxmath definitions to LaTeX "
1361 i = find_token(document.header, "\\font_math", 0)
1364 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1365 val = get_value(document.header, "\\font_math", i)
1367 "libertine-ntxm": "\\usepackage[libertine]{newtxmath}",
1368 "minion-ntxm": "\\usepackage[minion]{newtxmath}",
1369 "newtxmath": "\\usepackage{newtxmath}",
1371 if val in mathfont_dict.keys():
1372 add_to_preamble(document, mathfont_dict[val])
1373 document.header[i] = "\\font_math auto"
1376 def revert_biolinum(document):
1377 " Revert native biolinum font definition to LaTeX "
1379 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1380 i = find_token(document.header, "\\font_sans biolinum", 0)
1383 j = find_token(document.header, "\\font_osf true", 0)
1386 preamble = "\\usepackage"
1389 preamble += "{biolinum-type1}"
1390 add_to_preamble(document, [preamble])
1391 document.header[i] = "\\font_sans default"
1394 def revert_uop(document):
1395 " Revert native URW Classico (Optima) font definition to LaTeX "
1397 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1398 i = find_token(document.header, "\\font_sans uop", 0)
1400 preamble = "\\renewcommand{\\sfdefault}{uop}"
1401 add_to_preamble(document, [preamble])
1402 document.header[i] = "\\font_sans default"
1405 def convert_latexargs(document):
1406 " Convert InsetArgument to new syntax "
1408 if find_token(document.body, "\\begin_inset Argument", 0) == -1:
1412 # A list of layouts (document classes) with only optional or no arguments.
1413 # These can be safely converted to the new syntax
1414 # (I took the liberty to add some of my personal layouts/modules here; JSP)
1415 safe_layouts = ["aa", "aapaper", "aastex", "achemso", "acmsiggraph", "AEA",
1416 "agu-dtd", "agums", "agutex", "amsart", "amsbook", "apa",
1417 "arab-article", "armenian-article", "article-beamer", "article",
1418 "beamer", "book", "broadway", "chess", "cl2emult", "ctex-article",
1419 "ctex-book", "ctex-report", "dinbrief", "docbook-book", "docbook-chapter",
1420 "docbook", "docbook-section", "doublecol-new", "dtk", "ectaart", "egs",
1421 "elsarticle", "elsart", "entcs", "europecv", "extarticle", "extbook",
1422 "extletter", "extreport", "foils", "frletter", "g-brief2", "g-brief",
1423 "heb-article", "heb-letter", "hollywood", "IEEEtran", "ijmpc", "ijmpd",
1424 "iopart", "isprs", "jarticle", "jasatex", "jbook", "jgrga", "jreport",
1425 "jsarticle", "jsbeamer", "jsbook", "jss", "kluwer", "latex8", "letter", "lettre",
1426 "literate-article", "literate-book", "literate-report", "llncs", "ltugboat",
1427 "memoir", "moderncv", "mwart", "mwbk", "mwrep", "paper", "powerdot",
1428 "recipebook", "report", "revtex4", "revtex", "scrartcl", "scrarticle-beamer",
1429 "scrbook", "scrlettr", "scrlttr2", "scrreprt", "seminar", "siamltex",
1430 "sigplanconf", "simplecv", "singlecol", "singlecol-new", "slides", "spie",
1431 "svglobal3", "svglobal", "svjog", "svmono", "svmult", "svprobth", "tarticle",
1432 "tbook", "treport", "tufte-book", "tufte-handout"]
1433 # A list of "safe" modules, same as above
1434 safe_modules = ["biblatex", "beameraddons", "beamersession", "braille", "customHeadersFooters",
1435 "endnotes", "enumitem", "eqs-within-sections", "figs-within-sections", "fix-cm",
1436 "fixltx2e", "foottoend", "hanging", "jscharstyles", "knitr", "lilypond",
1437 "linguistics", "linguisticx", "logicalmkup", "minimalistic", "nomindex", "noweb",
1438 "pdfcomment", "sweave", "tabs-within-sections", "theorems-ams-bytype",
1439 "theorems-ams-extended-bytype", "theorems-ams-extended", "theorems-ams", "theorems-bytype",
1440 "theorems-chap-bytype", "theorems-chap", "theorems-named", "theorems-sec-bytype",
1441 "theorems-sec", "theorems-starred", "theorems-std", "todonotes"]
1442 # Modules we need to take care of
1443 caveat_modules = ["initials"]
1444 # information about the relevant styles in caveat_modules (number of opt and req args)
1445 # use this if we get more caveat_modules. For now, use hard coding (see below).
1446 # initials = [{'Layout' : 'Initial', 'opt' : 1, 'req' : 1}]
1448 # Is this a known safe layout?
1449 safe_layout = document.textclass in safe_layouts
1451 document.warning("Lyx2lyx knows nothing about textclass '%s'. "
1452 "Please check if short title insets have been converted correctly."
1453 % document.textclass)
1454 # Do we use unsafe or unknown modules
1455 mods = document.get_module_list()
1456 unknown_modules = False
1457 used_caveat_modules = list()
1459 if mod in safe_modules:
1461 if mod in caveat_modules:
1462 used_caveat_modules.append(mod)
1464 unknown_modules = True
1465 document.warning("Lyx2lyx knows nothing about module '%s'. "
1466 "Please check if short title insets have been converted correctly."
1471 i = find_token(document.body, "\\begin_inset Argument", i)
1475 if not safe_layout or unknown_modules:
1476 # We cannot do more here since we have no access to this layout.
1477 # InsetArgument itself will do the real work
1478 # (see InsetArgument::updateBuffer())
1479 document.body[i] = "\\begin_inset Argument 999"
1483 # Find containing paragraph layout
1484 parent = get_containing_layout(document.body, i)
1486 document.warning("Malformed LyX document: Can't find parent paragraph layout")
1493 if len(used_caveat_modules) > 0:
1494 # We know for now that this must be the initials module with the Initial layout
1495 # If we get more such modules, we need some automating.
1496 if parent[0] == "Initial":
1497 # Layout has 1 opt and 1 req arg.
1498 # Count the actual arguments
1500 for p in range(parbeg, parend):
1501 if document.body[p] == "\\begin_inset Argument":
1506 # Collect all arguments in this paragraph
1508 for p in range(parbeg, parend):
1509 if document.body[p] == "\\begin_inset Argument":
1511 if allowed_opts != -1:
1512 # We have less arguments than opt + required.
1513 # required must take precedence.
1514 if argnr > allowed_opts and argnr < first_req:
1516 document.body[p] = "\\begin_inset Argument %d" % argnr
1520 def revert_latexargs(document):
1521 " Revert InsetArgument to old syntax "
1524 rx = re.compile(r'^\\begin_inset Argument (\d+)$')
1527 # Search for Argument insets
1528 i = find_token(document.body, "\\begin_inset Argument", i)
1531 m = rx.match(document.body[i])
1533 # No ID: inset already reverted
1536 # Find containing paragraph layout
1537 parent = get_containing_layout(document.body, i)
1539 document.warning("Malformed LyX document: Can't find parent paragraph layout")
1544 realparbeg = parent[3]
1545 # Collect all arguments in this paragraph
1547 for p in range(parbeg, parend):
1548 m = rx.match(document.body[p])
1550 val = int(m.group(1))
1551 j = find_end_of_inset(document.body, p)
1552 # Revert to old syntax
1553 document.body[p] = "\\begin_inset Argument"
1555 document.warning("Malformed LyX document: Can't find end of Argument inset")
1558 args[val] = document.body[p : j + 1]
1560 realparend = realparend - len(document.body[p : j + 1])
1561 # Remove arg inset at this position
1562 del document.body[p : j + 1]
1565 # Now sort the arg insets
1567 for f in sorted(args):
1570 # Insert the sorted arg insets at paragraph begin
1571 document.body[realparbeg : realparbeg] = subst
1573 i = realparbeg + 1 + len(subst)
1576 def revert_IEEEtran(document):
1578 Reverts InsetArgument of
1581 Biography without photo
1584 if document.textclass == "IEEEtran":
1591 i = find_token(document.body, "\\begin_layout Page headings", i)
1593 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1596 i2 = find_token(document.body, "\\begin_inset Flex Paragraph Start", i2)
1598 revert_Argument_to_TeX_brace(document, i2, 0, 1, 1, False, False)
1601 j = find_token(document.body, "\\begin_layout Biography without photo", j)
1603 revert_Argument_to_TeX_brace(document, j, 0, 1, 1, True, False)
1606 k = find_token(document.body, "\\begin_layout Biography", k)
1607 kA = find_token(document.body, "\\begin_layout Biography without photo", k)
1608 if k == kA and k != -1:
1612 # start with the second argument, therefore 2
1613 revert_Argument_to_TeX_brace(document, k, 0, 2, 2, True, False)
1615 if i == -1 and i2 == -1 and j == -1 and k == -1:
1619 def revert_IEEEtran_2(document):
1621 Reverts Flex Paragraph Start to TeX-code
1623 if document.textclass == "IEEEtran":
1626 begin = find_token(document.body, "\\begin_inset Flex Paragraph Start", begin)
1629 end1 = find_end_of_inset(document.body, begin)
1630 document.body[end1 - 2 : end1 + 1] = put_cmd_in_ert("}")
1631 document.body[begin : begin + 4] = put_cmd_in_ert("\\IEEEPARstart{")
1635 def convert_IEEEtran(document):
1640 Biography without photo
1643 if document.textclass == "IEEEtran":
1649 i = find_token(document.body, "\\begin_layout Page headings", i)
1651 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
1654 j = find_token(document.body, "\\begin_layout Biography without photo", j)
1656 convert_TeX_brace_to_Argument(document, j, 1, 1, False, True, False)
1659 # assure that we don't handle Biography Biography without photo
1660 k = find_token(document.body, "\\begin_layout Biography", k)
1661 kA = find_token(document.body, "\\begin_layout Biography without photo", k - 1)
1662 if k == kA and k != -1:
1666 # the argument we want to convert is the second one
1667 convert_TeX_brace_to_Argument(document, k, 2, 2, False, True, False)
1669 if i == -1 and j == -1 and k == -1:
1673 def revert_AASTeX(document):
1674 " Reverts InsetArgument of Altaffilation to TeX-code "
1675 if document.textclass == "aastex":
1678 i = find_token(document.body, "\\begin_layout Altaffilation", i)
1681 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1685 def convert_AASTeX(document):
1686 " Converts ERT of Altaffilation to InsetArgument "
1687 if document.textclass == "aastex":
1690 i = find_token(document.body, "\\begin_layout Altaffilation", i)
1693 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
1697 def revert_AGUTeX(document):
1698 " Reverts InsetArgument of Author affiliation to TeX-code "
1699 if document.textclass == "agutex":
1702 i = find_token(document.body, "\\begin_layout Author affiliation", i)
1705 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1709 def convert_AGUTeX(document):
1710 " Converts ERT of Author affiliation to InsetArgument "
1711 if document.textclass == "agutex":
1714 i = find_token(document.body, "\\begin_layout Author affiliation", i)
1717 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
1721 def revert_IJMP(document):
1722 " Reverts InsetArgument of MarkBoth to TeX-code "
1723 if document.textclass == "ijmpc" or document.textclass == "ijmpd":
1726 i = find_token(document.body, "\\begin_layout MarkBoth", i)
1729 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1733 def convert_IJMP(document):
1734 " Converts ERT of MarkBoth to InsetArgument "
1735 if document.textclass == "ijmpc" or document.textclass == "ijmpd":
1738 i = find_token(document.body, "\\begin_layout MarkBoth", i)
1741 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
1745 def revert_SIGPLAN(document):
1746 " Reverts InsetArguments of SIGPLAN to TeX-code "
1747 if document.textclass == "sigplanconf":
1752 i = find_token(document.body, "\\begin_layout Conference", i)
1754 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1757 j = find_token(document.body, "\\begin_layout Author", j)
1759 revert_Argument_to_TeX_brace(document, j, 0, 1, 2, False, False)
1761 if i == -1 and j == -1:
1765 def convert_SIGPLAN(document):
1766 " Converts ERT of SIGPLAN to InsetArgument "
1767 if document.textclass == "sigplanconf":
1772 i = find_token(document.body, "\\begin_layout Conference", i)
1774 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
1777 j = find_token(document.body, "\\begin_layout Author", j)
1779 convert_TeX_brace_to_Argument(document, j, 1, 2, False, False, False)
1781 if i == -1 and j == -1:
1785 def revert_SIGGRAPH(document):
1786 " Reverts InsetArgument of Flex CRcat to TeX-code "
1787 if document.textclass == "acmsiggraph":
1790 i = find_token(document.body, "\\begin_inset Flex CRcat", i)
1793 revert_Argument_to_TeX_brace(document, i, 0, 1, 3, False, False)
1797 def convert_SIGGRAPH(document):
1798 " Converts ERT of Flex CRcat to InsetArgument "
1799 if document.textclass == "acmsiggraph":
1802 i = find_token(document.body, "\\begin_inset Flex CRcat", i)
1805 convert_TeX_brace_to_Argument(document, i, 1, 3, True, False, False)
1809 def revert_EuropeCV(document):
1810 " Reverts InsetArguments of europeCV to TeX-code "
1811 if document.textclass == "europecv":
1818 i = find_token(document.body, "\\begin_layout Item", i)
1820 revert_Argument_to_TeX_brace(document, i, 0, 2, 2, False, False)
1823 j = find_token(document.body, "\\begin_layout BulletedItem", j)
1825 revert_Argument_to_TeX_brace(document, j, 0, 2, 2, False, False)
1828 k = find_token(document.body, "\\begin_layout Language", k)
1830 revert_Argument_to_TeX_brace(document, k, 0, 2, 6, False, False)
1833 m = find_token(document.body, "\\begin_layout LastLanguage", m)
1835 revert_Argument_to_TeX_brace(document, m, 0, 2, 6, False, False)
1837 if i == -1 and j == -1 and k == -1 and m == -1:
1841 def convert_EuropeCV(document):
1842 " Converts ERT of europeCV to InsetArgument "
1843 if document.textclass == "europecv":
1850 i = find_token(document.body, "\\begin_layout Item", i)
1852 convert_TeX_brace_to_Argument(document, i, 2, 2, False, False, False)
1855 j = find_token(document.body, "\\begin_layout BulletedItem", j)
1857 convert_TeX_brace_to_Argument(document, j, 2, 2, False, False, False)
1860 k = find_token(document.body, "\\begin_layout Language", k)
1862 convert_TeX_brace_to_Argument(document, k, 2, 6, False, False, False)
1865 m = find_token(document.body, "\\begin_layout LastLanguage", m)
1867 convert_TeX_brace_to_Argument(document, m, 2, 6, False, False, False)
1869 if i == -1 and j == -1 and k == -1 and m == -1:
1873 def revert_ModernCV(document):
1874 " Reverts InsetArguments of modernCV to TeX-code "
1875 if document.textclass == "moderncv":
1883 j = find_token(document.body, "\\begin_layout Entry", j)
1885 revert_Argument_to_TeX_brace(document, j, 0, 1, 5, False, False)
1888 k = find_token(document.body, "\\begin_layout Item", k)
1890 revert_Argument_to_TeX_brace(document, k, 0, 1, 1, False, False)
1893 m = find_token(document.body, "\\begin_layout ItemWithComment", m)
1895 revert_Argument_to_TeX_brace(document, m, 0, 1, 2, False, False)
1896 document.body[m] = document.body[m].replace("\\begin_layout ItemWithComment", "\\begin_layout Language")
1899 o = find_token(document.body, "\\begin_layout DoubleItem", o)
1901 revert_Argument_to_TeX_brace(document, o, 0, 1, 3, False, False)
1902 document.body[o] = document.body[o].replace("\\begin_layout DoubleItem", "\\begin_layout Computer")
1905 p = find_token(document.body, "\\begin_layout Social", p)
1907 revert_Argument_to_TeX_brace(document, p, 0, 1, 1, False, True)
1909 if j == -1 and k == -1 and m == -1 and o == -1 and p == -1:
1913 def revert_ModernCV_2(document):
1914 " Reverts the Flex:Column inset of modernCV to TeX-code "
1915 if document.textclass == "moderncv":
1919 flex = find_token(document.body, "\\begin_inset Flex Column", flex)
1922 flexEnd = find_end_of_inset(document.body, flex)
1923 wasOpt = revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, False, True)
1924 revert_Argument_to_TeX_brace(document, flex, 0, 2, 2, False, False)
1925 flexEnd = find_end_of_inset(document.body, flex)
1927 document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\cvcolumn")
1929 document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\cvcolumn{")
1930 document.body[flexEnd + 4 : flexEnd + 7] = put_cmd_in_ert("}")
1934 def revert_ModernCV_3(document):
1935 " Reverts the Column style of modernCV to TeX-code "
1936 if document.textclass == "moderncv":
1937 # revert the layouts
1938 revert_ModernCV(document)
1940 # get the position of the end of the last column inset
1941 LastFlexEnd = revert_ModernCV_2(document)
1943 p = find_token(document.body, "\\begin_layout Columns", p)
1946 pEnd = find_end_of_layout(document.body, p)
1947 document.body[p] = document.body[p].replace("\\begin_layout Columns", "\\begin_layout Standard")
1948 if LastFlexEnd != -1:
1949 document.body[p + 1 : p + 1] = put_cmd_in_ert("\\begin{cvcolumns}")
1950 document.body[LastFlexEnd + 24 : LastFlexEnd + 24] = put_cmd_in_ert("\\end{cvcolumns}")
1954 def revert_ModernCV_4(document):
1955 " Reverts the style Social to TeX-code "
1956 if document.textclass == "moderncv":
1957 # revert the layouts
1958 revert_ModernCV(document)
1961 p = find_token(document.body, "\\begin_layout Social", p)
1964 pEnd = find_end_of_layout(document.body, p)
1965 document.body[p] = document.body[p].replace("\\begin_layout Social", "\\begin_layout Standard")
1966 document.body[p + 1 : p + 1] = put_cmd_in_ert("\\social")
1967 hasOpt = find_token(document.body, "[", p + 9)
1969 document.body[p + 30 : p + 30] = put_cmd_in_ert("{")
1970 document.body[p + 41 : p + 41] = put_cmd_in_ert("}")
1972 document.body[p + 11 : p + 11] = put_cmd_in_ert("{")
1973 document.body[p + 21 : p + 21] = put_cmd_in_ert("}")
1977 def convert_ModernCV(document):
1978 " Converts ERT of modernCV to InsetArgument "
1979 if document.textclass == "moderncv":
1987 i = find_token(document.body, "\\begin_layout DoubleItem", i)
1989 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
1990 document.body[o] = document.body[o].replace("\\begin_layout DoubleItem", "\\begin_layout DoubleListItem")
1993 j = find_token(document.body, "\\begin_layout Entry", j)
1995 convert_TeX_brace_to_Argument(document, j, 1, 5, False, False, False)
1998 k = find_token(document.body, "\\begin_layout Item", k)
2000 convert_TeX_brace_to_Argument(document, k, 1, 1, False, False, False)
2003 m = find_token(document.body, "\\begin_layout Language", m)
2005 convert_TeX_brace_to_Argument(document, m, 1, 2, False, False, False)
2007 if i == -1 and j == -1 and k == -1 and m == -1:
2011 def revert_Initials(document):
2012 " Reverts InsetArgument of Initial to TeX-code "
2015 i = find_token(document.body, "\\begin_layout Initial", i)
2018 # first arg (optional) and second arg (first mandatory) are supported in LyX 2.0.x
2019 revert_Argument_to_TeX_brace(document, i, 0, 3, 3, False, False)
2023 def convert_Initials(document):
2024 " Converts ERT of Initial to InsetArgument "
2027 i = find_token(document.body, "\\begin_layout Initial", i)
2030 convert_TeX_brace_to_Argument(document, i, 3, 3, False, False, False)
2034 def revert_literate(document):
2035 " Revert Literate document to old format "
2036 if del_token(document.header, "noweb", 0):
2037 document.textclass = "literate-" + document.textclass
2040 i = find_token(document.body, "\\begin_layout Chunk", i)
2043 document.body[i] = "\\begin_layout Scrap"
2047 def convert_literate(document):
2048 " Convert Literate document to new format"
2049 i = find_token(document.header, "\\textclass", 0)
2050 if (i != -1) and "literate-" in document.header[i]:
2051 document.textclass = document.header[i].replace("\\textclass literate-", "")
2052 j = find_token(document.header, "\\begin_modules", 0)
2054 document.header.insert(j + 1, "noweb")
2056 document.header.insert(i + 1, "\\end_modules")
2057 document.header.insert(i + 1, "noweb")
2058 document.header.insert(i + 1, "\\begin_modules")
2061 i = find_token(document.body, "\\begin_layout Scrap", i)
2064 document.body[i] = "\\begin_layout Chunk"
2068 def revert_itemargs(document):
2069 " Reverts \\item arguments to TeX-code "
2072 i = find_token(document.body, "\\begin_inset Argument item:", i)
2075 j = find_end_of_inset(document.body, i)
2076 # Find containing paragraph layout
2077 parent = get_containing_layout(document.body, i)
2079 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2083 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2084 endPlain = find_end_of_layout(document.body, beginPlain)
2085 content = document.body[beginPlain + 1 : endPlain]
2086 del document.body[i:j+1]
2087 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2088 document.body[parbeg : parbeg] = subst
2092 def revert_garamondx_newtxmath(document):
2093 " Revert native garamond newtxmath definition to LaTeX "
2095 i = find_token(document.header, "\\font_math", 0)
2098 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
2099 val = get_value(document.header, "\\font_math", i)
2100 if val == "garamondx-ntxm":
2101 add_to_preamble(document, "\\usepackage[garamondx]{newtxmath}")
2102 document.header[i] = "\\font_math auto"
2105 def revert_garamondx(document):
2106 " Revert native garamond font definition to LaTeX "
2108 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
2109 i = find_token(document.header, "\\font_roman garamondx", 0)
2112 j = find_token(document.header, "\\font_osf true", 0)
2115 preamble = "\\usepackage"
2117 preamble += "[osfI]"
2118 preamble += "{garamondx}"
2119 add_to_preamble(document, [preamble])
2120 document.header[i] = "\\font_roman default"
2123 def convert_beamerargs(document):
2124 " Converts beamer arguments to new layout "
2126 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2127 if document.textclass not in beamer_classes:
2130 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
2131 list_layouts = ["Itemize", "Enumerate", "Description"]
2132 rx = re.compile(r'^\\begin_inset Argument (\d+)$')
2136 i = find_token(document.body, "\\begin_inset Argument", i)
2139 # Find containing paragraph layout
2140 parent = get_containing_layout(document.body, i)
2142 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2147 layoutname = parent[0]
2148 for p in range(parbeg, parend):
2149 if layoutname in shifted_layouts:
2150 m = rx.match(document.body[p])
2152 argnr = int(m.group(1))
2154 document.body[p] = "\\begin_inset Argument %d" % argnr
2155 if layoutname == "AgainFrame":
2156 m = rx.match(document.body[p])
2158 document.body[p] = "\\begin_inset Argument 3"
2159 if document.body[p + 4] == "\\begin_inset ERT":
2160 if document.body[p + 9].startswith("<"):
2161 # This is an overlay specification
2163 document.body[p + 9] = document.body[p + 9][1:]
2164 if document.body[p + 9].endswith(">"):
2166 document.body[p + 9] = document.body[p + 9][:-1]
2168 document.body[p] = "\\begin_inset Argument 2"
2169 if layoutname in list_layouts:
2170 m = rx.match(document.body[p])
2172 if m.group(1) == "1":
2173 if document.body[p + 4] == "\\begin_inset ERT":
2174 if document.body[p + 9].startswith("<"):
2175 # This is an overlay specification
2177 document.body[p + 9] = document.body[p + 9][1:]
2178 if document.body[p + 9].endswith(">"):
2180 document.body[p + 9] = document.body[p + 9][:-1]
2181 elif layoutname != "Itemize":
2183 document.body[p] = "\\begin_inset Argument 2"
2187 def convert_againframe_args(document):
2188 " Converts beamer AgainFrame to new layout "
2190 # FIXME: This currently only works if the arguments are in one single ERT
2192 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2193 if document.textclass not in beamer_classes:
2198 i = find_token(document.body, "\\begin_layout AgainFrame", i)
2201 parent = get_containing_layout(document.body, i)
2203 document.warning("Wrong parent layout!")
2207 if document.body[parbeg] == "\\begin_inset ERT":
2208 ertcont = parbeg + 5
2209 if document.body[ertcont].startswith("[<"):
2210 # This is a default overlay specification
2212 document.body[ertcont] = document.body[ertcont][2:]
2213 if document.body[ertcont].endswith(">]"):
2215 document.body[ertcont] = document.body[ertcont][:-2]
2216 elif document.body[ertcont].endswith("]"):
2218 tok = document.body[ertcont].find('>][')
2220 subst = [document.body[ertcont][:tok],
2221 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2222 'status collapsed', '', '\\begin_layout Plain Layout',
2223 document.body[ertcont][tok + 3:-1]]
2224 document.body[ertcont : ertcont + 1] = subst
2225 # Convert to ArgInset
2226 document.body[parbeg] = "\\begin_inset Argument 2"
2229 elif document.body[ertcont].startswith("<"):
2230 # This is an overlay specification
2232 document.body[ertcont] = document.body[ertcont][1:]
2233 if document.body[ertcont].endswith(">"):
2235 document.body[ertcont] = document.body[ertcont][:-1]
2236 # Convert to ArgInset
2237 document.body[parbeg] = "\\begin_inset Argument 1"
2238 elif document.body[ertcont].endswith(">]"):
2240 tok = document.body[ertcont].find('>[<')
2242 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2243 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2244 'status collapsed', '', '\\begin_layout Plain Layout',
2245 document.body[ertcont][tok + 3:-2]]
2246 # Convert to ArgInset
2247 document.body[parbeg] = "\\begin_inset Argument 1"
2248 elif document.body[ertcont].endswith("]"):
2250 tok = document.body[ertcont].find('>[<')
2253 tokk = document.body[ertcont].find('>][')
2255 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2256 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2257 'status collapsed', '', '\\begin_layout Plain Layout',
2258 document.body[ertcont][tok + 3:tokk],
2259 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2260 'status collapsed', '', '\\begin_layout Plain Layout',
2261 document.body[ertcont][tokk + 3:-1]]
2263 tokk = document.body[ertcont].find('>[')
2265 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tokk],
2266 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2267 'status collapsed', '', '\\begin_layout Plain Layout',
2268 document.body[ertcont][tokk + 2:-1]]
2269 # Convert to ArgInset
2270 document.body[parbeg] = "\\begin_inset Argument 1"
2273 elif document.body[ertcont].startswith("["):
2274 # This is an ERT option
2276 document.body[ertcont] = document.body[ertcont][1:]
2277 if document.body[ertcont].endswith("]"):
2279 document.body[ertcont] = document.body[ertcont][:-1]
2280 # Convert to ArgInset
2281 document.body[parbeg] = "\\begin_inset Argument 3"
2287 def convert_corollary_args(document):
2288 " Converts beamer corrolary-style ERT arguments native InsetArgs "
2290 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2291 if document.textclass not in beamer_classes:
2294 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2295 for lay in corollary_layouts:
2298 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2301 parent = get_containing_layout(document.body, i)
2303 document.warning("Wrong parent layout!")
2307 if document.body[parbeg] == "\\begin_inset ERT":
2308 ertcont = parbeg + 5
2309 if document.body[ertcont].startswith("<"):
2310 # This is an overlay specification
2312 document.body[ertcont] = document.body[ertcont][1:]
2313 if document.body[ertcont].endswith(">"):
2315 document.body[ertcont] = document.body[ertcont][:-1]
2316 elif document.body[ertcont].endswith("]"):
2318 tok = document.body[ertcont].find('>[')
2320 subst = [document.body[ertcont][:tok],
2321 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2322 'status collapsed', '', '\\begin_layout Plain Layout',
2323 document.body[ertcont][tok + 2:-1]]
2324 document.body[ertcont : ertcont + 1] = subst
2325 # Convert to ArgInset
2326 document.body[parbeg] = "\\begin_inset Argument 1"
2329 elif document.body[ertcont].startswith("["):
2330 if document.body[ertcont].endswith("]"):
2331 # This is an ERT option
2333 document.body[ertcont] = document.body[ertcont][1:]
2335 document.body[ertcont] = document.body[ertcont][:-1]
2336 # Convert to ArgInset
2337 document.body[parbeg] = "\\begin_inset Argument 2"
2339 convert_TeX_brace_to_Argument(document, i, 2, 2, False, True, True)
2346 def convert_quote_args(document):
2347 " Converts beamer quote style ERT args to native InsetArgs "
2349 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2350 if document.textclass not in beamer_classes:
2353 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2354 for lay in quote_layouts:
2357 i = find_token(document.body, "\\begin_layout " + lay, i)
2360 parent = get_containing_layout(document.body, i)
2362 document.warning("Wrong parent layout!")
2366 if document.body[parbeg] == "\\begin_inset ERT":
2367 if document.body[i + 6].startswith("<"):
2368 # This is an overlay specification
2370 document.body[i + 6] = document.body[i + 6][1:]
2371 if document.body[i + 6].endswith(">"):
2373 document.body[i + 6] = document.body[i + 6][:-1]
2374 # Convert to ArgInset
2375 document.body[i + 1] = "\\begin_inset Argument 1"
2379 def revert_beamerargs(document):
2380 " Reverts beamer arguments to old layout "
2382 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2383 if document.textclass not in beamer_classes:
2387 list_layouts = ["Itemize", "Enumerate", "Description"]
2388 headings = ["Part", "Section", "Section*", "Subsection", "Subsection*",
2389 "Subsubsection", "Subsubsection*", "FrameSubtitle", "NoteItem"]
2390 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2391 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2392 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2395 i = find_token(document.body, "\\begin_inset Argument", i)
2398 # Find containing paragraph layout
2399 parent = get_containing_layout(document.body, i)
2401 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2406 realparbeg = parent[3]
2407 layoutname = parent[0]
2409 for p in range(parbeg, parend):
2413 if layoutname in headings:
2414 m = rx.match(document.body[p])
2418 # Find containing paragraph layout
2419 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2420 endPlain = find_end_of_layout(document.body, beginPlain)
2421 endInset = find_end_of_inset(document.body, p)
2422 argcontent = document.body[beginPlain + 1 : endPlain]
2424 realparend = realparend - len(document.body[p : endInset + 1])
2426 del document.body[p : endInset + 1]
2427 if layoutname == "FrameSubtitle":
2428 pre = put_cmd_in_ert("\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2429 elif layoutname == "NoteItem":
2430 pre = put_cmd_in_ert("\\note<") + argcontent + put_cmd_in_ert(">[item]")
2431 elif layoutname.endswith('*'):
2432 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower()[:-1] + "<") + argcontent + put_cmd_in_ert(">*")
2434 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2435 secarg = find_token(document.body, "\\begin_inset Argument 2", parbeg, parend)
2437 # Find containing paragraph layout
2438 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", secarg)
2439 endPlain = find_end_of_layout(document.body, beginPlain)
2440 endInset = find_end_of_inset(document.body, secarg)
2441 argcontent = document.body[beginPlain + 1 : endPlain]
2443 realparend = realparend - len(document.body[secarg : endInset + 1])
2444 del document.body[secarg : endInset + 1]
2445 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2446 pre += put_cmd_in_ert("{")
2447 document.body[parbeg] = "\\begin_layout Standard"
2448 document.body[realparbeg : realparbeg] = pre
2449 pe = find_end_of_layout(document.body, parbeg)
2450 post = put_cmd_in_ert("}")
2451 document.body[pe : pe] = post
2452 realparend += len(pre) + len(post)
2453 if layoutname == "AgainFrame":
2454 m = rx.match(document.body[p])
2458 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2459 endPlain = find_end_of_layout(document.body, beginPlain)
2460 endInset = find_end_of_inset(document.body, p)
2461 content = document.body[beginPlain + 1 : endPlain]
2463 realparend = realparend - len(document.body[p : endInset + 1])
2465 del document.body[p : endInset + 1]
2466 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2467 document.body[realparbeg : realparbeg] = subst
2468 if layoutname == "Overprint":
2469 m = rx.match(document.body[p])
2473 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2474 endPlain = find_end_of_layout(document.body, beginPlain)
2475 endInset = find_end_of_inset(document.body, p)
2476 content = document.body[beginPlain + 1 : endPlain]
2478 realparend = realparend - len(document.body[p : endInset + 1])
2480 del document.body[p : endInset + 1]
2481 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2482 document.body[realparbeg : realparbeg] = subst
2483 if layoutname == "OverlayArea":
2484 m = rx.match(document.body[p])
2488 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2489 endPlain = find_end_of_layout(document.body, beginPlain)
2490 endInset = find_end_of_inset(document.body, p)
2491 content = document.body[beginPlain + 1 : endPlain]
2493 realparend = realparend - len(document.body[p : endInset + 1])
2495 del document.body[p : endInset + 1]
2496 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2497 document.body[realparbeg : realparbeg] = subst
2498 if layoutname in list_layouts:
2499 m = rx.match(document.body[p])
2503 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2504 endPlain = find_end_of_layout(document.body, beginPlain)
2505 endInset = find_end_of_inset(document.body, p)
2506 content = document.body[beginPlain + 1 : endPlain]
2507 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2508 realparend = realparend + len(subst) - len(content)
2509 document.body[beginPlain + 1 : endPlain] = subst
2510 elif argnr == "item:1":
2511 j = find_end_of_inset(document.body, i)
2512 # Find containing paragraph layout
2513 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2514 endPlain = find_end_of_layout(document.body, beginPlain)
2515 content = document.body[beginPlain + 1 : endPlain]
2516 del document.body[i:j+1]
2517 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2518 document.body[realparbeg : realparbeg] = subst
2519 elif argnr == "item:2":
2520 j = find_end_of_inset(document.body, i)
2521 # Find containing paragraph layout
2522 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2523 endPlain = find_end_of_layout(document.body, beginPlain)
2524 content = document.body[beginPlain + 1 : endPlain]
2525 del document.body[i:j+1]
2526 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2527 document.body[realparbeg : realparbeg] = subst
2528 if layoutname in quote_layouts:
2529 m = rx.match(document.body[p])
2533 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2534 endPlain = find_end_of_layout(document.body, beginPlain)
2535 endInset = find_end_of_inset(document.body, p)
2536 content = document.body[beginPlain + 1 : endPlain]
2538 realparend = realparend - len(document.body[p : endInset + 1])
2540 del document.body[p : endInset + 1]
2541 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2542 document.body[realparbeg : realparbeg] = subst
2543 if layoutname in corollary_layouts:
2544 m = rx.match(document.body[p])
2548 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2549 endPlain = find_end_of_layout(document.body, beginPlain)
2550 endInset = find_end_of_inset(document.body, p)
2551 content = document.body[beginPlain + 1 : endPlain]
2553 realparend = realparend - len(document.body[p : endInset + 1])
2555 del document.body[p : endInset + 1]
2556 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2557 document.body[realparbeg : realparbeg] = subst
2562 def revert_beamerargs2(document):
2563 " Reverts beamer arguments to old layout, step 2 "
2565 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2566 if document.textclass not in beamer_classes:
2570 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
2571 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2572 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2575 i = find_token(document.body, "\\begin_inset Argument", i)
2578 # Find containing paragraph layout
2579 parent = get_containing_layout(document.body, i)
2581 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2586 realparbeg = parent[3]
2587 layoutname = parent[0]
2589 for p in range(parbeg, parend):
2593 if layoutname in shifted_layouts:
2594 m = rx.match(document.body[p])
2598 document.body[p] = "\\begin_inset Argument 1"
2599 if layoutname in corollary_layouts:
2600 m = rx.match(document.body[p])
2604 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2605 endPlain = find_end_of_layout(document.body, beginPlain)
2606 endInset = find_end_of_inset(document.body, p)
2607 content = document.body[beginPlain + 1 : endPlain]
2609 realparend = realparend - len(document.body[p : endInset + 1])
2611 del document.body[p : endInset + 1]
2612 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2613 document.body[realparbeg : realparbeg] = subst
2614 if layoutname == "OverlayArea":
2615 m = rx.match(document.body[p])
2619 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2620 endPlain = find_end_of_layout(document.body, beginPlain)
2621 endInset = find_end_of_inset(document.body, p)
2622 content = document.body[beginPlain + 1 : endPlain]
2624 realparend = realparend - len(document.body[p : endInset + 1])
2626 del document.body[p : endInset + 1]
2627 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2628 document.body[realparbeg : realparbeg] = subst
2629 if layoutname == "AgainFrame":
2630 m = rx.match(document.body[p])
2634 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2635 endPlain = find_end_of_layout(document.body, beginPlain)
2636 endInset = find_end_of_inset(document.body, p)
2637 content = document.body[beginPlain + 1 : endPlain]
2639 realparend = realparend - len(document.body[p : endInset + 1])
2641 del document.body[p : endInset + 1]
2642 subst = put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
2643 document.body[realparbeg : realparbeg] = subst
2647 def revert_beamerargs3(document):
2648 " Reverts beamer arguments to old layout, step 3 "
2650 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2651 if document.textclass not in beamer_classes:
2654 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2657 i = find_token(document.body, "\\begin_inset Argument", i)
2660 # Find containing paragraph layout
2661 parent = get_containing_layout(document.body, i)
2663 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2668 realparbeg = parent[3]
2669 layoutname = parent[0]
2671 for p in range(parbeg, parend):
2675 if layoutname == "AgainFrame":
2676 m = rx.match(document.body[p])
2680 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2681 endPlain = find_end_of_layout(document.body, beginPlain)
2682 endInset = find_end_of_inset(document.body, p)
2683 content = document.body[beginPlain + 1 : endPlain]
2685 realparend = realparend - len(document.body[p : endInset + 1])
2687 del document.body[p : endInset + 1]
2688 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2689 document.body[realparbeg : realparbeg] = subst
2693 def revert_beamerflex(document):
2694 " Reverts beamer Flex insets "
2696 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2697 if document.textclass not in beamer_classes:
2700 new_flexes = {"Bold" : "\\textbf", "Emphasize" : "\\emph", "Only" : "\\only",
2701 "Uncover" : "\\uncover", "Visible" : "\\visible",
2702 "Invisible" : "\\invisible", "Alternative" : "\\alt",
2703 "Beamer_Note" : "\\note"}
2704 old_flexes = {"Alert" : "\\alert", "Structure" : "\\structure"}
2705 rx = re.compile(r'^\\begin_inset Flex (.+)$')
2709 i = find_token(document.body, "\\begin_inset Flex", i)
2712 m = rx.match(document.body[i])
2714 flextype = m.group(1)
2715 z = find_end_of_inset(document.body, i)
2717 document.warning("Can't find end of Flex " + flextype + " inset.")
2720 if flextype in new_flexes:
2721 pre = put_cmd_in_ert(new_flexes[flextype])
2722 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2724 argend = find_end_of_inset(document.body, arg)
2726 document.warning("Can't find end of Argument!")
2729 # Find containing paragraph layout
2730 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2731 endPlain = find_end_of_layout(document.body, beginPlain)
2732 argcontent = document.body[beginPlain + 1 : endPlain]
2734 z = z - len(document.body[arg : argend + 1])
2736 del document.body[arg : argend + 1]
2737 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2738 arg = find_token(document.body, "\\begin_inset Argument 2", i, z)
2740 argend = find_end_of_inset(document.body, arg)
2742 document.warning("Can't find end of Argument!")
2745 # Find containing paragraph layout
2746 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2747 endPlain = find_end_of_layout(document.body, beginPlain)
2748 argcontent = document.body[beginPlain + 1 : endPlain]
2750 z = z - len(document.body[arg : argend + 1])
2752 del document.body[arg : argend + 1]
2753 if flextype == "Alternative":
2754 pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
2756 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2757 pre += put_cmd_in_ert("{")
2758 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2759 endPlain = find_end_of_layout(document.body, beginPlain)
2761 z = z - len(document.body[i : beginPlain + 1])
2763 document.body[i : beginPlain + 1] = pre
2764 post = put_cmd_in_ert("}")
2765 document.body[z - 2 : z + 1] = post
2766 elif flextype in old_flexes:
2767 pre = put_cmd_in_ert(old_flexes[flextype])
2768 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2772 argend = find_end_of_inset(document.body, arg)
2774 document.warning("Can't find end of Argument!")
2777 # Find containing paragraph layout
2778 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2779 endPlain = find_end_of_layout(document.body, beginPlain)
2780 argcontent = document.body[beginPlain + 1 : endPlain]
2782 z = z - len(document.body[arg : argend + 1])
2784 del document.body[arg : argend + 1]
2785 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2786 pre += put_cmd_in_ert("{")
2787 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2788 endPlain = find_end_of_layout(document.body, beginPlain)
2790 z = z - len(document.body[i : beginPlain + 1])
2792 document.body[i : beginPlain + 1] = pre
2793 post = put_cmd_in_ert("}")
2794 document.body[z - 2 : z + 1] = post
2799 def revert_beamerblocks(document):
2800 " Reverts beamer block arguments to ERT "
2802 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2803 if document.textclass not in beamer_classes:
2806 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2808 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2811 i = find_token(document.body, "\\begin_inset Argument", i)
2814 # Find containing paragraph layout
2815 parent = get_containing_layout(document.body, i)
2817 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2822 realparbeg = parent[3]
2823 layoutname = parent[0]
2825 for p in range(parbeg, parend):
2829 if layoutname in blocks:
2830 m = rx.match(document.body[p])
2834 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2835 endPlain = find_end_of_layout(document.body, beginPlain)
2836 endInset = find_end_of_inset(document.body, p)
2837 content = document.body[beginPlain + 1 : endPlain]
2839 realparend = realparend - len(document.body[p : endInset + 1])
2841 del document.body[p : endInset + 1]
2842 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2843 document.body[realparbeg : realparbeg] = subst
2845 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2846 endPlain = find_end_of_layout(document.body, beginPlain)
2847 endInset = find_end_of_inset(document.body, p)
2848 content = document.body[beginPlain + 1 : endPlain]
2850 realparend = realparend - len(document.body[p : endInset + 1])
2852 del document.body[p : endInset + 1]
2853 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2854 document.body[realparbeg : realparbeg] = subst
2859 def convert_beamerblocks(document):
2860 " Converts beamer block ERT args to native InsetArgs "
2862 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2863 if document.textclass not in beamer_classes:
2866 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2870 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2873 parent = get_containing_layout(document.body, i)
2874 if parent == False or parent[1] != i:
2875 document.warning("Wrong parent layout!")
2881 if document.body[parbeg] == "\\begin_inset ERT":
2882 ertcont = parbeg + 5
2884 if document.body[ertcont].startswith("<"):
2885 # This is an overlay specification
2887 document.body[ertcont] = document.body[ertcont][1:]
2888 if document.body[ertcont].endswith(">"):
2890 document.body[ertcont] = document.body[ertcont][:-1]
2891 # Convert to ArgInset
2892 document.body[parbeg] = "\\begin_inset Argument 1"
2893 elif document.body[ertcont].endswith("}"):
2895 tok = document.body[ertcont].find('>{')
2897 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2898 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2899 'status collapsed', '', '\\begin_layout Plain Layout',
2900 document.body[ertcont][tok + 2:-1]]
2901 # Convert to ArgInset
2902 document.body[parbeg] = "\\begin_inset Argument 1"
2903 elif document.body[ertcont].startswith("{"):
2904 # This is the block title
2905 if document.body[ertcont].endswith("}"):
2906 # strip off the braces
2907 document.body[ertcont] = document.body[ertcont][1:-1]
2908 # Convert to ArgInset
2909 document.body[parbeg] = "\\begin_inset Argument 2"
2910 elif count_pars_in_inset(document.body, ertcont) > 1:
2911 # Multipar ERT. Skip this.
2914 convert_TeX_brace_to_Argument(document, i, 2, 2, False, True, False)
2917 j = find_end_of_layout(document.body, i)
2919 document.warning("end of layout not found!")
2920 k = find_token(document.body, "\\begin_inset Argument", i, j)
2922 document.warning("InsetArgument not found!")
2924 l = find_end_of_inset(document.body, k)
2925 m = find_token(document.body, "\\begin_inset ERT", l, j)
2933 def convert_overprint(document):
2934 " Convert old beamer overprint layouts to ERT "
2936 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2937 if document.textclass not in beamer_classes:
2942 i = find_token(document.body, "\\begin_layout Overprint", i)
2945 # Find end of sequence
2946 j = find_end_of_sequence(document.body, i)
2948 document.warning("Malformed LyX document. Cannot find end of Overprint sequence!")
2952 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
2954 if document.body[j] == "\\end_deeper":
2955 esubst = ["", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
2957 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
2958 endseq = endseq + len(esubst) - len(document.body[j : j])
2959 document.body[j : j] = esubst
2960 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
2962 argend = find_end_of_layout(document.body, argbeg)
2964 document.warning("Malformed LyX document. Cannot find end of Overprint argument!")
2967 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
2968 endPlain = find_end_of_layout(document.body, beginPlain)
2969 content = document.body[beginPlain + 1 : endPlain]
2971 endseq = endseq - len(document.body[argbeg : argend + 1])
2973 del document.body[argbeg : argend + 1]
2974 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2976 endseq = endseq - len(document.body[i : i])
2977 document.body[i : i] = subst + ["\\end_layout"]
2978 endseq += len(subst)
2980 for p in range(i, endseq):
2981 if document.body[p] == "\\begin_layout Overprint":
2982 document.body[p] = "\\begin_layout Standard"
2987 def revert_overprint(document):
2988 " Revert old beamer overprint layouts to ERT "
2990 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2991 if document.textclass not in beamer_classes:
2996 i = find_token(document.body, "\\begin_layout Overprint", i)
2999 # Find end of sequence
3000 j = find_end_of_sequence(document.body, i)
3002 document.warning("Malformed LyX document. Cannot find end of Overprint sequence!")
3006 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
3007 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}")
3008 endseq = endseq + len(esubst) - len(document.body[j : j])
3009 if document.body[j] == "\\end_deeper":
3010 document.body[j : j] = ["\\end_deeper", ""] + esubst
3012 document.body[j : j] = esubst
3015 if document.body[r] == "\\begin_deeper":
3016 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3018 document.body[r] = ""
3019 document.body[s] = ""
3023 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
3025 argend = find_end_of_inset(document.body, argbeg)
3027 document.warning("Malformed LyX document. Cannot find end of Overprint argument!")
3030 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3031 endPlain = find_end_of_layout(document.body, beginPlain)
3032 content = document.body[beginPlain + 1 : endPlain]
3034 endseq = endseq - len(document.body[argbeg : argend])
3036 del document.body[argbeg : argend + 1]
3037 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3039 endseq = endseq - len(document.body[i : i])
3040 document.body[i : i] = subst + ["\\end_layout"]
3041 endseq += len(subst)
3047 if document.body[p] == "\\begin_layout Overprint":
3048 q = find_end_of_layout(document.body, p)
3050 document.warning("Malformed LyX document. Cannot find end of Overprint layout!")
3053 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\onslide")
3054 argbeg = find_token(document.body, "\\begin_inset Argument item:1", p, q)
3056 argend = find_end_of_inset(document.body, argbeg)
3058 document.warning("Malformed LyX document. Cannot find end of Overprint item argument!")
3061 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3062 endPlain = find_end_of_layout(document.body, beginPlain)
3063 content = document.body[beginPlain + 1 : endPlain]
3065 endseq = endseq - len(document.body[argbeg : argend + 1])
3067 del document.body[argbeg : argend + 1]
3068 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3069 endseq = endseq - len(document.body[p : p + 1]) + len(subst)
3070 document.body[p : p + 1] = subst
3076 def revert_frametitle(document):
3077 " Reverts beamer frametitle layout to ERT "
3079 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3080 if document.textclass not in beamer_classes:
3083 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
3086 i = find_token(document.body, "\\begin_layout FrameTitle", i)
3089 j = find_end_of_layout(document.body, i)
3091 document.warning("Malformed LyX document: Can't find end of FrameTitle layout")
3095 document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
3096 endlay += len(put_cmd_in_ert("}"))
3097 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\frametitle")
3098 for p in range(i, j):
3101 m = rx.match(document.body[p])
3105 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3106 endPlain = find_end_of_layout(document.body, beginPlain)
3107 endInset = find_end_of_inset(document.body, p)
3108 content = document.body[beginPlain + 1 : endPlain]
3110 endlay = endlay - len(document.body[p : endInset + 1])
3112 del document.body[p : endInset + 1]
3113 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3115 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3116 endPlain = find_end_of_layout(document.body, beginPlain)
3117 endInset = find_end_of_inset(document.body, p)
3118 content = document.body[beginPlain + 1 : endPlain]
3120 endlay = endlay - len(document.body[p : endInset + 1])
3122 del document.body[p : endInset + 1]
3123 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3125 subst += put_cmd_in_ert("{")
3126 document.body[i : i + 1] = subst
3130 def convert_epigraph(document):
3131 " Converts memoir epigraph to new syntax "
3133 if document.textclass != "memoir":
3138 i = find_token(document.body, "\\begin_layout Epigraph", i)
3141 j = find_end_of_layout(document.body, i)
3143 document.warning("Malformed LyX document: Can't find end of Epigraph layout")
3148 ert = find_token(document.body, "\\begin_inset ERT", i, j)
3150 endInset = find_end_of_inset(document.body, ert)
3151 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", ert)
3152 endPlain = find_end_of_layout(document.body, beginPlain)
3153 ertcont = beginPlain + 2
3154 if document.body[ertcont] == "}{":
3156 # Convert to ArgInset
3157 endlay = endlay - 2 * len(document.body[j])
3158 begsubst = ['\\begin_inset Argument post:1', 'status collapsed', '',
3159 '\\begin_layout Plain Layout']
3160 endsubst = ['\\end_layout', '', '\\end_inset', '', document.body[j]]
3161 document.body[j : j + 1] = endsubst
3162 document.body[endInset + 1 : endInset + 1] = begsubst
3164 endlay += len(begsubst) + len(endsubst)
3165 endlay = endlay - len(document.body[ert : endInset + 1])
3166 del document.body[ert : endInset + 1]
3171 def revert_epigraph(document):
3172 " Reverts memoir epigraph argument to ERT "
3174 if document.textclass != "memoir":
3179 i = find_token(document.body, "\\begin_layout Epigraph", i)
3182 j = find_end_of_layout(document.body, i)
3184 document.warning("Malformed LyX document: Can't find end of Epigraph layout")
3189 p = find_token(document.body, "\\begin_layout Argument post:1", i, j)
3191 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3192 endPlain = find_end_of_layout(document.body, beginPlain)
3193 endInset = find_end_of_inset(document.body, p)
3194 content = document.body[beginPlain + 1 : endPlain]
3196 endlay = endlay - len(document.body[p : endInset + 1])
3198 del document.body[p : endInset + 1]
3199 subst += put_cmd_in_ert("}{") + content
3201 subst += put_cmd_in_ert("}{")
3203 document.body[j : j] = subst + document.body[j : j]
3207 def convert_captioninsets(document):
3208 " Converts caption insets to new syntax "
3212 i = find_token(document.body, "\\begin_inset Caption", i)
3215 document.body[i] = "\\begin_inset Caption Standard"
3219 def revert_captioninsets(document):
3220 " Reverts caption insets to old syntax "
3224 i = find_token(document.body, "\\begin_inset Caption Standard", i)
3227 document.body[i] = "\\begin_inset Caption"
3231 def convert_captionlayouts(document):
3232 " Convert caption layouts to caption insets. "
3235 "Captionabove": "Above",
3236 "Captionbelow": "Below",
3237 "FigCaption" : "FigCaption",
3238 "Table_Caption" : "Table",
3239 "CenteredCaption" : "Centered",
3240 "Bicaption" : "Bicaption",
3245 i = find_token(document.body, "\\begin_layout", i)
3248 val = get_value(document.body, "\\begin_layout", i)
3249 if val in caption_dict.keys():
3250 j = find_end_of_layout(document.body, i)
3252 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3255 document.body[j:j] = ["\\end_layout", "", "\\end_inset", "", ""]
3256 document.body[i:i+1] = ["\\begin_layout %s" % document.default_layout,
3257 "\\begin_inset Caption %s" % caption_dict[val], "",
3258 "\\begin_layout %s" % document.default_layout]
3262 def revert_captionlayouts(document):
3263 " Revert caption insets to caption layouts. "
3266 "Above" : "Captionabove",
3267 "Below" : "Captionbelow",
3268 "FigCaption" : "FigCaption",
3269 "Table" : "Table_Caption",
3270 "Centered" : "CenteredCaption",
3271 "Bicaption" : "Bicaption",
3275 rx = re.compile(r'^\\begin_inset Caption (\S+)$')
3277 i = find_token(document.body, "\\begin_inset Caption", i)
3281 m = rx.match(document.body[i])
3285 if val not in caption_dict.keys():
3289 # We either need to delete the previous \begin_layout line, or we
3290 # need to end the previous layout if this inset is not in the first
3291 # position of the paragraph.
3292 layout_before = find_token_backwards(document.body, "\\begin_layout", i)
3293 if layout_before == -1:
3294 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3296 layout_line = document.body[layout_before]
3297 del_layout_before = True
3298 l = layout_before + 1
3300 if document.body[l] != "":
3301 del_layout_before = False
3304 if del_layout_before:
3305 del document.body[layout_before:i]
3308 document.body[i:i] = ["\\end_layout", ""]
3311 # Find start of layout in the inset and end of inset
3312 j = find_token(document.body, "\\begin_layout", i)
3314 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3316 k = find_end_of_inset(document.body, i)
3318 document.warning("Malformed LyX document: Missing `\\end_inset'.")
3321 # We either need to delete the following \end_layout line, or we need
3322 # to restart the old layout if this inset is not at the paragraph end.
3323 layout_after = find_token(document.body, "\\end_layout", k)
3324 if layout_after == -1:
3325 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3327 del_layout_after = True
3329 while l < layout_after:
3330 if document.body[l] != "":
3331 del_layout_after = False
3334 if del_layout_after:
3335 del document.body[k+1:layout_after+1]
3337 document.body[k+1:k+1] = [layout_line, ""]
3339 # delete \begin_layout and \end_inset and replace \begin_inset with
3340 # "\begin_layout XXX". This works because we can only have one
3341 # paragraph in the caption inset: The old \end_layout will be recycled.
3342 del document.body[k]
3343 if document.body[k] == "":
3344 del document.body[k]
3345 del document.body[j]
3346 if document.body[j] == "":
3347 del document.body[j]
3348 document.body[i] = "\\begin_layout %s" % caption_dict[val]
3349 if document.body[i+1] == "":
3350 del document.body[i+1]
3354 def revert_fragileframe(document):
3355 " Reverts beamer FragileFrame layout to ERT "
3357 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3358 if document.textclass not in beamer_classes:
3363 i = find_token(document.body, "\\begin_layout FragileFrame", i)
3366 # Find end of sequence
3367 j = find_end_of_sequence(document.body, i)
3369 document.warning("Malformed LyX document. Cannot find end of FragileFrame sequence!")
3373 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{frame}")
3374 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{frame}")
3375 endseq = endseq + len(esubst) - len(document.body[j : j])
3376 if document.body[j] == "\\end_deeper":
3377 document.body[j : j] = ["\\end_deeper", ""] + esubst
3379 document.body[j : j] = esubst
3380 for q in range(i, j):
3381 if document.body[q] == "\\begin_layout FragileFrame":
3382 document.body[q] = "\\begin_layout %s" % document.default_layout
3385 if document.body[r] == "\\begin_deeper":
3386 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3388 document.body[r] = ""
3389 document.body[s] = ""
3393 for p in range(1, 5):
3394 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, j)
3397 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3398 endPlain = find_end_of_layout(document.body, beginPlain)
3399 endInset = find_end_of_inset(document.body, arg)
3400 content = document.body[beginPlain + 1 : endPlain]
3402 j = j - len(document.body[arg : endInset + 1])
3404 del document.body[arg : endInset + 1]
3405 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3407 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3408 endPlain = find_end_of_layout(document.body, beginPlain)
3409 endInset = find_end_of_inset(document.body, arg)
3410 content = document.body[beginPlain + 1 : endPlain]
3412 j = j - len(document.body[arg : endInset + 1])
3414 del document.body[arg : endInset + 1]
3415 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3417 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3418 endPlain = find_end_of_layout(document.body, beginPlain)
3419 endInset = find_end_of_inset(document.body, arg)
3420 content = document.body[beginPlain + 1 : endPlain]
3422 j = j - len(document.body[arg : endInset + 1])
3424 del document.body[arg : endInset + 1]
3425 subst += put_cmd_in_ert("[fragile,") + content + put_cmd_in_ert("]")
3427 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3428 endPlain = find_end_of_layout(document.body, beginPlain)
3429 endInset = find_end_of_inset(document.body, arg)
3430 content = document.body[beginPlain + 1 : endPlain]
3432 j = j - len(document.body[arg : endInset + 1])
3434 del document.body[arg : endInset + 1]
3435 subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
3437 subst += put_cmd_in_ert("[fragile]")
3439 document.body[i : i + 1] = subst
3443 def revert_newframes(document):
3444 " Reverts beamer Frame and PlainFrame layouts to old forms "
3446 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3447 if document.textclass not in beamer_classes:
3451 "Frame" : "BeginFrame",
3452 "PlainFrame" : "BeginPlainFrame",
3455 rx = re.compile(r'^\\begin_layout (\S+)$')
3458 i = find_token(document.body, "\\begin_layout", i)
3462 m = rx.match(document.body[i])
3466 if val not in frame_dict.keys():
3469 # Find end of sequence
3470 j = find_end_of_sequence(document.body, i)
3472 document.warning("Malformed LyX document. Cannot find end of Frame sequence!")
3476 subst = ["\\begin_layout %s" % frame_dict[val]]
3477 esubst = ["\\end_layout", "", "\\begin_layout EndFrame", "", "\\end_layout"]
3478 endseq = endseq + len(esubst) - len(document.body[j : j])
3479 if document.body[j] == "\\end_deeper":
3480 document.body[j : j] = ["\\end_deeper", ""] + esubst
3482 document.body[j : j] = esubst
3483 for q in range(i, j):
3484 if document.body[q] == "\\begin_layout %s" % val:
3485 document.body[q] = "\\begin_layout %s" % document.default_layout
3488 if document.body[r] == "\\begin_deeper":
3489 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3491 document.body[r] = ""
3492 document.body[s] = ""
3496 l = find_end_of_layout(document.body, i)
3497 for p in range(1, 5):
3498 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, l)
3501 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3502 endPlain = find_end_of_layout(document.body, beginPlain)
3503 endInset = find_end_of_inset(document.body, arg)
3504 content = document.body[beginPlain + 1 : endPlain]
3506 l = l - len(document.body[arg : endInset + 1])
3508 del document.body[arg : endInset + 1]
3509 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3511 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3512 endPlain = find_end_of_layout(document.body, beginPlain)
3513 endInset = find_end_of_inset(document.body, arg)
3514 content = document.body[beginPlain + 1 : endPlain]
3516 l = l - len(document.body[arg : endInset + 1])
3518 del document.body[arg : endInset + 1]
3519 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3521 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3522 endPlain = find_end_of_layout(document.body, beginPlain)
3523 endInset = find_end_of_inset(document.body, arg)
3524 content = document.body[beginPlain + 1 : endPlain]
3526 l = l - len(document.body[arg : endInset + 1])
3528 del document.body[arg : endInset + 1]
3529 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3531 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3532 endPlain = find_end_of_layout(document.body, beginPlain)
3533 endInset = find_end_of_inset(document.body, arg)
3534 content = document.body[beginPlain + 1 : endPlain]
3536 l = l - len(document.body[arg : endInset + 1])
3538 del document.body[arg : endInset + 1]
3541 document.body[i : i + 1] = subst
3544 # known encodings that do not change their names (same LyX and LaTeX names)
3545 known_enc_tuple = ("auto", "default", "ansinew", "applemac", "armscii8", "ascii",
3546 "cp437", "cp437de", "cp850", "cp852", "cp855", "cp858", "cp862", "cp865", "cp866",
3547 "cp1250", "cp1251", "cp1252", "cp1255", "cp1256", "cp1257", "koi8-r", "koi8-u",
3548 "pt154", "pt254", "tis620-0", "utf8", "utf8x", "utf8-plain")
3550 def convert_encodings(document):
3551 "Use the LyX names of the encodings instead of the LaTeX names."
3552 LaTeX2LyX_enc_dict = {
3553 "8859-6": "iso8859-6",
3554 "8859-8": "iso8859-8",
3556 "euc": "euc-jp-platex",
3561 "iso88595": "iso8859-5",
3562 "iso-8859-7": "iso8859-7",
3564 "jis": "jis-platex",
3566 "l7xenc": "iso8859-13",
3567 "latin1": "iso8859-1",
3568 "latin2": "iso8859-2",
3569 "latin3": "iso8859-3",
3570 "latin4": "iso8859-4",
3571 "latin5": "iso8859-9",
3572 "latin9": "iso8859-15",
3573 "latin10": "iso8859-16",
3574 "SJIS": "shift-jis",
3575 "sjis": "shift-jis-platex",
3578 i = find_token(document.header, "\\inputencoding" , 0)
3581 val = get_value(document.header, "\\inputencoding", i)
3582 if val in LaTeX2LyX_enc_dict.keys():
3583 document.header[i] = "\\inputencoding %s" % LaTeX2LyX_enc_dict[val]
3584 elif val not in known_enc_tuple:
3585 document.warning("Ignoring unknown input encoding: `%s'" % val)
3588 def revert_encodings(document):
3589 """Revert to using the LaTeX names of the encodings instead of the LyX names.
3590 Also revert utf8-platex to sjis, the language default when using Japanese.
3592 LyX2LaTeX_enc_dict = {
3597 "euc-jp-platex": "euc",
3600 "iso8859-1": "latin1",
3601 "iso8859-2": "latin2",
3602 "iso8859-3": "latin3",
3603 "iso8859-4": "latin4",
3604 "iso8859-5": "iso88595",
3605 "iso8859-6": "8859-6",
3606 "iso8859-7": "iso-8859-7",
3607 "iso8859-8": "8859-8",
3608 "iso8859-9": "latin5",
3609 "iso8859-13": "l7xenc",
3610 "iso8859-15": "latin9",
3611 "iso8859-16": "latin10",
3613 "jis-platex": "jis",
3614 "shift-jis": "SJIS",
3615 "shift-jis-platex": "sjis",
3617 "utf8-platex": "sjis"
3619 i = find_token(document.header, "\\inputencoding" , 0)
3622 val = get_value(document.header, "\\inputencoding", i)
3623 if val in LyX2LaTeX_enc_dict.keys():
3624 document.header[i] = "\\inputencoding %s" % LyX2LaTeX_enc_dict[val]
3625 elif val not in known_enc_tuple:
3626 document.warning("Ignoring unknown input encoding: `%s'" % val)
3629 def revert_IEEEtran_3(document):
3631 Reverts Flex Insets to TeX-code
3633 if document.textclass == "IEEEtran":
3639 h = find_token(document.body, "\\begin_inset Flex Author Mark", h)
3641 endh = find_end_of_inset(document.body, h)
3642 document.body[endh - 2 : endh + 1] = put_cmd_in_ert("}")
3643 document.body[h : h + 4] = put_cmd_in_ert("\\IEEEauthorrefmark{")
3646 i = find_token(document.body, "\\begin_inset Flex Author Name", i)
3648 endi = find_end_of_inset(document.body, i)
3649 document.body[endi - 2 : endi + 1] = put_cmd_in_ert("}")
3650 document.body[i : i + 4] = put_cmd_in_ert("\\IEEEauthorblockN{")
3653 j = find_token(document.body, "\\begin_inset Flex Author Affiliation", j)
3655 endj = find_end_of_inset(document.body, j)
3656 document.body[endj - 2 : endj + 1] = put_cmd_in_ert("}")
3657 document.body[j : j + 4] = put_cmd_in_ert("\\IEEEauthorblockA{")
3659 if i == -1 and j == -1 and h == -1:
3663 def revert_kurier_fonts(document):
3664 " Revert kurier font definition to LaTeX "
3666 i = find_token(document.header, "\\font_math", 0)
3668 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3669 val = get_value(document.header, "\\font_math", i)
3670 if val == "kurier-math":
3671 add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
3672 "\\usepackage[math]{kurier}\n" \
3673 "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
3674 document.header[i] = "\\font_math auto"
3676 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3677 kurier_fonts = ["kurier", "kurierc", "kurierl", "kurierlc"]
3678 k = find_token(document.header, "\\font_sans kurier", 0)
3680 sf = get_value(document.header, "\\font_sans", k)
3681 if sf in kurier_fonts:
3682 add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
3683 document.header[k] = "\\font_sans default"
3685 def revert_iwona_fonts(document):
3686 " Revert iwona font definition to LaTeX "
3688 i = find_token(document.header, "\\font_math", 0)
3690 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3691 val = get_value(document.header, "\\font_math", i)
3692 if val == "iwona-math":
3693 add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
3694 "\\usepackage[math]{iwona}\n" \
3695 "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
3696 document.header[i] = "\\font_math auto"
3698 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3699 iwona_fonts = ["iwona", "iwonac", "iwonal", "iwonalc"]
3700 k = find_token(document.header, "\\font_sans iwona", 0)
3702 sf = get_value(document.header, "\\font_sans", k)
3703 if sf in iwona_fonts:
3704 add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
3705 document.header[k] = "\\font_sans default"
3708 def revert_new_libertines(document):
3709 " Revert new libertine font definition to LaTeX "
3711 if find_token(document.header, "\\use_non_tex_fonts true", 0) != -1:
3714 i = find_token(document.header, "\\font_typewriter libertine-mono", 0)
3716 preamble = "\\usepackage"
3717 sc = find_token(document.header, "\\font_tt_scale", 0)
3719 scval = get_value(document.header, "\\font_tt_scale", sc)
3721 preamble += "[scale=%f]" % (float(scval) / 100)
3722 document.header[sc] = "\\font_tt_scale 100"
3723 preamble += "{libertineMono-type1}"
3724 add_to_preamble(document, [preamble])
3725 document.header[i] = "\\font_typewriter default"
3727 k = find_token(document.header, "\\font_sans biolinum", 0)
3729 preamble = "\\usepackage"
3731 j = find_token(document.header, "\\font_osf true", 0)
3736 sc = find_token(document.header, "\\font_sf_scale", 0)
3738 scval = get_value(document.header, "\\font_sf_scale", sc)
3740 options += ",scale=%f" % (float(scval) / 100)
3741 document.header[sc] = "\\font_sf_scale 100"
3743 preamble += "[" + options +"]"
3744 preamble += "{biolinum-type1}"
3745 add_to_preamble(document, [preamble])
3746 document.header[k] = "\\font_sans default"
3749 def convert_lyxframes(document):
3750 " Converts old beamer frames to new style "
3752 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3753 if document.textclass not in beamer_classes:
3756 framebeg = ["BeginFrame", "BeginPlainFrame"]
3757 frameend = ["Frame", "PlainFrame", "EndFrame", "BeginFrame", "BeginPlainFrame", "AgainFrame",
3758 "Section", "Section*", "Subsection", "Subsection*", "Subsubsection", "Subsubsection*"]
3759 for lay in framebeg:
3762 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
3765 parent = get_containing_layout(document.body, i)
3766 if parent == False or parent[1] != i:
3767 document.warning("Wrong parent layout!")
3770 frametype = parent[0]
3774 # Step I: Convert ERT arguments
3775 # FIXME: This currently only works if the arguments are in one single ERT
3777 if document.body[parbeg] == "\\begin_inset ERT":
3778 ertend = find_end_of_inset(document.body, parbeg)
3780 document.warning("Malformed LyX document: missing ERT \\end_inset")
3782 ertcont = parbeg + 5
3783 if document.body[ertcont].startswith("[<"):
3784 # This is a default overlay specification
3786 document.body[ertcont] = document.body[ertcont][2:]
3787 if document.body[ertcont].endswith(">]"):
3789 document.body[ertcont] = document.body[ertcont][:-2]
3790 elif document.body[ertcont].endswith("]"):
3792 tok = document.body[ertcont].find('>][')
3794 subst = [document.body[ertcont][:tok],
3795 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
3796 'status collapsed', '', '\\begin_layout Plain Layout',
3797 document.body[ertcont][tok + 3:-1]]
3798 document.body[ertcont : ertcont + 1] = subst
3800 # Convert to ArgInset
3801 document.body[parbeg] = "\\begin_inset Argument 2"
3802 elif document.body[ertcont].startswith("<"):
3803 # This is an overlay specification
3805 document.body[ertcont] = document.body[ertcont][1:]
3806 if document.body[ertcont].endswith(">"):
3808 document.body[ertcont] = document.body[ertcont][:-1]
3809 # Convert to ArgInset
3810 document.body[parbeg] = "\\begin_inset Argument 1"
3811 elif document.body[ertcont].endswith(">]"):
3813 tok = document.body[ertcont].find('>[<')
3815 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
3816 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
3817 'status collapsed', '', '\\begin_layout Plain Layout',
3818 document.body[ertcont][tok + 3:-2]]
3819 # Convert to ArgInset
3820 document.body[parbeg] = "\\begin_inset Argument 1"
3822 elif document.body[ertcont].endswith("]"):
3824 tok = document.body[ertcont].find('>[<')
3827 tokk = document.body[ertcont].find('>][')
3829 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
3830 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
3831 'status collapsed', '', '\\begin_layout Plain Layout',
3832 document.body[ertcont][tok + 3:tokk],
3833 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
3834 'status collapsed', '', '\\begin_layout Plain Layout',
3835 document.body[ertcont][tokk + 3:-1]]
3838 tokk = document.body[ertcont].find('>[')
3840 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tokk],
3841 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
3842 'status collapsed', '', '\\begin_layout Plain Layout',
3843 document.body[ertcont][tokk + 2:-1]]
3845 # Convert to ArgInset
3846 document.body[parbeg] = "\\begin_inset Argument 1"
3847 elif document.body[ertcont].startswith("["):
3848 # This is an ERT option
3850 document.body[ertcont] = document.body[ertcont][1:]
3851 if document.body[ertcont].endswith("]"):
3853 document.body[ertcont] = document.body[ertcont][:-1]
3854 # Convert to ArgInset
3855 document.body[parbeg] = "\\begin_inset Argument 3"
3856 # End of argument conversion
3857 # Step II: Now rename the layout and convert the title to an argument
3858 j = find_end_of_layout(document.body, i)
3859 document.body[j : j + 1] = ['\\end_layout', '', '\\end_inset', '', '\\end_layout']
3860 if lay == "BeginFrame":
3861 document.body[i] = "\\begin_layout Frame"
3863 document.body[i] = "\\begin_layout PlainFrame"
3864 document.body[ertend + 1 : ertend + 1] = ['\\begin_inset Argument 4',
3865 'status open', '', '\\begin_layout Plain Layout']
3866 # Step III: find real frame end
3870 fend = find_token(document.body, "\\begin_layout", jj)
3872 document.warning("Malformed LyX document: No real frame end!")
3874 val = get_value(document.body, "\\begin_layout", fend)
3875 if val not in frameend:
3878 old = document.body[fend]
3879 if val == frametype:
3880 document.body[fend : fend] = ['\\end_deeper', '', '\\begin_layout Separator', '', '\\end_layout']
3882 document.body[fend : fend] = ['\\end_deeper']
3883 document.body[j + 1 : j + 1] = ['', '\\begin_deeper']
3888 def remove_endframes(document):
3889 " Remove deprecated beamer endframes "
3891 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3892 if document.textclass not in beamer_classes:
3897 i = find_token_exact(document.body, "\\begin_layout EndFrame", i)
3900 j = find_end_of_layout(document.body, i)
3902 document.warning("Malformed LyX document: Missing \\end_layout to EndFrame")
3905 del document.body[i : j + 1]
3908 def revert_powerdot_flexes(document):
3909 " Reverts powerdot flex insets "
3911 if document.textclass != "powerdot":
3914 flexes = {"Onslide" : "\\onslide",
3915 "Onslide*" : "\\onslide*",
3916 "Onslide+" : "\\onslide+"}
3917 rx = re.compile(r'^\\begin_inset Flex (.+)$')
3921 i = find_token(document.body, "\\begin_inset Flex", i)
3924 m = rx.match(document.body[i])
3926 flextype = m.group(1)
3927 z = find_end_of_inset(document.body, i)
3929 document.warning("Can't find end of Flex " + flextype + " inset.")
3932 if flextype in flexes:
3933 pre = put_cmd_in_ert(flexes[flextype])
3934 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
3936 argend = find_end_of_inset(document.body, arg)
3938 document.warning("Can't find end of Argument!")
3941 # Find containing paragraph layout
3942 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3943 endPlain = find_end_of_layout(document.body, beginPlain)
3944 argcontent = document.body[beginPlain + 1 : endPlain]
3946 z = z - len(document.body[arg : argend + 1])
3948 del document.body[arg : argend + 1]
3949 pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
3950 pre += put_cmd_in_ert("{")
3951 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
3952 endPlain = find_end_of_layout(document.body, beginPlain)
3954 z = z - len(document.body[i : beginPlain + 1])
3956 document.body[i : beginPlain + 1] = pre
3957 post = put_cmd_in_ert("}")
3958 document.body[z - 2 : z + 1] = post
3962 def revert_powerdot_pause(document):
3963 " Reverts powerdot pause layout to ERT "
3965 if document.textclass != "powerdot":
3970 i = find_token(document.body, "\\begin_layout Pause", i)
3973 j = find_end_of_layout(document.body, i)
3975 document.warning("Malformed LyX document: Can't find end of Pause layout")
3979 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\pause")
3980 for p in range(i, j):
3983 arg = find_token(document.body, "\\begin_inset Argument 1", i, j)
3985 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3986 endPlain = find_end_of_layout(document.body, beginPlain)
3987 endInset = find_end_of_inset(document.body, p)
3988 content = document.body[beginPlain + 1 : endPlain]
3990 endlay = endlay - len(document.body[p : endInset + 1])
3992 del document.body[p : endInset + 1]
3993 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3995 document.body[i : i + 1] = subst
3999 def revert_powerdot_itemargs(document):
4000 " Reverts powerdot item arguments to ERT "
4002 if document.textclass != "powerdot":
4006 list_layouts = ["Itemize", "ItemizeType1", "Enumerate", "EnumerateType1"]
4007 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
4010 i = find_token(document.body, "\\begin_inset Argument", i)
4013 # Find containing paragraph layout
4014 parent = get_containing_layout(document.body, i)
4016 document.warning("Malformed LyX document: Can't find parent paragraph layout")
4021 realparbeg = parent[3]
4022 layoutname = parent[0]
4024 for p in range(parbeg, parend):
4028 if layoutname in list_layouts:
4029 m = rx.match(document.body[p])
4032 if argnr == "item:1":
4033 j = find_end_of_inset(document.body, i)
4034 # Find containing paragraph layout
4035 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
4036 endPlain = find_end_of_layout(document.body, beginPlain)
4037 content = document.body[beginPlain + 1 : endPlain]
4038 del document.body[i:j+1]
4039 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
4040 document.body[realparbeg : realparbeg] = subst
4041 elif argnr == "item:2":
4042 j = find_end_of_inset(document.body, i)
4043 # Find containing paragraph layout
4044 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
4045 endPlain = find_end_of_layout(document.body, beginPlain)
4046 content = document.body[beginPlain + 1 : endPlain]
4047 del document.body[i:j+1]
4048 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
4049 document.body[realparbeg : realparbeg] = subst
4054 def revert_powerdot_columns(document):
4055 " Reverts powerdot twocolumn to TeX-code "
4056 if document.textclass != "powerdot":
4059 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
4062 i = find_token(document.body, "\\begin_layout Twocolumn", i)
4065 j = find_end_of_layout(document.body, i)
4067 document.warning("Malformed LyX document: Can't find end of Twocolumn layout")
4071 document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
4072 endlay += len(put_cmd_in_ert("}"))
4073 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\twocolumn")
4074 for p in range(i, j):
4077 m = rx.match(document.body[p])
4081 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
4082 endPlain = find_end_of_layout(document.body, beginPlain)
4083 endInset = find_end_of_inset(document.body, p)
4084 content = document.body[beginPlain + 1 : endPlain]
4086 endlay = endlay - len(document.body[p : endInset + 1])
4088 del document.body[p : endInset + 1]
4089 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
4091 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
4092 endPlain = find_end_of_layout(document.body, beginPlain)
4093 endInset = find_end_of_inset(document.body, p)
4094 content = document.body[beginPlain + 1 : endPlain]
4096 endlay = endlay - len(document.body[p : endInset + 1])
4098 del document.body[p : endInset + 1]
4099 subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
4101 subst += put_cmd_in_ert("{")
4102 document.body[i : i + 1] = subst
4106 def revert_mbox_fbox(document):
4107 'Convert revert mbox/fbox boxes to TeX-code'
4110 i = find_token(document.body, "\\begin_inset Box", i)
4113 j = find_token(document.body, "width", i)
4115 document.warning("Malformed LyX document: Can't find box width")
4117 width = get_value(document.body, "width", j)
4118 k = find_end_of_inset(document.body, j)
4120 document.warning("Malformed LyX document: Can't find end of box inset")
4123 BeginLayout = find_token(document.body, "\\begin_layout Plain Layout", j)
4124 EndLayout = find_token(document.body, "\\end_layout", BeginLayout)
4125 # replace if width is ""
4127 document.body[EndLayout:k + 1] = put_cmd_in_ert("}")
4128 if document.body[i] == "\\begin_inset Box Frameless":
4129 document.body[i:BeginLayout + 1] = put_cmd_in_ert("\\mbox{")
4130 if document.body[i] == "\\begin_inset Box Boxed":
4131 document.body[i:BeginLayout + 1] = put_cmd_in_ert("\\fbox{")
4135 def revert_starred_caption(document):
4136 " Reverts unnumbered longtable caption insets "
4140 i = find_token(document.body, "\\begin_inset Caption LongTableNoNumber", i)
4143 # This is not equivalent, but since the caption inset is a full blown
4144 # text inset a true conversion to ERT is too difficult.
4145 document.body[i] = "\\begin_inset Caption Standard"
4149 def revert_forced_local_layout(document):
4152 i = find_token(document.header, "\\begin_forced_local_layout", i)
4155 j = find_end_of(document.header, i, "\\begin_forced_local_layout", "\\end_forced_local_layout")
4157 # this should not happen
4159 regexp = re.compile(r'\s*forcelocal', re.IGNORECASE)
4160 k = find_re(document.header, regexp, i, j)
4162 del document.header[k]
4164 k = find_re(document.header, regexp, i, j)
4165 k = find_token(document.header, "\\begin_local_layout", 0)
4167 document.header[i] = "\\begin_local_layout"
4168 document.header[j] = "\\end_local_layout"
4170 l = find_end_of(document.header, k, "\\begin_local_layout", "\\end_local_layout")
4172 # this should not happen
4174 lines = document.header[i+1 : j]
4176 document.header[k+1 : k+1] = lines
4177 document.header[i : j ] = []
4179 document.header[i : j ] = []
4180 document.header[k+1 : k+1] = lines
4183 def revert_aa1(document):
4184 " Reverts InsetArguments of aa to TeX-code "
4185 if document.textclass == "aa":
4189 i = find_token(document.body, "\\begin_layout Abstract (structured)", i)
4191 revert_Argument_to_TeX_brace(document, i, 0, 1, 4, False, False)
4197 def revert_aa2(document):
4198 " Reverts InsetArguments of aa to TeX-code "
4199 if document.textclass == "aa":
4203 i = find_token(document.body, "\\begin_layout Abstract (structured)", i)
4205 document.body[i] = "\\begin_layout Abstract"
4211 def revert_tibetan(document):
4212 "Set the document language for Tibetan to English"
4214 if document.language == "tibetan":
4215 document.language = "english"
4216 i = find_token(document.header, "\\language", 0)
4218 document.header[i] = "\\language english"
4220 while j < len(document.body):
4221 j = find_token(document.body, "\\lang tibetan", j)
4223 document.body[j] = document.body[j].replace("\\lang tibetan", "\\lang english")
4226 j = len(document.body)
4235 # the idea here is that we will have a sequence of chunk paragraphs
4236 # we want to convert them to paragraphs in a chunk inset
4237 # the last will be discarded
4238 # the first should look like: <<FROGS>>=
4239 # will will discard the delimiters, and put the contents into the
4240 # optional argument of the inset
4241 def convert_chunks(document):
4242 first_re = re.compile(r'<<(.*)>>=')
4245 # the beginning of this sequence
4247 # find start of a block of chunks
4248 i = find_token(document.body, "\\begin_layout Chunk", i)
4256 # process the one we just found
4257 j = find_end_of_layout(document.body, i)
4259 document.warning("Malformed LyX documents. Can't find end of Chunk layout!")
4261 thischunk = "".join(document.body[i + 1:j])
4262 contents.append(document.body[i + 1:j])
4264 if thischunk == "@":
4267 # look for the next one
4269 i = find_token(document.body, "\\begin_layout", i)
4273 layout = get_value(document.body, "\\begin_layout", i)
4274 #sys.stderr.write(layout+ '\n')
4275 if layout != "Chunk":
4279 # error, but we can try to continue
4286 # the last chunk should simply have an "@" in it
4288 if ''.join(contents[-1]) != "@":
4289 document.warning("Unexpected chunk contents.")
4294 # the first item should look like: <<FROGS>>=
4295 # we want the inside
4296 optarg = ' '.join(contents[0])
4298 match = first_re.search(optarg)
4300 optarg = match.groups()[0]
4303 newstuff = ['\\begin_layout Standard',
4304 '\\begin_inset Flex Chunk',
4306 '\\begin_layout Plain Layout', '']
4310 ['\\begin_inset Argument 1',
4312 '\\begin_layout Plain Layout',
4320 newstuff.extend(['', '\\begin_layout Plain Layout', ''])
4324 newstuff.append('\\end_layout')
4326 newstuff.extend(['', '\\end_inset', '', '\\end_layout', ''])
4328 document.body[start:end] = newstuff
4330 k += len(newstuff) - (end - start)
4333 def revert_chunks(document):
4336 i = find_token(document.body, "\\begin_inset Flex Chunk", i)
4340 iend = find_end_of_inset(document.body, i)
4342 document.warning("Can't find end of Chunk!")
4346 # Look for optional argument
4348 ostart = find_token(document.body, "\\begin_inset Argument 1", i, iend)
4350 oend = find_end_of_inset(document.body, ostart)
4351 k = find_token(document.body, "\\begin_layout Plain Layout", ostart, oend)
4353 document.warning("Malformed LyX document: Can't find argument contents!")
4355 m = find_end_of_layout(document.body, k)
4356 optarg = "".join(document.body[k+1:m])
4359 # We now remove the optional argument, so we have something
4360 # uniform on which to work
4361 document.body[ostart : oend + 1] = []
4362 # iend is now invalid
4363 iend = find_end_of_inset(document.body, i)
4365 retval = get_containing_layout(document.body, i)
4367 document.warning("Can't find containing layout for Chunk!")
4370 (lname, lstart, lend, pstart) = retval
4371 # we now want to work through the various paragraphs, and collect their contents
4375 k = find_token(document.body, "\\begin_layout Plain Layout", k, lend)
4378 j = find_end_of_layout(document.body, k)
4380 document.warning("Can't find end of layout inside chunk!")
4382 parlist.append(document.body[k+1:j])
4384 # we now need to wrap all of these paragraphs in chunks
4387 newlines.extend(["\\begin_layout Chunk", "", "<<" + optarg + ">>=", "\\end_layout", ""])
4388 for stuff in parlist:
4389 newlines.extend(["\\begin_layout Chunk"] + stuff + ["\\end_layout", ""])
4390 newlines.extend(["\\begin_layout Chunk", "", "@", "\\end_layout", ""])
4391 # replace old content with new content
4392 document.body[lstart : lend + 1] = newlines
4393 i = lstart + len(newlines)
4400 supported_versions = ["2.1.0","2.1"]
4403 [415, [convert_undertilde]],
4405 [417, [convert_japanese_encodings]],
4408 [420, [convert_biblio_style]],
4409 [421, [convert_longtable_captions]],
4410 [422, [convert_use_packages]],
4411 [423, [convert_use_mathtools]],
4412 [424, [convert_cite_engine_type]],
4416 [428, [convert_cell_rotation]],
4417 [429, [convert_table_rotation]],
4418 [430, [convert_listoflistings]],
4419 [431, [convert_use_amssymb]],
4421 [433, [convert_armenian]],
4429 [441, [convert_mdnomath]],
4434 [446, [convert_latexargs]],
4435 [447, [convert_IEEEtran, convert_AASTeX, convert_AGUTeX, convert_IJMP, convert_SIGPLAN, convert_SIGGRAPH, convert_EuropeCV, convert_Initials, convert_ModernCV]],
4436 [448, [convert_literate]],
4439 [451, [convert_beamerargs, convert_againframe_args, convert_corollary_args, convert_quote_args]],
4440 [452, [convert_beamerblocks]],
4441 [453, [convert_use_stmaryrd]],
4442 [454, [convert_overprint]],
4444 [456, [convert_epigraph]],
4445 [457, [convert_use_stackrel]],
4446 [458, [convert_captioninsets, convert_captionlayouts]],
4451 [463, [convert_encodings]],
4452 [464, [convert_use_cancel]],
4453 [465, [convert_lyxframes, remove_endframes]],
4459 [471, [convert_cite_engine_type_default]],
4462 [474, [convert_chunks]],
4466 [473, [revert_chunks]],
4467 [472, [revert_tibetan]],
4468 [471, [revert_aa1,revert_aa2]],
4469 [470, [revert_cite_engine_type_default]],
4470 [469, [revert_forced_local_layout]],
4471 [468, [revert_starred_caption]],
4472 [467, [revert_mbox_fbox]],
4473 [466, [revert_iwona_fonts]],
4474 [465, [revert_powerdot_flexes, revert_powerdot_pause, revert_powerdot_itemargs, revert_powerdot_columns]],
4476 [463, [revert_use_cancel]],
4477 [462, [revert_encodings]],
4478 [461, [revert_new_libertines]],
4479 [460, [revert_kurier_fonts]],
4480 [459, [revert_IEEEtran_3]],
4481 [458, [revert_fragileframe, revert_newframes]],
4482 [457, [revert_captioninsets, revert_captionlayouts]],
4483 [456, [revert_use_stackrel]],
4484 [455, [revert_epigraph]],
4485 [454, [revert_frametitle]],
4486 [453, [revert_overprint]],
4487 [452, [revert_use_stmaryrd]],
4488 [451, [revert_beamerblocks]],
4489 [450, [revert_beamerargs, revert_beamerargs2, revert_beamerargs3, revert_beamerflex]],
4490 [449, [revert_garamondx, revert_garamondx_newtxmath]],
4491 [448, [revert_itemargs]],
4492 [447, [revert_literate]],
4493 [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]],
4494 [445, [revert_latexargs]],
4495 [444, [revert_uop]],
4496 [443, [revert_biolinum]],
4498 [441, [revert_newtxmath]],
4499 [440, [revert_mdnomath]],
4500 [439, [revert_mathfonts]],
4501 [438, [revert_minionpro]],
4502 [437, [revert_ipadeco, revert_ipachar]],
4503 [436, [revert_texgyre]],
4504 [435, [revert_mathdesign]],
4505 [434, [revert_txtt]],
4506 [433, [revert_libertine]],
4507 [432, [revert_armenian]],
4508 [431, [revert_languages, revert_ancientgreek]],
4509 [430, [revert_use_amssymb]],
4510 [429, [revert_listoflistings]],
4511 [428, [revert_table_rotation]],
4512 [427, [revert_cell_rotation]],
4513 [426, [revert_tipa]],
4514 [425, [revert_verbatim]],
4515 [424, [revert_cancel]],
4516 [423, [revert_cite_engine_type]],
4517 [422, [revert_use_mathtools]],
4518 [421, [revert_use_packages]],
4519 [420, [revert_longtable_captions]],
4520 [419, [revert_biblio_style]],
4521 [418, [revert_australian]],
4522 [417, [revert_justification]],
4523 [416, [revert_japanese_encodings]],
4524 [415, [revert_negative_space, revert_math_spaces]],
4525 [414, [revert_undertilde]],
4526 [413, [revert_visible_space]]
4530 if __name__ == "__main__":