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 document.body[p + 4].startswith("<"):
2182 # This is an overlay specification (without ERT)
2184 document.body[p + 4] = document.body[p + 4][1:]
2185 if document.body[p + 4].endswith(">"):
2187 document.body[p + 4] = document.body[p + 4][:-1]
2188 elif layoutname != "Itemize":
2190 document.body[p] = "\\begin_inset Argument 2"
2195 # Helper function for the frame conversion routines
2197 # FIXME: This method currently requires the arguments to be either
2198 # * In one (whole) ERT each: <ERT>[<arg1>]</ERT><ERT><arg2></ERT><ERT>[arg3]</ERT>
2199 # * Altogether in one whole ERT: <ERT>[<arg1>]<arg2>[arg3]</ERT>
2200 # If individual arguments mix ERT and non-ERT or are splitted
2201 # over several ERTs, the parsing fails.
2202 def convert_beamerframeargs(document, i, parbeg):
2205 if document.body[parbeg] != "\\begin_inset ERT":
2207 ertend = find_end_of_inset(document.body, parbeg)
2209 document.warning("Malformed LyX document: missing ERT \\end_inset")
2211 ertcont = parbeg + 5
2212 if document.body[ertcont].startswith("[<"):
2213 # This is a default overlay specification
2215 document.body[ertcont] = document.body[ertcont][2:]
2216 if document.body[ertcont].endswith(">]"):
2218 document.body[ertcont] = document.body[ertcont][:-2]
2219 elif document.body[ertcont].endswith("]"):
2221 tok = document.body[ertcont].find('>][')
2223 subst = [document.body[ertcont][:tok],
2224 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2225 'status collapsed', '', '\\begin_layout Plain Layout',
2226 document.body[ertcont][tok + 3:-1]]
2227 document.body[ertcont : ertcont + 1] = subst
2229 # Convert to ArgInset
2230 document.body[parbeg] = "\\begin_inset Argument 2"
2231 elif document.body[ertcont].startswith("<"):
2232 # This is an overlay specification
2234 document.body[ertcont] = document.body[ertcont][1:]
2235 if document.body[ertcont].endswith(">"):
2237 document.body[ertcont] = document.body[ertcont][:-1]
2238 # Convert to ArgInset
2239 document.body[parbeg] = "\\begin_inset Argument 1"
2240 elif document.body[ertcont].endswith(">]"):
2242 tok = document.body[ertcont].find('>[<')
2244 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2245 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2246 'status collapsed', '', '\\begin_layout Plain Layout',
2247 document.body[ertcont][tok + 3:-2]]
2248 # Convert to ArgInset
2249 document.body[parbeg] = "\\begin_inset Argument 1"
2251 elif document.body[ertcont].endswith("]"):
2253 tok = document.body[ertcont].find('>[<')
2256 tokk = document.body[ertcont].find('>][')
2258 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2259 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2260 'status collapsed', '', '\\begin_layout Plain Layout',
2261 document.body[ertcont][tok + 3:tokk],
2262 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2263 'status collapsed', '', '\\begin_layout Plain Layout',
2264 document.body[ertcont][tokk + 3:-1]]
2267 tokk = document.body[ertcont].find('>[')
2269 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tokk],
2270 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2271 'status collapsed', '', '\\begin_layout Plain Layout',
2272 document.body[ertcont][tokk + 2:-1]]
2274 # Convert to ArgInset
2275 document.body[parbeg] = "\\begin_inset Argument 1"
2276 elif document.body[ertcont].startswith("["):
2277 # This is an ERT option
2279 document.body[ertcont] = document.body[ertcont][1:]
2280 if document.body[ertcont].endswith("]"):
2282 document.body[ertcont] = document.body[ertcont][:-1]
2283 # Convert to ArgInset
2284 document.body[parbeg] = "\\begin_inset Argument 3"
2290 def convert_againframe_args(document):
2291 " Converts beamer AgainFrame to new layout "
2293 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2294 if document.textclass not in beamer_classes:
2299 i = find_token(document.body, "\\begin_layout AgainFrame", i)
2302 parent = get_containing_layout(document.body, i)
2304 document.warning("Wrong parent layout!")
2308 # Convert ERT arguments
2309 # FIXME: See restrictions in convert_beamerframeargs method
2310 ertend = convert_beamerframeargs(document, i, parbeg)
2316 def convert_corollary_args(document):
2317 " Converts beamer corrolary-style ERT arguments native InsetArgs "
2319 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2320 if document.textclass not in beamer_classes:
2323 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2324 for lay in corollary_layouts:
2327 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2330 parent = get_containing_layout(document.body, i)
2332 document.warning("Wrong parent layout!")
2336 if document.body[parbeg] == "\\begin_inset ERT":
2337 ertcont = parbeg + 5
2338 if document.body[ertcont].startswith("<"):
2339 # This is an overlay specification
2341 document.body[ertcont] = document.body[ertcont][1:]
2342 if document.body[ertcont].endswith(">"):
2344 document.body[ertcont] = document.body[ertcont][:-1]
2345 elif document.body[ertcont].endswith("]"):
2347 tok = document.body[ertcont].find('>[')
2349 subst = [document.body[ertcont][:tok],
2350 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2351 'status collapsed', '', '\\begin_layout Plain Layout',
2352 document.body[ertcont][tok + 2:-1]]
2353 document.body[ertcont : ertcont + 1] = subst
2354 # Convert to ArgInset
2355 document.body[parbeg] = "\\begin_inset Argument 1"
2358 elif document.body[ertcont].startswith("["):
2359 if document.body[ertcont].endswith("]"):
2360 # This is an ERT option
2362 document.body[ertcont] = document.body[ertcont][1:]
2364 document.body[ertcont] = document.body[ertcont][:-1]
2365 # Convert to ArgInset
2366 document.body[parbeg] = "\\begin_inset Argument 2"
2368 convert_TeX_brace_to_Argument(document, i, 2, 2, False, True, True)
2375 def convert_quote_args(document):
2376 " Converts beamer quote style ERT args to native InsetArgs "
2378 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2379 if document.textclass not in beamer_classes:
2382 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2383 for lay in quote_layouts:
2386 i = find_token(document.body, "\\begin_layout " + lay, i)
2389 parent = get_containing_layout(document.body, i)
2391 document.warning("Wrong parent layout!")
2395 if document.body[parbeg] == "\\begin_inset ERT":
2396 if document.body[i + 6].startswith("<"):
2397 # This is an overlay specification
2399 document.body[i + 6] = document.body[i + 6][1:]
2400 if document.body[i + 6].endswith(">"):
2402 document.body[i + 6] = document.body[i + 6][:-1]
2403 # Convert to ArgInset
2404 document.body[i + 1] = "\\begin_inset Argument 1"
2408 def revert_beamerargs(document):
2409 " Reverts beamer arguments to old layout "
2411 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2412 if document.textclass not in beamer_classes:
2416 list_layouts = ["Itemize", "Enumerate", "Description"]
2417 headings = ["Part", "Section", "Section*", "Subsection", "Subsection*",
2418 "Subsubsection", "Subsubsection*", "FrameSubtitle", "NoteItem"]
2419 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2420 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2421 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2424 i = find_token(document.body, "\\begin_inset Argument", i)
2427 # Find containing paragraph layout
2428 parent = get_containing_layout(document.body, i)
2430 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2435 realparbeg = parent[3]
2436 layoutname = parent[0]
2438 for p in range(parbeg, parend):
2442 if layoutname in headings:
2443 m = rx.match(document.body[p])
2447 # Find containing paragraph layout
2448 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2449 endPlain = find_end_of_layout(document.body, beginPlain)
2450 endInset = find_end_of_inset(document.body, p)
2451 argcontent = document.body[beginPlain + 1 : endPlain]
2453 realparend = realparend - len(document.body[p : endInset + 1])
2455 del document.body[p : endInset + 1]
2456 if layoutname == "FrameSubtitle":
2457 pre = put_cmd_in_ert("\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2458 elif layoutname == "NoteItem":
2459 pre = put_cmd_in_ert("\\note<") + argcontent + put_cmd_in_ert(">[item]")
2460 elif layoutname.endswith('*'):
2461 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower()[:-1] + "<") + argcontent + put_cmd_in_ert(">*")
2463 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2464 secarg = find_token(document.body, "\\begin_inset Argument 2", parbeg, parend)
2466 # Find containing paragraph layout
2467 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", secarg)
2468 endPlain = find_end_of_layout(document.body, beginPlain)
2469 endInset = find_end_of_inset(document.body, secarg)
2470 argcontent = document.body[beginPlain + 1 : endPlain]
2472 realparend = realparend - len(document.body[secarg : endInset + 1])
2473 del document.body[secarg : endInset + 1]
2474 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2475 pre += put_cmd_in_ert("{")
2476 document.body[parbeg] = "\\begin_layout Standard"
2477 document.body[realparbeg : realparbeg] = pre
2478 pe = find_end_of_layout(document.body, parbeg)
2479 post = put_cmd_in_ert("}")
2480 document.body[pe : pe] = post
2481 realparend += len(pre) + len(post)
2482 if layoutname == "AgainFrame":
2483 m = rx.match(document.body[p])
2487 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2488 endPlain = find_end_of_layout(document.body, beginPlain)
2489 endInset = find_end_of_inset(document.body, p)
2490 content = document.body[beginPlain + 1 : endPlain]
2492 realparend = realparend - len(document.body[p : endInset + 1])
2494 del document.body[p : endInset + 1]
2495 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2496 document.body[realparbeg : realparbeg] = subst
2497 if layoutname == "Overprint":
2498 m = rx.match(document.body[p])
2502 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2503 endPlain = find_end_of_layout(document.body, beginPlain)
2504 endInset = find_end_of_inset(document.body, p)
2505 content = document.body[beginPlain + 1 : endPlain]
2507 realparend = realparend - len(document.body[p : endInset + 1])
2509 del document.body[p : endInset + 1]
2510 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2511 document.body[realparbeg : realparbeg] = subst
2512 if layoutname == "OverlayArea":
2513 m = rx.match(document.body[p])
2517 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2518 endPlain = find_end_of_layout(document.body, beginPlain)
2519 endInset = find_end_of_inset(document.body, p)
2520 content = document.body[beginPlain + 1 : endPlain]
2522 realparend = realparend - len(document.body[p : endInset + 1])
2524 del document.body[p : endInset + 1]
2525 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2526 document.body[realparbeg : realparbeg] = subst
2527 if layoutname in list_layouts:
2528 m = rx.match(document.body[p])
2532 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2533 endPlain = find_end_of_layout(document.body, beginPlain)
2534 endInset = find_end_of_inset(document.body, p)
2535 content = document.body[beginPlain + 1 : endPlain]
2536 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2537 realparend = realparend + len(subst) - len(content)
2538 document.body[beginPlain + 1 : endPlain] = subst
2539 elif argnr == "item:1":
2540 j = find_end_of_inset(document.body, i)
2541 # Find containing paragraph layout
2542 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2543 endPlain = find_end_of_layout(document.body, beginPlain)
2544 content = document.body[beginPlain + 1 : endPlain]
2545 del document.body[i:j+1]
2546 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2547 document.body[realparbeg : realparbeg] = subst
2548 elif argnr == "item:2":
2549 j = find_end_of_inset(document.body, i)
2550 # Find containing paragraph layout
2551 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2552 endPlain = find_end_of_layout(document.body, beginPlain)
2553 content = document.body[beginPlain + 1 : endPlain]
2554 del document.body[i:j+1]
2555 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2556 document.body[realparbeg : realparbeg] = subst
2557 if layoutname in quote_layouts:
2558 m = rx.match(document.body[p])
2562 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2563 endPlain = find_end_of_layout(document.body, beginPlain)
2564 endInset = find_end_of_inset(document.body, p)
2565 content = document.body[beginPlain + 1 : endPlain]
2567 realparend = realparend - len(document.body[p : endInset + 1])
2569 del document.body[p : endInset + 1]
2570 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2571 document.body[realparbeg : realparbeg] = subst
2572 if layoutname in corollary_layouts:
2573 m = rx.match(document.body[p])
2577 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2578 endPlain = find_end_of_layout(document.body, beginPlain)
2579 endInset = find_end_of_inset(document.body, p)
2580 content = document.body[beginPlain + 1 : endPlain]
2582 realparend = realparend - len(document.body[p : endInset + 1])
2584 del document.body[p : endInset + 1]
2585 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2586 document.body[realparbeg : realparbeg] = subst
2591 def revert_beamerargs2(document):
2592 " Reverts beamer arguments to old layout, step 2 "
2594 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2595 if document.textclass not in beamer_classes:
2599 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
2600 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2601 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2604 i = find_token(document.body, "\\begin_inset Argument", i)
2607 # Find containing paragraph layout
2608 parent = get_containing_layout(document.body, i)
2610 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2615 realparbeg = parent[3]
2616 layoutname = parent[0]
2618 for p in range(parbeg, parend):
2622 if layoutname in shifted_layouts:
2623 m = rx.match(document.body[p])
2627 document.body[p] = "\\begin_inset Argument 1"
2628 if layoutname in corollary_layouts:
2629 m = rx.match(document.body[p])
2633 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2634 endPlain = find_end_of_layout(document.body, beginPlain)
2635 endInset = find_end_of_inset(document.body, p)
2636 content = document.body[beginPlain + 1 : endPlain]
2638 realparend = realparend - len(document.body[p : endInset + 1])
2640 del document.body[p : endInset + 1]
2641 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2642 document.body[realparbeg : realparbeg] = subst
2643 if layoutname == "OverlayArea":
2644 m = rx.match(document.body[p])
2648 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2649 endPlain = find_end_of_layout(document.body, beginPlain)
2650 endInset = find_end_of_inset(document.body, p)
2651 content = document.body[beginPlain + 1 : endPlain]
2653 realparend = realparend - len(document.body[p : endInset + 1])
2655 del document.body[p : endInset + 1]
2656 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2657 document.body[realparbeg : realparbeg] = subst
2658 if layoutname == "AgainFrame":
2659 m = rx.match(document.body[p])
2663 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2664 endPlain = find_end_of_layout(document.body, beginPlain)
2665 endInset = find_end_of_inset(document.body, p)
2666 content = document.body[beginPlain + 1 : endPlain]
2668 realparend = realparend - len(document.body[p : endInset + 1])
2670 del document.body[p : endInset + 1]
2671 subst = put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
2672 document.body[realparbeg : realparbeg] = subst
2676 def revert_beamerargs3(document):
2677 " Reverts beamer arguments to old layout, step 3 "
2679 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2680 if document.textclass not in beamer_classes:
2683 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2686 i = find_token(document.body, "\\begin_inset Argument", i)
2689 # Find containing paragraph layout
2690 parent = get_containing_layout(document.body, i)
2692 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2697 realparbeg = parent[3]
2698 layoutname = parent[0]
2700 for p in range(parbeg, parend):
2704 if layoutname == "AgainFrame":
2705 m = rx.match(document.body[p])
2709 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2710 endPlain = find_end_of_layout(document.body, beginPlain)
2711 endInset = find_end_of_inset(document.body, p)
2712 content = document.body[beginPlain + 1 : endPlain]
2714 realparend = realparend - len(document.body[p : endInset + 1])
2716 del document.body[p : endInset + 1]
2717 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2718 document.body[realparbeg : realparbeg] = subst
2722 def revert_beamerflex(document):
2723 " Reverts beamer Flex insets "
2725 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2726 if document.textclass not in beamer_classes:
2729 new_flexes = {"Bold" : "\\textbf", "Emphasize" : "\\emph", "Only" : "\\only",
2730 "Uncover" : "\\uncover", "Visible" : "\\visible",
2731 "Invisible" : "\\invisible", "Alternative" : "\\alt",
2732 "Beamer_Note" : "\\note"}
2733 old_flexes = {"Alert" : "\\alert", "Structure" : "\\structure"}
2734 rx = re.compile(r'^\\begin_inset Flex (.+)$')
2738 i = find_token(document.body, "\\begin_inset Flex", i)
2741 m = rx.match(document.body[i])
2743 flextype = m.group(1)
2744 z = find_end_of_inset(document.body, i)
2746 document.warning("Can't find end of Flex " + flextype + " inset.")
2749 if flextype in new_flexes:
2750 pre = put_cmd_in_ert(new_flexes[flextype])
2751 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2753 argend = find_end_of_inset(document.body, arg)
2755 document.warning("Can't find end of Argument!")
2758 # Find containing paragraph layout
2759 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2760 endPlain = find_end_of_layout(document.body, beginPlain)
2761 argcontent = document.body[beginPlain + 1 : endPlain]
2763 z = z - len(document.body[arg : argend + 1])
2765 del document.body[arg : argend + 1]
2766 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2767 arg = find_token(document.body, "\\begin_inset Argument 2", i, z)
2769 argend = find_end_of_inset(document.body, arg)
2771 document.warning("Can't find end of Argument!")
2774 # Find containing paragraph layout
2775 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2776 endPlain = find_end_of_layout(document.body, beginPlain)
2777 argcontent = document.body[beginPlain + 1 : endPlain]
2779 z = z - len(document.body[arg : argend + 1])
2781 del document.body[arg : argend + 1]
2782 if flextype == "Alternative":
2783 pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
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
2795 elif flextype in old_flexes:
2796 pre = put_cmd_in_ert(old_flexes[flextype])
2797 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2801 argend = find_end_of_inset(document.body, arg)
2803 document.warning("Can't find end of Argument!")
2806 # Find containing paragraph layout
2807 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2808 endPlain = find_end_of_layout(document.body, beginPlain)
2809 argcontent = document.body[beginPlain + 1 : endPlain]
2811 z = z - len(document.body[arg : argend + 1])
2813 del document.body[arg : argend + 1]
2814 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2815 pre += put_cmd_in_ert("{")
2816 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2817 endPlain = find_end_of_layout(document.body, beginPlain)
2819 z = z - len(document.body[i : beginPlain + 1])
2821 document.body[i : beginPlain + 1] = pre
2822 post = put_cmd_in_ert("}")
2823 document.body[z - 2 : z + 1] = post
2828 def revert_beamerblocks(document):
2829 " Reverts beamer block arguments to ERT "
2831 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2832 if document.textclass not in beamer_classes:
2835 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2837 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2840 i = find_token(document.body, "\\begin_inset Argument", i)
2843 # Find containing paragraph layout
2844 parent = get_containing_layout(document.body, i)
2846 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2851 realparbeg = parent[3]
2852 layoutname = parent[0]
2854 for p in range(parbeg, parend):
2858 if layoutname in blocks:
2859 m = rx.match(document.body[p])
2863 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2864 endPlain = find_end_of_layout(document.body, beginPlain)
2865 endInset = find_end_of_inset(document.body, p)
2866 content = document.body[beginPlain + 1 : endPlain]
2868 realparend = realparend - len(document.body[p : endInset + 1])
2870 del document.body[p : endInset + 1]
2871 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2872 document.body[realparbeg : realparbeg] = subst
2874 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2875 endPlain = find_end_of_layout(document.body, beginPlain)
2876 endInset = find_end_of_inset(document.body, p)
2877 content = document.body[beginPlain + 1 : endPlain]
2879 realparend = realparend - len(document.body[p : endInset + 1])
2881 del document.body[p : endInset + 1]
2882 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2883 document.body[realparbeg : realparbeg] = subst
2888 def convert_beamerblocks(document):
2889 " Converts beamer block ERT args to native InsetArgs "
2891 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2892 if document.textclass not in beamer_classes:
2895 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2899 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2902 parent = get_containing_layout(document.body, i)
2903 if parent == False or parent[1] != i:
2904 document.warning("Wrong parent layout!")
2911 if document.body[parbeg] == "\\begin_inset ERT":
2912 ertcontfirstline = parbeg + 5
2913 ertcontlastline = parend - 6
2915 if document.body[ertcontfirstline].startswith("<"):
2916 # This is an overlay specification
2918 document.body[ertcontfirstline] = document.body[ertcontfirstline][1:]
2919 if document.body[ertcontlastline].endswith(">"):
2921 document.body[ertcontlastline] = document.body[ertcontlastline][:-1]
2922 # Convert to ArgInset
2923 document.body[parbeg] = "\\begin_inset Argument 1"
2924 elif document.body[ertcontlastline].endswith("}"):
2926 document.body[ertcontlastline] = document.body[ertcontlastline][:-1]
2928 ertcontdivline = ertcontfirstline
2929 tok = document.body[ertcontdivline].find('>{')
2931 regexp = re.compile(r'.*>\{', re.IGNORECASE)
2932 ertcontdivline = find_re(document.body, regexp, ertcontfirstline, ertcontlastline)
2933 tok = document.body[ertcontdivline].find('>{')
2935 if ertcontfirstline < ertcontlastline:
2936 # Multiline ERT. Might contain TeX code. Embrace in ERT.
2937 document.body[ertcontlastline : ertcontlastline + 1] = [
2938 document.body[ertcontlastline], '\\end_layout', '', '\\end_inset']
2939 document.body[ertcontdivline : ertcontdivline + 1] = [document.body[ertcontdivline][:tok],
2940 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2941 'status collapsed', '', '\\begin_layout Plain Layout',
2942 '\\begin_inset ERT', '', 'status open' '', '\\begin_layout Plain Layout',
2943 document.body[ertcontdivline][tok + 2:]]
2945 document.body[ertcontdivline : ertcontdivline + 1] = [document.body[ertcontdivline][:tok],
2946 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2947 'status collapsed', '', '\\begin_layout Plain Layout',
2948 document.body[ertcontdivline][tok + 2:]]
2949 # Convert to ArgInset
2950 document.body[parbeg] = "\\begin_inset Argument 1"
2951 elif document.body[ertcontfirstline].startswith("{"):
2952 # This is the block title
2953 if document.body[ertcontlastline].endswith("}"):
2954 # strip off the braces
2955 document.body[ertcontfirstline] = document.body[ertcontfirstline][1:]
2956 document.body[ertcontlastline] = document.body[ertcontlastline][:-1]
2957 if ertcontfirstline < ertcontlastline:
2958 # Multiline ERT. Might contain TeX code. Embrace in ERT.
2959 document.body[parend : parend + 1] = [
2960 document.body[parend], '\\end_layout', '', '\\end_inset']
2961 document.body[parbeg : parbeg + 1] = ['\\begin_inset Argument 2',
2962 'status collapsed', '', '\\begin_layout Plain Layout',
2963 '\\begin_inset ERT', '']
2965 # Convert to ArgInset
2966 document.body[parbeg] = "\\begin_inset Argument 2"
2967 elif count_pars_in_inset(document.body, ertcontfirstline) > 1:
2968 # Multipar ERT. Skip this.
2971 convert_TeX_brace_to_Argument(document, i, 2, 2, False, True, False)
2974 j = find_end_of_layout(document.body, i)
2976 document.warning("end of layout not found!")
2977 k = find_token(document.body, "\\begin_inset Argument", i, j)
2979 document.warning("InsetArgument not found!")
2981 l = find_end_of_inset(document.body, k)
2982 m = find_token(document.body, "\\begin_inset ERT", l, j)
2985 ertcontfirstline = m + 5
2990 def convert_overprint(document):
2991 " Convert old beamer overprint layouts to ERT "
2993 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2994 if document.textclass not in beamer_classes:
2999 i = find_token(document.body, "\\begin_layout Overprint", i)
3002 # Find end of sequence
3003 j = find_end_of_sequence(document.body, i)
3005 document.warning("Malformed LyX document. Cannot find end of Overprint sequence!")
3009 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
3011 if document.body[j] == "\\end_deeper":
3012 esubst = ["", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
3014 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
3015 endseq = endseq + len(esubst) - len(document.body[j : j])
3016 document.body[j : j] = esubst
3017 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
3019 argend = find_end_of_layout(document.body, argbeg)
3021 document.warning("Malformed LyX document. Cannot find end of Overprint argument!")
3024 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3025 endPlain = find_end_of_layout(document.body, beginPlain)
3026 content = document.body[beginPlain + 1 : endPlain]
3028 endseq = endseq - len(document.body[argbeg : argend + 1])
3030 del document.body[argbeg : argend + 1]
3031 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3033 endseq = endseq - len(document.body[i : i])
3034 document.body[i : i] = subst + ["\\end_layout"]
3035 endseq += len(subst)
3037 for p in range(i, endseq):
3038 if document.body[p] == "\\begin_layout Overprint":
3039 document.body[p] = "\\begin_layout Standard"
3044 def revert_overprint(document):
3045 " Revert old beamer overprint layouts to ERT "
3047 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3048 if document.textclass not in beamer_classes:
3053 i = find_token(document.body, "\\begin_layout Overprint", i)
3056 # Find end of sequence
3057 j = find_end_of_sequence(document.body, i)
3059 document.warning("Malformed LyX document. Cannot find end of Overprint sequence!")
3063 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
3064 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}")
3065 endseq = endseq + len(esubst) - len(document.body[j : j])
3066 if document.body[j] == "\\end_deeper":
3067 document.body[j : j] = ["\\end_deeper", ""] + esubst
3069 document.body[j : j] = esubst
3072 if document.body[r] == "\\begin_deeper":
3073 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3075 document.body[r] = ""
3076 document.body[s] = ""
3080 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
3082 argend = find_end_of_inset(document.body, argbeg)
3084 document.warning("Malformed LyX document. Cannot find end of Overprint argument!")
3087 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3088 endPlain = find_end_of_layout(document.body, beginPlain)
3089 content = document.body[beginPlain + 1 : endPlain]
3091 endseq = endseq - len(document.body[argbeg : argend])
3093 del document.body[argbeg : argend + 1]
3094 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3096 endseq = endseq - len(document.body[i : i])
3097 document.body[i : i] = subst + ["\\end_layout"]
3098 endseq += len(subst)
3104 if document.body[p] == "\\begin_layout Overprint":
3105 q = find_end_of_layout(document.body, p)
3107 document.warning("Malformed LyX document. Cannot find end of Overprint layout!")
3110 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\onslide")
3111 argbeg = find_token(document.body, "\\begin_inset Argument item:1", p, q)
3113 argend = find_end_of_inset(document.body, argbeg)
3115 document.warning("Malformed LyX document. Cannot find end of Overprint item argument!")
3118 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3119 endPlain = find_end_of_layout(document.body, beginPlain)
3120 content = document.body[beginPlain + 1 : endPlain]
3122 endseq = endseq - len(document.body[argbeg : argend + 1])
3124 del document.body[argbeg : argend + 1]
3125 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3126 endseq = endseq - len(document.body[p : p + 1]) + len(subst)
3127 document.body[p : p + 1] = subst
3133 def revert_frametitle(document):
3134 " Reverts beamer frametitle layout to ERT "
3136 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3137 if document.textclass not in beamer_classes:
3140 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
3143 i = find_token(document.body, "\\begin_layout FrameTitle", i)
3146 j = find_end_of_layout(document.body, i)
3148 document.warning("Malformed LyX document: Can't find end of FrameTitle layout")
3152 document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
3153 endlay += len(put_cmd_in_ert("}"))
3154 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\frametitle")
3155 for p in range(i, j):
3158 m = rx.match(document.body[p])
3162 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3163 endPlain = find_end_of_layout(document.body, beginPlain)
3164 endInset = find_end_of_inset(document.body, p)
3165 content = document.body[beginPlain + 1 : endPlain]
3167 endlay = endlay - len(document.body[p : endInset + 1])
3169 del document.body[p : endInset + 1]
3170 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3172 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3173 endPlain = find_end_of_layout(document.body, beginPlain)
3174 endInset = find_end_of_inset(document.body, p)
3175 content = document.body[beginPlain + 1 : endPlain]
3177 endlay = endlay - len(document.body[p : endInset + 1])
3179 del document.body[p : endInset + 1]
3180 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3182 subst += put_cmd_in_ert("{")
3183 document.body[i : i + 1] = subst
3187 def convert_epigraph(document):
3188 " Converts memoir epigraph to new syntax "
3190 if document.textclass != "memoir":
3195 i = find_token(document.body, "\\begin_layout Epigraph", i)
3198 j = find_end_of_layout(document.body, i)
3200 document.warning("Malformed LyX document: Can't find end of Epigraph layout")
3205 ert = find_token(document.body, "\\begin_inset ERT", i, j)
3207 endInset = find_end_of_inset(document.body, ert)
3208 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", ert)
3209 endPlain = find_end_of_layout(document.body, beginPlain)
3210 ertcont = beginPlain + 2
3211 if document.body[ertcont] == "}{":
3213 # Convert to ArgInset
3214 endlay = endlay - 2 * len(document.body[j])
3215 begsubst = ['\\begin_inset Argument post:1', 'status collapsed', '',
3216 '\\begin_layout Plain Layout']
3217 endsubst = ['\\end_layout', '', '\\end_inset', '', document.body[j]]
3218 document.body[j : j + 1] = endsubst
3219 document.body[endInset + 1 : endInset + 1] = begsubst
3221 endlay += len(begsubst) + len(endsubst)
3222 endlay = endlay - len(document.body[ert : endInset + 1])
3223 del document.body[ert : endInset + 1]
3228 def revert_epigraph(document):
3229 " Reverts memoir epigraph argument to ERT "
3231 if document.textclass != "memoir":
3236 i = find_token(document.body, "\\begin_layout Epigraph", i)
3239 j = find_end_of_layout(document.body, i)
3241 document.warning("Malformed LyX document: Can't find end of Epigraph layout")
3246 p = find_token(document.body, "\\begin_layout Argument post:1", i, j)
3248 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3249 endPlain = find_end_of_layout(document.body, beginPlain)
3250 endInset = find_end_of_inset(document.body, p)
3251 content = document.body[beginPlain + 1 : endPlain]
3253 endlay = endlay - len(document.body[p : endInset + 1])
3255 del document.body[p : endInset + 1]
3256 subst += put_cmd_in_ert("}{") + content
3258 subst += put_cmd_in_ert("}{")
3260 document.body[j : j] = subst + document.body[j : j]
3264 def convert_captioninsets(document):
3265 " Converts caption insets to new syntax "
3269 i = find_token(document.body, "\\begin_inset Caption", i)
3272 document.body[i] = "\\begin_inset Caption Standard"
3276 def revert_captioninsets(document):
3277 " Reverts caption insets to old syntax "
3281 i = find_token(document.body, "\\begin_inset Caption Standard", i)
3284 document.body[i] = "\\begin_inset Caption"
3288 def convert_captionlayouts(document):
3289 " Convert caption layouts to caption insets. "
3292 "Captionabove": "Above",
3293 "Captionbelow": "Below",
3294 "FigCaption" : "FigCaption",
3295 "Table_Caption" : "Table",
3296 "CenteredCaption" : "Centered",
3297 "Bicaption" : "Bicaption",
3302 i = find_token(document.body, "\\begin_layout", i)
3305 val = get_value(document.body, "\\begin_layout", i)
3306 if val in caption_dict.keys():
3307 j = find_end_of_layout(document.body, i)
3309 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3312 document.body[j:j] = ["\\end_layout", "", "\\end_inset", "", ""]
3313 document.body[i:i+1] = ["\\begin_layout %s" % document.default_layout,
3314 "\\begin_inset Caption %s" % caption_dict[val], "",
3315 "\\begin_layout %s" % document.default_layout]
3319 def revert_captionlayouts(document):
3320 " Revert caption insets to caption layouts. "
3323 "Above" : "Captionabove",
3324 "Below" : "Captionbelow",
3325 "FigCaption" : "FigCaption",
3326 "Table" : "Table_Caption",
3327 "Centered" : "CenteredCaption",
3328 "Bicaption" : "Bicaption",
3332 rx = re.compile(r'^\\begin_inset Caption (\S+)$')
3334 i = find_token(document.body, "\\begin_inset Caption", i)
3338 m = rx.match(document.body[i])
3342 if val not in caption_dict.keys():
3346 # We either need to delete the previous \begin_layout line, or we
3347 # need to end the previous layout if this inset is not in the first
3348 # position of the paragraph.
3349 layout_before = find_token_backwards(document.body, "\\begin_layout", i)
3350 if layout_before == -1:
3351 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3353 layout_line = document.body[layout_before]
3354 del_layout_before = True
3355 l = layout_before + 1
3357 if document.body[l] != "":
3358 del_layout_before = False
3361 if del_layout_before:
3362 del document.body[layout_before:i]
3365 document.body[i:i] = ["\\end_layout", ""]
3368 # Find start of layout in the inset and end of inset
3369 j = find_token(document.body, "\\begin_layout", i)
3371 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3373 k = find_end_of_inset(document.body, i)
3375 document.warning("Malformed LyX document: Missing `\\end_inset'.")
3378 # We either need to delete the following \end_layout line, or we need
3379 # to restart the old layout if this inset is not at the paragraph end.
3380 layout_after = find_token(document.body, "\\end_layout", k)
3381 if layout_after == -1:
3382 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3384 del_layout_after = True
3386 while l < layout_after:
3387 if document.body[l] != "":
3388 del_layout_after = False
3391 if del_layout_after:
3392 del document.body[k+1:layout_after+1]
3394 document.body[k+1:k+1] = [layout_line, ""]
3396 # delete \begin_layout and \end_inset and replace \begin_inset with
3397 # "\begin_layout XXX". This works because we can only have one
3398 # paragraph in the caption inset: The old \end_layout will be recycled.
3399 del document.body[k]
3400 if document.body[k] == "":
3401 del document.body[k]
3402 del document.body[j]
3403 if document.body[j] == "":
3404 del document.body[j]
3405 document.body[i] = "\\begin_layout %s" % caption_dict[val]
3406 if document.body[i+1] == "":
3407 del document.body[i+1]
3411 def revert_fragileframe(document):
3412 " Reverts beamer FragileFrame layout to ERT "
3414 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3415 if document.textclass not in beamer_classes:
3420 i = find_token(document.body, "\\begin_layout FragileFrame", i)
3423 # Find end of sequence
3424 j = find_end_of_sequence(document.body, i)
3426 document.warning("Malformed LyX document. Cannot find end of FragileFrame sequence!")
3430 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{frame}")
3431 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{frame}")
3432 endseq = endseq + len(esubst) - len(document.body[j : j])
3433 if document.body[j] == "\\end_deeper":
3434 document.body[j : j] = ["\\end_deeper", ""] + esubst
3436 document.body[j : j] = esubst
3437 for q in range(i, j):
3438 if document.body[q] == "\\begin_layout FragileFrame":
3439 document.body[q] = "\\begin_layout %s" % document.default_layout
3442 if document.body[r] == "\\begin_deeper":
3443 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3445 document.body[r] = ""
3446 document.body[s] = ""
3450 for p in range(1, 5):
3451 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, j)
3454 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3455 endPlain = find_end_of_layout(document.body, beginPlain)
3456 endInset = find_end_of_inset(document.body, arg)
3457 content = document.body[beginPlain + 1 : endPlain]
3459 j = j - len(document.body[arg : endInset + 1])
3461 del document.body[arg : endInset + 1]
3462 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3464 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3465 endPlain = find_end_of_layout(document.body, beginPlain)
3466 endInset = find_end_of_inset(document.body, arg)
3467 content = document.body[beginPlain + 1 : endPlain]
3469 j = j - len(document.body[arg : endInset + 1])
3471 del document.body[arg : endInset + 1]
3472 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3474 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3475 endPlain = find_end_of_layout(document.body, beginPlain)
3476 endInset = find_end_of_inset(document.body, arg)
3477 content = document.body[beginPlain + 1 : endPlain]
3479 j = j - len(document.body[arg : endInset + 1])
3481 del document.body[arg : endInset + 1]
3482 subst += put_cmd_in_ert("[fragile,") + content + put_cmd_in_ert("]")
3484 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3485 endPlain = find_end_of_layout(document.body, beginPlain)
3486 endInset = find_end_of_inset(document.body, arg)
3487 content = document.body[beginPlain + 1 : endPlain]
3489 j = j - len(document.body[arg : endInset + 1])
3491 del document.body[arg : endInset + 1]
3492 subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
3494 subst += put_cmd_in_ert("[fragile]")
3496 document.body[i : i + 1] = subst
3500 def revert_newframes(document):
3501 " Reverts beamer Frame and PlainFrame layouts to old forms "
3503 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3504 if document.textclass not in beamer_classes:
3508 "Frame" : "BeginFrame",
3509 "PlainFrame" : "BeginPlainFrame",
3512 rx = re.compile(r'^\\begin_layout (\S+)$')
3515 i = find_token(document.body, "\\begin_layout", i)
3519 m = rx.match(document.body[i])
3523 if val not in frame_dict.keys():
3526 # Find end of sequence
3527 j = find_end_of_sequence(document.body, i)
3529 document.warning("Malformed LyX document. Cannot find end of Frame sequence!")
3533 subst = ["\\begin_layout %s" % frame_dict[val]]
3534 esubst = ["\\end_layout", "", "\\begin_layout EndFrame", "", "\\end_layout"]
3535 endseq = endseq + len(esubst) - len(document.body[j : j])
3536 if document.body[j] == "\\end_deeper":
3537 document.body[j : j] = ["\\end_deeper", ""] + esubst
3539 document.body[j : j] = esubst
3540 for q in range(i, j):
3541 if document.body[q] == "\\begin_layout %s" % val:
3542 document.body[q] = "\\begin_layout %s" % document.default_layout
3545 if document.body[r] == "\\begin_deeper":
3546 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3548 document.body[r] = ""
3549 document.body[s] = ""
3553 l = find_end_of_layout(document.body, i)
3554 for p in range(1, 5):
3555 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, l)
3558 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3559 endPlain = find_end_of_layout(document.body, beginPlain)
3560 endInset = find_end_of_inset(document.body, arg)
3561 content = document.body[beginPlain + 1 : endPlain]
3563 l = l - len(document.body[arg : endInset + 1])
3565 del document.body[arg : endInset + 1]
3566 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3568 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3569 endPlain = find_end_of_layout(document.body, beginPlain)
3570 endInset = find_end_of_inset(document.body, arg)
3571 content = document.body[beginPlain + 1 : endPlain]
3573 l = l - len(document.body[arg : endInset + 1])
3575 del document.body[arg : endInset + 1]
3576 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3578 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3579 endPlain = find_end_of_layout(document.body, beginPlain)
3580 endInset = find_end_of_inset(document.body, arg)
3581 content = document.body[beginPlain + 1 : endPlain]
3583 l = l - len(document.body[arg : endInset + 1])
3585 del document.body[arg : endInset + 1]
3586 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3588 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3589 endPlain = find_end_of_layout(document.body, beginPlain)
3590 endInset = find_end_of_inset(document.body, arg)
3591 content = document.body[beginPlain + 1 : endPlain]
3593 l = l - len(document.body[arg : endInset + 1])
3595 del document.body[arg : endInset + 1]
3598 document.body[i : i + 1] = subst
3601 # known encodings that do not change their names (same LyX and LaTeX names)
3602 known_enc_tuple = ("auto", "default", "ansinew", "applemac", "armscii8", "ascii",
3603 "cp437", "cp437de", "cp850", "cp852", "cp855", "cp858", "cp862", "cp865", "cp866",
3604 "cp1250", "cp1251", "cp1252", "cp1255", "cp1256", "cp1257", "koi8-r", "koi8-u",
3605 "pt154", "pt254", "tis620-0", "utf8", "utf8x", "utf8-plain")
3607 def convert_encodings(document):
3608 "Use the LyX names of the encodings instead of the LaTeX names."
3609 LaTeX2LyX_enc_dict = {
3610 "8859-6": "iso8859-6",
3611 "8859-8": "iso8859-8",
3613 "euc": "euc-jp-platex",
3618 "iso88595": "iso8859-5",
3619 "iso-8859-7": "iso8859-7",
3621 "jis": "jis-platex",
3623 "l7xenc": "iso8859-13",
3624 "latin1": "iso8859-1",
3625 "latin2": "iso8859-2",
3626 "latin3": "iso8859-3",
3627 "latin4": "iso8859-4",
3628 "latin5": "iso8859-9",
3629 "latin9": "iso8859-15",
3630 "latin10": "iso8859-16",
3631 "SJIS": "shift-jis",
3632 "sjis": "shift-jis-platex",
3635 i = find_token(document.header, "\\inputencoding" , 0)
3638 val = get_value(document.header, "\\inputencoding", i)
3639 if val in LaTeX2LyX_enc_dict.keys():
3640 document.header[i] = "\\inputencoding %s" % LaTeX2LyX_enc_dict[val]
3641 elif val not in known_enc_tuple:
3642 document.warning("Ignoring unknown input encoding: `%s'" % val)
3645 def revert_encodings(document):
3646 """Revert to using the LaTeX names of the encodings instead of the LyX names.
3647 Also revert utf8-platex to sjis, the language default when using Japanese.
3649 LyX2LaTeX_enc_dict = {
3654 "euc-jp-platex": "euc",
3657 "iso8859-1": "latin1",
3658 "iso8859-2": "latin2",
3659 "iso8859-3": "latin3",
3660 "iso8859-4": "latin4",
3661 "iso8859-5": "iso88595",
3662 "iso8859-6": "8859-6",
3663 "iso8859-7": "iso-8859-7",
3664 "iso8859-8": "8859-8",
3665 "iso8859-9": "latin5",
3666 "iso8859-13": "l7xenc",
3667 "iso8859-15": "latin9",
3668 "iso8859-16": "latin10",
3670 "jis-platex": "jis",
3671 "shift-jis": "SJIS",
3672 "shift-jis-platex": "sjis",
3674 "utf8-platex": "sjis"
3676 i = find_token(document.header, "\\inputencoding" , 0)
3679 val = get_value(document.header, "\\inputencoding", i)
3680 if val in LyX2LaTeX_enc_dict.keys():
3681 document.header[i] = "\\inputencoding %s" % LyX2LaTeX_enc_dict[val]
3682 elif val not in known_enc_tuple:
3683 document.warning("Ignoring unknown input encoding: `%s'" % val)
3686 def revert_IEEEtran_3(document):
3688 Reverts Flex Insets to TeX-code
3690 if document.textclass == "IEEEtran":
3696 h = find_token(document.body, "\\begin_inset Flex Author Mark", h)
3698 endh = find_end_of_inset(document.body, h)
3699 document.body[endh - 2 : endh + 1] = put_cmd_in_ert("}")
3700 document.body[h : h + 4] = put_cmd_in_ert("\\IEEEauthorrefmark{")
3703 i = find_token(document.body, "\\begin_inset Flex Author Name", i)
3705 endi = find_end_of_inset(document.body, i)
3706 document.body[endi - 2 : endi + 1] = put_cmd_in_ert("}")
3707 document.body[i : i + 4] = put_cmd_in_ert("\\IEEEauthorblockN{")
3710 j = find_token(document.body, "\\begin_inset Flex Author Affiliation", j)
3712 endj = find_end_of_inset(document.body, j)
3713 document.body[endj - 2 : endj + 1] = put_cmd_in_ert("}")
3714 document.body[j : j + 4] = put_cmd_in_ert("\\IEEEauthorblockA{")
3716 if i == -1 and j == -1 and h == -1:
3720 def revert_kurier_fonts(document):
3721 " Revert kurier font definition to LaTeX "
3723 i = find_token(document.header, "\\font_math", 0)
3725 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3726 val = get_value(document.header, "\\font_math", i)
3727 if val == "kurier-math":
3728 add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
3729 "\\usepackage[math]{kurier}\n" \
3730 "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
3731 document.header[i] = "\\font_math auto"
3733 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3734 kurier_fonts = ["kurier", "kurierc", "kurierl", "kurierlc"]
3735 k = find_token(document.header, "\\font_sans kurier", 0)
3737 sf = get_value(document.header, "\\font_sans", k)
3738 if sf in kurier_fonts:
3739 add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
3740 document.header[k] = "\\font_sans default"
3742 def revert_iwona_fonts(document):
3743 " Revert iwona font definition to LaTeX "
3745 i = find_token(document.header, "\\font_math", 0)
3747 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3748 val = get_value(document.header, "\\font_math", i)
3749 if val == "iwona-math":
3750 add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
3751 "\\usepackage[math]{iwona}\n" \
3752 "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
3753 document.header[i] = "\\font_math auto"
3755 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3756 iwona_fonts = ["iwona", "iwonac", "iwonal", "iwonalc"]
3757 k = find_token(document.header, "\\font_sans iwona", 0)
3759 sf = get_value(document.header, "\\font_sans", k)
3760 if sf in iwona_fonts:
3761 add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
3762 document.header[k] = "\\font_sans default"
3765 def revert_new_libertines(document):
3766 " Revert new libertine font definition to LaTeX "
3768 if find_token(document.header, "\\use_non_tex_fonts true", 0) != -1:
3771 i = find_token(document.header, "\\font_typewriter libertine-mono", 0)
3773 preamble = "\\usepackage"
3774 sc = find_token(document.header, "\\font_tt_scale", 0)
3776 scval = get_value(document.header, "\\font_tt_scale", sc)
3778 preamble += "[scale=%f]" % (float(scval) / 100)
3779 document.header[sc] = "\\font_tt_scale 100"
3780 preamble += "{libertineMono-type1}"
3781 add_to_preamble(document, [preamble])
3782 document.header[i] = "\\font_typewriter default"
3784 k = find_token(document.header, "\\font_sans biolinum", 0)
3786 preamble = "\\usepackage"
3788 j = find_token(document.header, "\\font_osf true", 0)
3793 sc = find_token(document.header, "\\font_sf_scale", 0)
3795 scval = get_value(document.header, "\\font_sf_scale", sc)
3797 options += ",scale=%f" % (float(scval) / 100)
3798 document.header[sc] = "\\font_sf_scale 100"
3800 preamble += "[" + options +"]"
3801 preamble += "{biolinum-type1}"
3802 add_to_preamble(document, [preamble])
3803 document.header[k] = "\\font_sans default"
3806 def convert_lyxframes(document):
3807 " Converts old beamer frames to new style "
3809 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3810 if document.textclass not in beamer_classes:
3813 framebeg = ["BeginFrame", "BeginPlainFrame"]
3814 frameend = ["Frame", "PlainFrame", "EndFrame", "BeginFrame", "BeginPlainFrame", "AgainFrame",
3815 "Section", "Section*", "Subsection", "Subsection*", "Subsubsection", "Subsubsection*"]
3816 for lay in framebeg:
3819 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
3822 parent = get_containing_layout(document.body, i)
3823 if parent == False or parent[1] != i:
3824 document.warning("Wrong parent layout!")
3827 frametype = parent[0]
3831 # Step I: Convert ERT arguments
3832 # FIXME: See restrictions in convert_beamerframeargs method
3833 ertend = convert_beamerframeargs(document, i, parbeg)
3836 # Step II: Now rename the layout and convert the title to an argument
3837 j = find_end_of_layout(document.body, i)
3838 document.body[j : j + 1] = ['\\end_layout', '', '\\end_inset', '', '\\end_layout']
3839 if lay == "BeginFrame":
3840 document.body[i] = "\\begin_layout Frame"
3842 document.body[i] = "\\begin_layout PlainFrame"
3843 document.body[ertend + 1 : ertend + 1] = ['\\begin_inset Argument 4',
3844 'status open', '', '\\begin_layout Plain Layout']
3845 # Step III: find real frame end
3849 fend = find_token(document.body, "\\begin_layout", jj)
3851 document.warning("Malformed LyX document: No real frame end!")
3853 val = get_value(document.body, "\\begin_layout", fend)
3854 if val not in frameend:
3857 old = document.body[fend]
3858 if val == frametype:
3859 document.body[fend : fend] = ['\\end_deeper', '', '\\begin_layout Separator', '', '\\end_layout']
3860 # consider explicit EndFrames between two identical frame types
3861 elif val == "EndFrame":
3862 nextlayout = find_token(document.body, "\\begin_layout", fend + 1)
3863 if nextlayout != -1 and get_value(document.body, "\\begin_layout", nextlayout) == frametype:
3864 document.body[fend : fend] = ['\\end_deeper', '', '\\begin_layout Separator', '', '\\end_layout']
3866 document.body[fend : fend] = ['\\end_deeper']
3868 document.body[fend : fend] = ['\\end_deeper']
3869 document.body[j + 1 : j + 1] = ['', '\\begin_deeper']
3874 def remove_endframes(document):
3875 " Remove deprecated beamer endframes "
3877 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3878 if document.textclass not in beamer_classes:
3883 i = find_token_exact(document.body, "\\begin_layout EndFrame", i)
3886 j = find_end_of_layout(document.body, i)
3888 document.warning("Malformed LyX document: Missing \\end_layout to EndFrame")
3891 del document.body[i : j + 1]
3894 def revert_powerdot_flexes(document):
3895 " Reverts powerdot flex insets "
3897 if document.textclass != "powerdot":
3900 flexes = {"Onslide" : "\\onslide",
3901 "Onslide*" : "\\onslide*",
3902 "Onslide+" : "\\onslide+"}
3903 rx = re.compile(r'^\\begin_inset Flex (.+)$')
3907 i = find_token(document.body, "\\begin_inset Flex", i)
3910 m = rx.match(document.body[i])
3912 flextype = m.group(1)
3913 z = find_end_of_inset(document.body, i)
3915 document.warning("Can't find end of Flex " + flextype + " inset.")
3918 if flextype in flexes:
3919 pre = put_cmd_in_ert(flexes[flextype])
3920 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
3922 argend = find_end_of_inset(document.body, arg)
3924 document.warning("Can't find end of Argument!")
3927 # Find containing paragraph layout
3928 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3929 endPlain = find_end_of_layout(document.body, beginPlain)
3930 argcontent = document.body[beginPlain + 1 : endPlain]
3932 z = z - len(document.body[arg : argend + 1])
3934 del document.body[arg : argend + 1]
3935 pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
3936 pre += put_cmd_in_ert("{")
3937 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
3938 endPlain = find_end_of_layout(document.body, beginPlain)
3940 z = z - len(document.body[i : beginPlain + 1])
3942 document.body[i : beginPlain + 1] = pre
3943 post = put_cmd_in_ert("}")
3944 document.body[z - 2 : z + 1] = post
3948 def revert_powerdot_pause(document):
3949 " Reverts powerdot pause layout to ERT "
3951 if document.textclass != "powerdot":
3956 i = find_token(document.body, "\\begin_layout Pause", i)
3959 j = find_end_of_layout(document.body, i)
3961 document.warning("Malformed LyX document: Can't find end of Pause layout")
3965 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\pause")
3966 for p in range(i, j):
3969 arg = find_token(document.body, "\\begin_inset Argument 1", i, j)
3971 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3972 endPlain = find_end_of_layout(document.body, beginPlain)
3973 endInset = find_end_of_inset(document.body, p)
3974 content = document.body[beginPlain + 1 : endPlain]
3976 endlay = endlay - len(document.body[p : endInset + 1])
3978 del document.body[p : endInset + 1]
3979 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3981 document.body[i : i + 1] = subst
3985 def revert_powerdot_itemargs(document):
3986 " Reverts powerdot item arguments to ERT "
3988 if document.textclass != "powerdot":
3992 list_layouts = ["Itemize", "ItemizeType1", "Enumerate", "EnumerateType1"]
3993 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
3996 i = find_token(document.body, "\\begin_inset Argument", i)
3999 # Find containing paragraph layout
4000 parent = get_containing_layout(document.body, i)
4002 document.warning("Malformed LyX document: Can't find parent paragraph layout")
4007 realparbeg = parent[3]
4008 layoutname = parent[0]
4010 for p in range(parbeg, parend):
4014 if layoutname in list_layouts:
4015 m = rx.match(document.body[p])
4018 if argnr == "item:1":
4019 j = find_end_of_inset(document.body, i)
4020 # Find containing paragraph layout
4021 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
4022 endPlain = find_end_of_layout(document.body, beginPlain)
4023 content = document.body[beginPlain + 1 : endPlain]
4024 del document.body[i:j+1]
4025 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
4026 document.body[realparbeg : realparbeg] = subst
4027 elif argnr == "item:2":
4028 j = find_end_of_inset(document.body, i)
4029 # Find containing paragraph layout
4030 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
4031 endPlain = find_end_of_layout(document.body, beginPlain)
4032 content = document.body[beginPlain + 1 : endPlain]
4033 del document.body[i:j+1]
4034 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
4035 document.body[realparbeg : realparbeg] = subst
4040 def revert_powerdot_columns(document):
4041 " Reverts powerdot twocolumn to TeX-code "
4042 if document.textclass != "powerdot":
4045 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
4048 i = find_token(document.body, "\\begin_layout Twocolumn", i)
4051 j = find_end_of_layout(document.body, i)
4053 document.warning("Malformed LyX document: Can't find end of Twocolumn layout")
4057 document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
4058 endlay += len(put_cmd_in_ert("}"))
4059 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\twocolumn")
4060 for p in range(i, j):
4063 m = rx.match(document.body[p])
4067 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
4068 endPlain = find_end_of_layout(document.body, beginPlain)
4069 endInset = find_end_of_inset(document.body, p)
4070 content = document.body[beginPlain + 1 : endPlain]
4072 endlay = endlay - len(document.body[p : endInset + 1])
4074 del document.body[p : endInset + 1]
4075 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
4077 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
4078 endPlain = find_end_of_layout(document.body, beginPlain)
4079 endInset = find_end_of_inset(document.body, p)
4080 content = document.body[beginPlain + 1 : endPlain]
4082 endlay = endlay - len(document.body[p : endInset + 1])
4084 del document.body[p : endInset + 1]
4085 subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
4087 subst += put_cmd_in_ert("{")
4088 document.body[i : i + 1] = subst
4092 def revert_mbox_fbox(document):
4093 'Convert revert mbox/fbox boxes to TeX-code'
4096 i = find_token(document.body, "\\begin_inset Box", i)
4099 j = find_token(document.body, "width", i)
4101 document.warning("Malformed LyX document: Can't find box width")
4103 width = get_value(document.body, "width", j)
4104 k = find_end_of_inset(document.body, j)
4106 document.warning("Malformed LyX document: Can't find end of box inset")
4109 BeginLayout = find_token(document.body, "\\begin_layout Plain Layout", j)
4110 EndLayout = find_token(document.body, "\\end_layout", BeginLayout)
4111 # replace if width is ""
4113 document.body[EndLayout:k + 1] = put_cmd_in_ert("}")
4114 if document.body[i] == "\\begin_inset Box Frameless":
4115 document.body[i:BeginLayout + 1] = put_cmd_in_ert("\\mbox{")
4116 if document.body[i] == "\\begin_inset Box Boxed":
4117 document.body[i:BeginLayout + 1] = put_cmd_in_ert("\\fbox{")
4121 def revert_starred_caption(document):
4122 " Reverts unnumbered longtable caption insets "
4126 i = find_token(document.body, "\\begin_inset Caption LongTableNoNumber", i)
4129 # This is not equivalent, but since the caption inset is a full blown
4130 # text inset a true conversion to ERT is too difficult.
4131 document.body[i] = "\\begin_inset Caption Standard"
4135 def revert_forced_local_layout(document):
4138 i = find_token(document.header, "\\begin_forced_local_layout", i)
4141 j = find_end_of(document.header, i, "\\begin_forced_local_layout", "\\end_forced_local_layout")
4143 # this should not happen
4145 regexp = re.compile(r'\s*forcelocal', re.IGNORECASE)
4146 k = find_re(document.header, regexp, i, j)
4148 del document.header[k]
4150 k = find_re(document.header, regexp, i, j)
4151 k = find_token(document.header, "\\begin_local_layout", 0)
4153 document.header[i] = "\\begin_local_layout"
4154 document.header[j] = "\\end_local_layout"
4156 l = find_end_of(document.header, k, "\\begin_local_layout", "\\end_local_layout")
4158 # this should not happen
4160 lines = document.header[i+1 : j]
4162 document.header[k+1 : k+1] = lines
4163 document.header[i : j ] = []
4165 document.header[i : j ] = []
4166 document.header[k+1 : k+1] = lines
4169 def revert_aa1(document):
4170 " Reverts InsetArguments of aa to TeX-code "
4171 if document.textclass == "aa":
4175 i = find_token(document.body, "\\begin_layout Abstract (structured)", i)
4177 revert_Argument_to_TeX_brace(document, i, 0, 1, 4, False, False)
4183 def revert_aa2(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 document.body[i] = "\\begin_layout Abstract"
4197 def revert_tibetan(document):
4198 "Set the document language for Tibetan to English"
4200 if document.language == "tibetan":
4201 document.language = "english"
4202 i = find_token(document.header, "\\language", 0)
4204 document.header[i] = "\\language english"
4206 while j < len(document.body):
4207 j = find_token(document.body, "\\lang tibetan", j)
4209 document.body[j] = document.body[j].replace("\\lang tibetan", "\\lang english")
4212 j = len(document.body)
4221 # the idea here is that we will have a sequence of chunk paragraphs
4222 # we want to convert them to paragraphs in a chunk inset
4223 # the last will be discarded
4224 # the first should look like: <<FROGS>>=
4225 # will will discard the delimiters, and put the contents into the
4226 # optional argument of the inset
4227 def convert_chunks(document):
4228 first_re = re.compile(r'<<(.*)>>=')
4231 # the beginning of this sequence
4233 # find start of a block of chunks
4234 i = find_token(document.body, "\\begin_layout Chunk", i)
4242 # process the one we just found
4243 j = find_end_of_layout(document.body, i)
4245 document.warning("Malformed LyX documents. Can't find end of Chunk layout!")
4247 thischunk = "".join(document.body[i + 1:j])
4248 contents.append(document.body[i + 1:j])
4250 if thischunk == "@":
4253 # look for the next one
4255 i = find_token(document.body, "\\begin_layout", i)
4259 layout = get_value(document.body, "\\begin_layout", i)
4260 #sys.stderr.write(layout+ '\n')
4261 if layout != "Chunk":
4265 # error, but we can try to continue
4272 # the last chunk should simply have an "@" in it
4274 if ''.join(contents[-1]) != "@":
4275 document.warning("Unexpected chunk contents.")
4280 # the first item should look like: <<FROGS>>=
4281 # we want the inside
4282 optarg = ' '.join(contents[0])
4284 match = first_re.search(optarg)
4286 optarg = match.groups()[0]
4289 newstuff = ['\\begin_layout Standard',
4290 '\\begin_inset Flex Chunk',
4292 '\\begin_layout Plain Layout', '']
4296 ['\\begin_inset Argument 1',
4298 '\\begin_layout Plain Layout',
4306 newstuff.extend(['', '\\begin_layout Plain Layout', ''])
4310 newstuff.append('\\end_layout')
4312 newstuff.extend(['', '\\end_inset', '', '\\end_layout', ''])
4314 document.body[start:end] = newstuff
4316 k += len(newstuff) - (end - start)
4319 def revert_chunks(document):
4322 i = find_token(document.body, "\\begin_inset Flex Chunk", i)
4326 iend = find_end_of_inset(document.body, i)
4328 document.warning("Can't find end of Chunk!")
4332 # Look for optional argument
4334 ostart = find_token(document.body, "\\begin_inset Argument 1", i, iend)
4336 oend = find_end_of_inset(document.body, ostart)
4337 k = find_token(document.body, "\\begin_layout Plain Layout", ostart, oend)
4339 document.warning("Malformed LyX document: Can't find argument contents!")
4341 m = find_end_of_layout(document.body, k)
4342 optarg = "".join(document.body[k+1:m])
4345 # We now remove the optional argument, so we have something
4346 # uniform on which to work
4347 document.body[ostart : oend + 1] = []
4348 # iend is now invalid
4349 iend = find_end_of_inset(document.body, i)
4351 retval = get_containing_layout(document.body, i)
4353 document.warning("Can't find containing layout for Chunk!")
4356 (lname, lstart, lend, pstart) = retval
4357 # we now want to work through the various paragraphs, and collect their contents
4361 k = find_token(document.body, "\\begin_layout Plain Layout", k, lend)
4364 j = find_end_of_layout(document.body, k)
4366 document.warning("Can't find end of layout inside chunk!")
4368 parlist.append(document.body[k+1:j])
4370 # we now need to wrap all of these paragraphs in chunks
4373 newlines.extend(["\\begin_layout Chunk", "", "<<" + optarg + ">>=", "\\end_layout", ""])
4374 for stuff in parlist:
4375 newlines.extend(["\\begin_layout Chunk"] + stuff + ["\\end_layout", ""])
4376 newlines.extend(["\\begin_layout Chunk", "", "@", "\\end_layout", ""])
4377 # replace old content with new content
4378 document.body[lstart : lend + 1] = newlines
4379 i = lstart + len(newlines)
4386 supported_versions = ["2.1.0","2.1"]
4389 [415, [convert_undertilde]],
4391 [417, [convert_japanese_encodings]],
4394 [420, [convert_biblio_style]],
4395 [421, [convert_longtable_captions]],
4396 [422, [convert_use_packages]],
4397 [423, [convert_use_mathtools]],
4398 [424, [convert_cite_engine_type]],
4402 [428, [convert_cell_rotation]],
4403 [429, [convert_table_rotation]],
4404 [430, [convert_listoflistings]],
4405 [431, [convert_use_amssymb]],
4407 [433, [convert_armenian]],
4415 [441, [convert_mdnomath]],
4420 [446, [convert_latexargs]],
4421 [447, [convert_IEEEtran, convert_AASTeX, convert_AGUTeX, convert_IJMP, convert_SIGPLAN, convert_SIGGRAPH, convert_EuropeCV, convert_Initials, convert_ModernCV]],
4422 [448, [convert_literate]],
4425 [451, [convert_beamerargs, convert_againframe_args, convert_corollary_args, convert_quote_args]],
4426 [452, [convert_beamerblocks]],
4427 [453, [convert_use_stmaryrd]],
4428 [454, [convert_overprint]],
4430 [456, [convert_epigraph]],
4431 [457, [convert_use_stackrel]],
4432 [458, [convert_captioninsets, convert_captionlayouts]],
4437 [463, [convert_encodings]],
4438 [464, [convert_use_cancel]],
4439 [465, [convert_lyxframes, remove_endframes]],
4445 [471, [convert_cite_engine_type_default]],
4448 [474, [convert_chunks]],
4452 [473, [revert_chunks]],
4453 [472, [revert_tibetan]],
4454 [471, [revert_aa1,revert_aa2]],
4455 [470, [revert_cite_engine_type_default]],
4456 [469, [revert_forced_local_layout]],
4457 [468, [revert_starred_caption]],
4458 [467, [revert_mbox_fbox]],
4459 [466, [revert_iwona_fonts]],
4460 [465, [revert_powerdot_flexes, revert_powerdot_pause, revert_powerdot_itemargs, revert_powerdot_columns]],
4462 [463, [revert_use_cancel]],
4463 [462, [revert_encodings]],
4464 [461, [revert_new_libertines]],
4465 [460, [revert_kurier_fonts]],
4466 [459, [revert_IEEEtran_3]],
4467 [458, [revert_fragileframe, revert_newframes]],
4468 [457, [revert_captioninsets, revert_captionlayouts]],
4469 [456, [revert_use_stackrel]],
4470 [455, [revert_epigraph]],
4471 [454, [revert_frametitle]],
4472 [453, [revert_overprint]],
4473 [452, [revert_use_stmaryrd]],
4474 [451, [revert_beamerblocks]],
4475 [450, [revert_beamerargs, revert_beamerargs2, revert_beamerargs3, revert_beamerflex]],
4476 [449, [revert_garamondx, revert_garamondx_newtxmath]],
4477 [448, [revert_itemargs]],
4478 [447, [revert_literate]],
4479 [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]],
4480 [445, [revert_latexargs]],
4481 [444, [revert_uop]],
4482 [443, [revert_biolinum]],
4484 [441, [revert_newtxmath]],
4485 [440, [revert_mdnomath]],
4486 [439, [revert_mathfonts]],
4487 [438, [revert_minionpro]],
4488 [437, [revert_ipadeco, revert_ipachar]],
4489 [436, [revert_texgyre]],
4490 [435, [revert_mathdesign]],
4491 [434, [revert_txtt]],
4492 [433, [revert_libertine]],
4493 [432, [revert_armenian]],
4494 [431, [revert_languages, revert_ancientgreek]],
4495 [430, [revert_use_amssymb]],
4496 [429, [revert_listoflistings]],
4497 [428, [revert_table_rotation]],
4498 [427, [revert_cell_rotation]],
4499 [426, [revert_tipa]],
4500 [425, [revert_verbatim]],
4501 [424, [revert_cancel]],
4502 [423, [revert_cite_engine_type]],
4503 [422, [revert_use_mathtools]],
4504 [421, [revert_use_packages]],
4505 [420, [revert_longtable_captions]],
4506 [419, [revert_biblio_style]],
4507 [418, [revert_australian]],
4508 [417, [revert_justification]],
4509 [416, [revert_japanese_encodings]],
4510 [415, [revert_negative_space, revert_math_spaces]],
4511 [414, [revert_undertilde]],
4512 [413, [revert_visible_space]]
4516 if __name__ == "__main__":