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):
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)
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
120 Todo: this routine can currently handle only one mandatory argument of environments
125 while lineERT != -1 and n < nmax + 1:
126 lineERT = find_token(document.body, "\\begin_inset ERT", lineERT)
127 if environment == False and lineERT != -1:
128 bracePair = find_token(document.body, "}{", lineERT)
129 # assure that the "}{" is in this ERT
130 if bracePair == lineERT + 5:
131 end = find_token(document.body, "\\end_inset", bracePair)
132 document.body[lineERT : end + 1] = ["\\end_layout", "", "\\end_inset"]
134 # in the case that n > 1 we have optional arguments before
135 # therefore detect them if any
137 # first check if there is an argument
138 lineArg = find_token(document.body, "\\begin_inset Argument", line)
139 if lineArg < lineERT and lineArg != -1:
140 # we have an argument, so now search backwards for its end
141 # we must now assure that we don't find other insets like e.g. a newline
142 endInsetArg = lineERT
143 endLayoutArg = endInsetArg
144 while endInsetArg != endLayoutArg + 2 and endInsetArg != -1:
145 endInsetArg = endInsetArg - 1
146 endLayoutArg = endInsetArg
147 endInsetArg = find_token_backwards(document.body, "\\end_inset", endInsetArg)
148 endLayoutArg = find_token_backwards(document.body, "\\end_layout", endLayoutArg)
149 line = endInsetArg + 1
151 document.body[line + 1 : line + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
153 document.body[line + 4 : line + 4] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
155 document.body[endn : endn] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
159 # now check the case that we have "}" + "{" in two ERTs
161 endBrace = find_token(document.body, "}", lineERT)
162 if endBrace == lineERT + 5:
163 beginBrace = find_token(document.body, "{", endBrace)
164 # assure that the ERTs are consecutive (11 or 12 depending if there is a space between the ERTs or not)
165 if beginBrace == endBrace + 11 or beginBrace == endBrace + 12:
166 end = find_token(document.body, "\\end_inset", beginBrace)
167 document.body[lineERT : end + 1] = ["\\end_layout", "", "\\end_inset"]
169 # in the case that n > 1 we have optional arguments before
170 # therefore detect them if any
172 # first check if there is an argument
173 lineArg = find_token(document.body, "\\begin_inset Argument", line)
174 if lineArg < lineERT and lineArg != -1:
175 # we have an argument, so now search backwards for its end
176 # we must now assure that we don't find other insets like e.g. a newline
177 endInsetArg = lineERT
178 endLayoutArg = endInsetArg
179 while endInsetArg != endLayoutArg + 2 and endInsetArg != -1:
180 endInsetArg = endInsetArg - 1
181 endLayoutArg = endInsetArg
182 endInsetArg = find_token_backwards(document.body, "\\end_inset", endInsetArg)
183 endLayoutArg = find_token_backwards(document.body, "\\end_layout", endLayoutArg)
184 line = endInsetArg + 1
186 document.body[line + 1 : line + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
188 document.body[line + 4 : line + 4] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
190 document.body[endn : endn] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
193 # set the line where the next argument will be inserted
194 if beginBrace == endBrace + 11:
202 if environment == True and lineERT != -1:
203 opening = find_token(document.body, "{", lineERT)
204 if opening == lineERT + 5: # assure that the "{" is in this ERT
205 end = find_token(document.body, "\\end_inset", opening)
206 document.body[lineERT : end + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
208 lineERT2 = find_token(document.body, "\\begin_inset ERT", lineERT)
209 closing = find_token(document.body, "}", lineERT2)
210 if closing == lineERT2 + 5: # assure that the "}" is in this ERT
211 end2 = find_token(document.body, "\\end_inset", closing)
212 document.body[lineERT2 : end2 + 1] = ["\\end_layout", "", "\\end_inset"]
217 ###############################################################################
219 ### Conversion and reversion routines
221 ###############################################################################
223 def revert_visible_space(document):
224 "Revert InsetSpace visible into its ERT counterpart"
227 i = find_token(document.body, "\\begin_inset space \\textvisiblespace{}", i)
230 end = find_end_of_inset(document.body, i)
231 subst = put_cmd_in_ert("\\textvisiblespace{}")
232 document.body[i:end + 1] = subst
235 def convert_undertilde(document):
236 " Load undertilde automatically "
237 i = find_token(document.header, "\\use_mathdots" , 0)
239 i = find_token(document.header, "\\use_mhchem" , 0)
241 i = find_token(document.header, "\\use_esint" , 0)
243 document.warning("Malformed LyX document: Can't find \\use_mathdots.")
245 j = find_token(document.preamble, "\\usepackage{undertilde}", 0)
247 document.header.insert(i + 1, "\\use_undertilde 0")
249 document.header.insert(i + 1, "\\use_undertilde 2")
250 del document.preamble[j]
253 def revert_undertilde(document):
254 " Load undertilde if used in the document "
255 undertilde = find_token(document.header, "\\use_undertilde" , 0)
257 document.warning("No \\use_undertilde line. Assuming auto.")
259 val = get_value(document.header, "\\use_undertilde", undertilde)
260 del document.header[undertilde]
264 document.warning("Invalid \\use_undertilde value: " + val + ". Assuming auto.")
265 # probably usedots has not been changed, but be safe.
273 add_to_preamble(document, ["\\usepackage{undertilde}"])
276 # so we are in the auto case. we want to load undertilde if \utilde is used.
279 i = find_token(document.body, '\\begin_inset Formula', i)
282 j = find_end_of_inset(document.body, i)
284 document.warning("Malformed LyX document: Can't find end of Formula inset at line " + str(i))
287 code = "\n".join(document.body[i:j])
288 if code.find("\\utilde") != -1:
289 add_to_preamble(document, ["\\@ifundefined{utilde}{\\usepackage{undertilde}}"])
294 def revert_negative_space(document):
295 "Revert InsetSpace negmedspace and negthickspace into its TeX-code counterpart"
300 i = find_token(document.body, "\\begin_inset space \\negmedspace{}", i)
302 j = find_token(document.body, "\\begin_inset space \\negthickspace{}", j)
304 # load amsmath in the preamble if not already loaded if we are at the end of checking
306 i = find_token(document.header, "\\use_amsmath 2", 0)
308 add_to_preamble(document, ["\\@ifundefined{negthickspace}{\\usepackage{amsmath}}"])
312 end = find_end_of_inset(document.body, i)
313 subst = put_cmd_in_ert("\\negmedspace{}")
314 document.body[i:end + 1] = subst
315 j = find_token(document.body, "\\begin_inset space \\negthickspace{}", j)
318 end = find_end_of_inset(document.body, j)
319 subst = put_cmd_in_ert("\\negthickspace{}")
320 document.body[j:end + 1] = subst
324 def revert_math_spaces(document):
325 "Revert formulas with protected custom space and protected hfills to TeX-code"
328 i = find_token(document.body, "\\begin_inset Formula", i)
331 j = document.body[i].find("\\hspace*")
333 end = find_end_of_inset(document.body, i)
334 subst = put_cmd_in_ert(document.body[i][21:])
335 document.body[i:end + 1] = subst
339 def convert_japanese_encodings(document):
340 " Rename the japanese encodings to names understood by platex "
342 "EUC-JP-pLaTeX": "euc",
344 "SJIS-pLaTeX": "sjis"
346 i = find_token(document.header, "\\inputencoding" , 0)
349 val = get_value(document.header, "\\inputencoding", i)
350 if val in jap_enc_dict.keys():
351 document.header[i] = "\\inputencoding %s" % jap_enc_dict[val]
354 def revert_japanese_encodings(document):
355 " Revert the japanese encodings name changes "
357 "euc": "EUC-JP-pLaTeX",
359 "sjis": "SJIS-pLaTeX"
361 i = find_token(document.header, "\\inputencoding" , 0)
364 val = get_value(document.header, "\\inputencoding", i)
365 if val in jap_enc_dict.keys():
366 document.header[i] = "\\inputencoding %s" % jap_enc_dict[val]
369 def revert_justification(document):
370 " Revert the \\justification buffer param"
371 if not del_token(document.header, '\\justification', 0):
372 document.warning("Malformed LyX document: Missing \\justification.")
375 def revert_australian(document):
376 "Set English language variants Australian and Newzealand to English"
378 if document.language == "australian" or document.language == "newzealand":
379 document.language = "english"
380 i = find_token(document.header, "\\language", 0)
382 document.header[i] = "\\language english"
385 j = find_token(document.body, "\\lang australian", j)
387 j = find_token(document.body, "\\lang newzealand", 0)
391 document.body[j] = document.body[j].replace("\\lang newzealand", "\\lang english")
393 document.body[j] = document.body[j].replace("\\lang australian", "\\lang english")
397 def convert_biblio_style(document):
398 "Add a sensible default for \\biblio_style based on the citation engine."
399 i = find_token(document.header, "\\cite_engine", 0)
401 engine = get_value(document.header, "\\cite_engine", i).split("_")[0]
402 style = {"basic": "plain", "natbib": "plainnat", "jurabib": "jurabib"}
403 document.header.insert(i + 1, "\\biblio_style " + style[engine])
406 def revert_biblio_style(document):
407 "BibTeX insets with default option use the style defined by \\biblio_style."
408 i = find_token(document.header, "\\biblio_style" , 0)
410 document.warning("No \\biblio_style line. Nothing to do.")
413 default_style = get_value(document.header, "\\biblio_style", i)
414 del document.header[i]
416 # We are looking for bibtex insets having the default option
419 i = find_token(document.body, "\\begin_inset CommandInset bibtex", i)
422 j = find_end_of_inset(document.body, i)
424 document.warning("Malformed LyX document: Can't find end of bibtex inset at line " + str(i))
427 k = find_token(document.body, "options", i, j)
429 options = get_quoted_value(document.body, "options", k)
430 if "default" in options.split(","):
431 document.body[k] = 'options "%s"' \
432 % options.replace("default", default_style)
436 def handle_longtable_captions(document, forward):
439 begin_table = find_token(document.body, '<lyxtabular version=', begin_table)
440 if begin_table == -1:
442 end_table = find_end_of(document.body, begin_table, '<lyxtabular', '</lyxtabular>')
444 document.warning("Malformed LyX document: Could not find end of table.")
447 fline = find_token(document.body, "<features", begin_table, end_table)
449 document.warning("Can't find features for inset at line " + str(begin_table))
452 p = document.body[fline].find("islongtable")
457 numrows = get_option_value(document.body[begin_table], "rows")
459 numrows = int(numrows)
461 document.warning(document.body[begin_table])
462 document.warning("Unable to determine rows!")
463 begin_table = end_table
465 begin_row = begin_table
466 for row in range(numrows):
467 begin_row = find_token(document.body, '<row', begin_row, end_table)
469 document.warning("Can't find row " + str(row + 1))
471 end_row = find_end_of(document.body, begin_row, '<row', '</row>')
473 document.warning("Can't find end of row " + str(row + 1))
476 if (get_option_value(document.body[begin_row], 'caption') == 'true' and
477 get_option_value(document.body[begin_row], 'endfirsthead') != 'true' and
478 get_option_value(document.body[begin_row], 'endhead') != 'true' and
479 get_option_value(document.body[begin_row], 'endfoot') != 'true' and
480 get_option_value(document.body[begin_row], 'endlastfoot') != 'true'):
481 document.body[begin_row] = set_option_value(document.body[begin_row], 'caption', 'true", endfirsthead="true')
482 elif get_option_value(document.body[begin_row], 'caption') == 'true':
483 if get_option_value(document.body[begin_row], 'endfirsthead') == 'true':
484 document.body[begin_row] = set_option_value(document.body[begin_row], 'endfirsthead', 'false')
485 if get_option_value(document.body[begin_row], 'endhead') == 'true':
486 document.body[begin_row] = set_option_value(document.body[begin_row], 'endhead', 'false')
487 if get_option_value(document.body[begin_row], 'endfoot') == 'true':
488 document.body[begin_row] = set_option_value(document.body[begin_row], 'endfoot', 'false')
489 if get_option_value(document.body[begin_row], 'endlastfoot') == 'true':
490 document.body[begin_row] = set_option_value(document.body[begin_row], 'endlastfoot', 'false')
492 # since there could be a tabular inside this one, we
493 # cannot jump to end.
497 def convert_longtable_captions(document):
498 "Add a firsthead flag to caption rows"
499 handle_longtable_captions(document, True)
502 def revert_longtable_captions(document):
503 "remove head/foot flag from caption rows"
504 handle_longtable_captions(document, False)
507 def convert_use_packages(document):
508 "use_xxx yyy => use_package xxx yyy"
509 packages = ["amsmath", "esint", "mathdots", "mhchem", "undertilde"]
511 i = find_token(document.header, "\\use_%s" % p, 0)
513 value = get_value(document.header, "\\use_%s" % p, i)
514 document.header[i] = "\\use_package %s %s" % (p, value)
517 def revert_use_packages(document):
518 "use_package xxx yyy => use_xxx yyy"
519 packages = ["amsmath", "esint", "mathdots", "mhchem", "undertilde"]
520 # the order is arbitrary for the use_package version, and not all packages need to be given.
521 # Ensure a complete list and correct order (important for older LyX versions and especially lyx2lyx)
524 regexp = re.compile(r'(\\use_package\s+%s)' % p)
525 i = find_re(document.header, regexp, j)
527 value = get_value(document.header, "\\use_package %s" % p, i).split()[1]
528 del document.header[i]
530 document.header.insert(j, "\\use_%s %s" % (p, value))
534 def convert_use_package(document, pkg):
535 i = find_token(document.header, "\\use_package", 0)
537 document.warning("Malformed LyX document: Can't find \\use_package.")
539 j = find_token(document.preamble, "\\usepackage{" + pkg + "}", 0)
541 document.header.insert(i + 1, "\\use_package " + pkg + " 0")
543 document.header.insert(i + 1, "\\use_package " + pkg + " 2")
544 del document.preamble[j]
547 def revert_use_package(document, pkg, commands, oldauto):
548 # oldauto defines how the version we are reverting to behaves:
549 # if it is true, the old version uses the package automatically.
550 # if it is false, the old version never uses the package.
551 regexp = re.compile(r'(\\use_package\s+%s)' % pkg)
552 i = find_re(document.header, regexp, 0)
553 value = "1" # default is auto
555 value = get_value(document.header, "\\use_package" , i).split()[1]
556 del document.header[i]
557 if value == "2": # on
558 add_to_preamble(document, ["\\usepackage{" + pkg + "}"])
559 elif value == "1" and not oldauto: # auto
562 i = find_token(document.body, '\\begin_inset Formula', i)
565 j = find_end_of_inset(document.body, i)
567 document.warning("Malformed LyX document: Can't find end of Formula inset at line " + str(i))
570 code = "\n".join(document.body[i:j])
572 if code.find("\\%s" % c) != -1:
573 add_to_preamble(document, ["\\usepackage{" + pkg + "}"])
578 def convert_use_mathtools(document):
579 "insert use_package mathtools"
580 convert_use_package(document, "mathtools")
583 def revert_use_mathtools(document):
584 "remove use_package mathtools"
585 commands = ["mathclap", "mathllap", "mathrlap", \
586 "lgathered", "rgathered", "vcentcolon", "dblcolon", \
587 "coloneqq", "Coloneqq", "coloneq", "Coloneq", "eqqcolon", \
588 "Eqqcolon", "eqcolon", "Eqcolon", "colonapprox", \
589 "Colonapprox", "colonsim", "Colonsim"]
590 revert_use_package(document, "mathtools", commands, False)
593 def convert_use_stmaryrd(document):
594 "insert use_package stmaryrd"
595 convert_use_package(document, "stmaryrd")
598 def revert_use_stmaryrd(document):
599 "remove use_package stmaryrd"
600 # commands provided by stmaryrd.sty but LyX uses other packages:
601 # boxdot lightning, bigtriangledown, bigtriangleup
602 commands = ["shortleftarrow", "shortrightarrow", "shortuparrow", \
603 "shortdownarrow", "Yup", "Ydown", "Yleft", "Yright", \
604 "varcurlyvee", "varcurlywedge", "minuso", "baro", \
605 "sslash", "bbslash", "moo", "varotimes", "varoast", \
606 "varobar", "varodot", "varoslash", "varobslash", \
607 "varocircle", "varoplus", "varominus", "boxast", \
608 "boxbar", "boxslash", "boxbslash", "boxcircle", \
609 "boxbox", "boxempty", "merge", "vartimes", \
610 "fatsemi", "sswarrow", "ssearrow", "curlywedgeuparrow", \
611 "curlywedgedownarrow", "fatslash", "fatbslash", "lbag", \
612 "rbag", "varbigcirc", "leftrightarroweq", \
613 "curlyveedownarrow", "curlyveeuparrow", "nnwarrow", \
614 "nnearrow", "leftslice", "rightslice", "varolessthan", \
615 "varogreaterthan", "varovee", "varowedge", "talloblong", \
616 "interleave", "obar", "obslash", "olessthan", \
617 "ogreaterthan", "ovee", "owedge", "oblong", "inplus", \
618 "niplus", "nplus", "subsetplus", "supsetplus", \
619 "subsetpluseq", "supsetpluseq", "Lbag", "Rbag", \
620 "llbracket", "rrbracket", "llparenthesis", \
621 "rrparenthesis", "binampersand", "bindnasrepma", \
622 "trianglelefteqslant", "trianglerighteqslant", \
623 "ntrianglelefteqslant", "ntrianglerighteqslant", \
624 "llfloor", "rrfloor", "llceil", "rrceil", "arrownot", \
625 "Arrownot", "Mapstochar", "mapsfromchar", "Mapsfromchar", \
626 "leftrightarrowtriangle", "leftarrowtriangle", \
627 "rightarrowtriangle", \
628 "bigcurlyvee", "bigcurlywedge", "bigsqcap", "bigbox", \
629 "bigparallel", "biginterleave", "bignplus", \
630 "varcopyright", "longarrownot", "Longarrownot", \
631 "Mapsto", "mapsfrom", "Mapsfrom" "Longmapsto", \
632 "longmapsfrom", "Longmapsfrom"]
633 revert_use_package(document, "stmaryrd", commands, False)
637 def convert_use_stackrel(document):
638 "insert use_package stackrel"
639 convert_use_package(document, "stackrel")
642 def revert_use_stackrel(document):
643 "remove use_package stackrel"
644 commands = ["stackrel"]
645 revert_use_package(document, "stackrel", commands, False)
648 def convert_cite_engine_type(document):
649 "Determine the \\cite_engine_type from the citation engine."
650 i = find_token(document.header, "\\cite_engine", 0)
653 engine = get_value(document.header, "\\cite_engine", i)
655 engine, type = engine.split("_")
657 type = {"basic": "numerical", "jurabib": "authoryear"}[engine]
658 document.header[i] = "\\cite_engine " + engine
659 document.header.insert(i + 1, "\\cite_engine_type " + type)
662 def revert_cite_engine_type(document):
663 "Natbib had the type appended with an underscore."
664 engine_type = "numerical"
665 i = find_token(document.header, "\\cite_engine_type" , 0)
667 document.warning("No \\cite_engine_type line. Assuming numerical.")
669 engine_type = get_value(document.header, "\\cite_engine_type", i)
670 del document.header[i]
672 # We are looking for the natbib citation engine
673 i = find_token(document.header, "\\cite_engine natbib", 0)
676 document.header[i] = "\\cite_engine natbib_" + engine_type
679 def convert_cite_engine_type_default(document):
680 "Convert \\cite_engine_type to default for the basic citation engine."
681 i = find_token(document.header, "\\cite_engine basic", 0)
684 i = find_token(document.header, "\\cite_engine_type" , 0)
687 document.header[i] = "\\cite_engine_type default"
690 def revert_cite_engine_type_default(document):
691 """Revert \\cite_engine_type default.
693 Revert to numerical for the basic cite engine, otherwise to authoryear."""
694 engine_type = "authoryear"
695 i = find_token(document.header, "\\cite_engine_type default" , 0)
698 j = find_token(document.header, "\\cite_engine basic", 0)
700 engine_type = "numerical"
701 document.header[i] = "\\cite_engine_type " + engine_type
704 # this is the same, as revert_use_cancel() except for the default
705 def revert_cancel(document):
706 "add cancel to the preamble if necessary"
707 commands = ["cancelto", "cancel", "bcancel", "xcancel"]
708 revert_use_package(document, "cancel", commands, False)
711 def revert_verbatim(document):
712 " Revert verbatim einvironments completely to TeX-code. "
715 subst_end = ['\end_layout', '', '\\begin_layout Plain Layout',
717 '\\begin_layout Plain Layout', '', '',
720 '\\end_layout', '', '\\end_inset',
721 '', '', '\\end_layout']
722 subst_begin = ['\\begin_layout Standard', '\\noindent',
723 '\\begin_inset ERT', 'status collapsed', '',
724 '\\begin_layout Plain Layout', '', '', '\\backslash',
726 '\\end_layout', '', '\\begin_layout Plain Layout', '']
728 i = find_token(document.body, "\\begin_layout Verbatim", i)
731 j = find_end_of_layout(document.body, i)
733 document.warning("Malformed LyX document: Can't find end of Verbatim layout")
736 # delete all line breaks insets (there are no other insets)
739 n = find_token(document.body, "\\begin_inset Newline newline", l)
741 n = find_token(document.body, "\\begin_inset Newline linebreak", l)
744 m = find_end_of_inset(document.body, n)
745 del(document.body[m:m+1])
746 document.body[n:n+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
749 # consecutive verbatim environments need to be connected
750 k = find_token(document.body, "\\begin_layout Verbatim", j)
751 if k == j + 2 and consecutive == False:
753 document.body[j:j+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
754 document.body[i:i+1] = subst_begin
756 if k == j + 2 and consecutive == True:
757 document.body[j:j+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
758 del(document.body[i:i+1])
760 if k != j + 2 and consecutive == True:
761 document.body[j:j+1] = subst_end
762 # the next paragraph must not be indented
763 document.body[j+19:j+19] = ['\\noindent']
764 del(document.body[i:i+1])
768 document.body[j:j+1] = subst_end
769 # the next paragraph must not be indented
770 document.body[j+19:j+19] = ['\\noindent']
771 document.body[i:i+1] = subst_begin
774 def revert_tipa(document):
775 " Revert native TIPA insets to mathed or ERT. "
778 i = find_token(document.body, "\\begin_inset IPA", i)
781 j = find_end_of_inset(document.body, i)
783 document.warning("Malformed LyX document: Can't find end of IPA inset")
787 n = find_token(document.body, "\\begin_layout", i, j)
789 document.warning("Malformed LyX document: IPA inset has no embedded layout")
792 m = find_end_of_layout(document.body, n)
794 document.warning("Malformed LyX document: Can't find end of embedded layout")
797 content = document.body[n+1:m]
798 p = find_token(document.body, "\\begin_layout", m, j)
799 if p != -1 or len(content) > 1:
801 content = document.body[i+1:j]
803 # IPA insets with multiple pars need to be wrapped by \begin{IPA}...\end{IPA}
804 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}")
805 add_to_preamble(document, ["\\usepackage{tipa,tipx}"])
807 # single-par IPA insets can be reverted to mathed
808 document.body[i:j+1] = ["\\begin_inset Formula $\\text{\\textipa{" + content[0] + "}}$", "\\end_inset"]
812 def revert_cell_rotation(document):
813 "Revert cell rotations to TeX-code"
815 load_rotating = False
819 # first, let's find out if we need to do anything
820 i = find_token(document.body, '<cell ', i)
823 j = document.body[i].find('rotate="')
825 k = document.body[i].find('"', j + 8)
826 value = document.body[i][j + 8 : k]
828 rgx = re.compile(r' rotate="[^"]+?"')
829 # remove rotate option
830 document.body[i] = rgx.sub('', document.body[i])
832 rgx = re.compile(r' rotate="[^"]+?"')
833 document.body[i] = rgx.sub('rotate="true"', document.body[i])
835 rgx = re.compile(r' rotate="[^"]+?"')
837 # remove rotate option
838 document.body[i] = rgx.sub('', document.body[i])
840 document.body[i + 5 : i + 5] = \
841 put_cmd_in_ert("\\end{turn}")
842 document.body[i + 4 : i + 4] = \
843 put_cmd_in_ert("\\begin{turn}{" + value + "}")
849 add_to_preamble(document, ["\\@ifundefined{turnbox}{\usepackage{rotating}}{}"])
852 def convert_cell_rotation(document):
853 'Convert cell rotation statements from "true" to "90"'
857 # first, let's find out if we need to do anything
858 i = find_token(document.body, '<cell ', i)
861 j = document.body[i].find('rotate="true"')
863 rgx = re.compile(r'rotate="[^"]+?"')
864 # convert "true" to "90"
865 document.body[i] = rgx.sub('rotate="90"', document.body[i])
870 def revert_table_rotation(document):
871 "Revert table rotations to TeX-code"
873 load_rotating = False
877 # first, let's find out if we need to do anything
878 i = find_token(document.body, '<features ', i)
881 j = document.body[i].find('rotate="')
883 end_table = find_token(document.body, '</lyxtabular>', j)
884 k = document.body[i].find('"', j + 8)
885 value = document.body[i][j + 8 : k]
887 rgx = re.compile(r' rotate="[^"]+?"')
888 # remove rotate option
889 document.body[i] = rgx.sub('', document.body[i])
891 rgx = re.compile(r'rotate="[^"]+?"')
892 document.body[i] = rgx.sub('rotate="true"', document.body[i])
894 rgx = re.compile(r' rotate="[^"]+?"')
896 # remove rotate option
897 document.body[i] = rgx.sub('', document.body[i])
899 document.body[end_table + 3 : end_table + 3] = \
900 put_cmd_in_ert("\\end{turn}")
901 document.body[i - 2 : i - 2] = \
902 put_cmd_in_ert("\\begin{turn}{" + value + "}")
908 add_to_preamble(document, ["\\@ifundefined{turnbox}{\usepackage{rotating}}{}"])
911 def convert_table_rotation(document):
912 'Convert table rotation statements from "true" to "90"'
916 # first, let's find out if we need to do anything
917 i = find_token(document.body, '<features ', i)
920 j = document.body[i].find('rotate="true"')
922 rgx = re.compile(r'rotate="[^"]+?"')
923 # convert "true" to "90"
924 document.body[i] = rgx.sub('rotate="90"', document.body[i])
929 def convert_listoflistings(document):
930 'Convert ERT \lstlistoflistings to TOC lstlistoflistings inset'
931 # We can support roundtrip because the command is so simple
934 i = find_token(document.body, "\\begin_inset ERT", i)
937 j = find_end_of_inset(document.body, i)
939 document.warning("Malformed LyX document: Can't find end of ERT inset")
942 ert = get_ert(document.body, i)
943 if ert == "\\lstlistoflistings{}":
944 document.body[i:j] = ["\\begin_inset CommandInset toc", "LatexCommand lstlistoflistings", ""]
950 def revert_listoflistings(document):
951 'Convert TOC lstlistoflistings inset to ERT lstlistoflistings'
954 i = find_token(document.body, "\\begin_inset CommandInset toc", i)
957 if document.body[i+1] == "LatexCommand lstlistoflistings":
958 j = find_end_of_inset(document.body, i)
960 document.warning("Malformed LyX document: Can't find end of TOC inset")
963 subst = put_cmd_in_ert("\\lstlistoflistings{}")
964 document.body[i:j+1] = subst
965 add_to_preamble(document, ["\\usepackage{listings}"])
969 def convert_use_amssymb(document):
970 "insert use_package amssymb"
971 regexp = re.compile(r'(\\use_package\s+amsmath)')
972 i = find_re(document.header, regexp, 0)
974 document.warning("Malformed LyX document: Can't find \\use_package amsmath.")
976 value = get_value(document.header, "\\use_package" , i).split()[1]
979 useamsmath = int(value)
981 document.warning("Invalid \\use_package amsmath: " + value + ". Assuming auto.")
983 j = find_token(document.preamble, "\\usepackage{amssymb}", 0)
985 document.header.insert(i + 1, "\\use_package amssymb %d" % useamsmath)
987 document.header.insert(i + 1, "\\use_package amssymb 2")
988 del document.preamble[j]
991 def revert_use_amssymb(document):
992 "remove use_package amssymb"
993 regexp1 = re.compile(r'(\\use_package\s+amsmath)')
994 regexp2 = re.compile(r'(\\use_package\s+amssymb)')
995 i = find_re(document.header, regexp1, 0)
996 j = find_re(document.header, regexp2, 0)
997 value1 = "1" # default is auto
998 value2 = "1" # default is auto
1000 value1 = get_value(document.header, "\\use_package" , i).split()[1]
1002 value2 = get_value(document.header, "\\use_package" , j).split()[1]
1003 del document.header[j]
1004 if value1 != value2 and value2 == "2": # on
1005 add_to_preamble(document, ["\\usepackage{amssymb}"])
1008 def convert_use_cancel(document):
1009 "insert use_package cancel"
1010 convert_use_package(document, "cancel")
1013 def revert_use_cancel(document):
1014 "remove use_package cancel"
1015 commands = ["cancel", "bcancel", "xcancel", "cancelto"]
1016 revert_use_package(document, "cancel", commands, True)
1019 def revert_ancientgreek(document):
1020 "Set the document language for ancientgreek to greek"
1022 if document.language == "ancientgreek":
1023 document.language = "greek"
1024 i = find_token(document.header, "\\language", 0)
1026 document.header[i] = "\\language greek"
1029 j = find_token(document.body, "\\lang ancientgreek", j)
1033 document.body[j] = document.body[j].replace("\\lang ancientgreek", "\\lang greek")
1037 def revert_languages(document):
1038 "Set the document language for new supported languages to English"
1041 "coptic", "divehi", "hindi", "kurmanji", "lao", "marathi", "occitan", "sanskrit",
1042 "syriac", "tamil", "telugu", "urdu"
1044 for n in range(len(languages)):
1045 if document.language == languages[n]:
1046 document.language = "english"
1047 i = find_token(document.header, "\\language", 0)
1049 document.header[i] = "\\language english"
1051 while j < len(document.body):
1052 j = find_token(document.body, "\\lang " + languages[n], j)
1054 document.body[j] = document.body[j].replace("\\lang " + languages[n], "\\lang english")
1057 j = len(document.body)
1060 def convert_armenian(document):
1061 "Use polyglossia and thus non-TeX fonts for Armenian"
1063 if document.language == "armenian":
1064 i = find_token(document.header, "\\use_non_tex_fonts", 0)
1066 document.header[i] = "\\use_non_tex_fonts true"
1069 def revert_armenian(document):
1070 "Use ArmTeX and thus TeX fonts for Armenian"
1072 if document.language == "armenian":
1073 i = find_token(document.header, "\\use_non_tex_fonts", 0)
1075 document.header[i] = "\\use_non_tex_fonts false"
1078 def revert_libertine(document):
1079 " Revert native libertine font definition to LaTeX "
1081 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1082 i = find_token(document.header, "\\font_roman libertine", 0)
1085 j = find_token(document.header, "\\font_osf true", 0)
1088 preamble = "\\usepackage"
1090 document.header[j] = "\\font_osf false"
1093 preamble += "[lining]"
1094 preamble += "{libertine-type1}"
1095 add_to_preamble(document, [preamble])
1096 document.header[i] = "\\font_roman default"
1099 def revert_txtt(document):
1100 " Revert native txtt font definition to LaTeX "
1102 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1103 i = find_token(document.header, "\\font_typewriter txtt", 0)
1105 preamble = "\\renewcommand{\\ttdefault}{txtt}"
1106 add_to_preamble(document, [preamble])
1107 document.header[i] = "\\font_typewriter default"
1110 def revert_mathdesign(document):
1111 " Revert native mathdesign font definition to LaTeX "
1113 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1119 i = find_token(document.header, "\\font_roman", 0)
1122 val = get_value(document.header, "\\font_roman", i)
1123 if val in mathdesign_dict.keys():
1124 preamble = "\\usepackage[%s" % mathdesign_dict[val]
1126 j = find_token(document.header, "\\font_osf true", 0)
1129 document.header[j] = "\\font_osf false"
1130 l = find_token(document.header, "\\font_sc true", 0)
1133 document.header[l] = "\\font_sc false"
1135 preamble += ",expert"
1136 preamble += "]{mathdesign}"
1137 add_to_preamble(document, [preamble])
1138 document.header[i] = "\\font_roman default"
1141 def revert_texgyre(document):
1142 " Revert native TeXGyre font definition to LaTeX "
1144 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1145 texgyre_fonts = ["tgadventor", "tgbonum", "tgchorus", "tgcursor", \
1146 "tgheros", "tgpagella", "tgschola", "tgtermes"]
1147 i = find_token(document.header, "\\font_roman", 0)
1149 val = get_value(document.header, "\\font_roman", i)
1150 if val in texgyre_fonts:
1151 preamble = "\\usepackage{%s}" % val
1152 add_to_preamble(document, [preamble])
1153 document.header[i] = "\\font_roman default"
1154 i = find_token(document.header, "\\font_sans", 0)
1156 val = get_value(document.header, "\\font_sans", i)
1157 if val in texgyre_fonts:
1158 preamble = "\\usepackage{%s}" % val
1159 add_to_preamble(document, [preamble])
1160 document.header[i] = "\\font_sans default"
1161 i = find_token(document.header, "\\font_typewriter", 0)
1163 val = get_value(document.header, "\\font_typewriter", i)
1164 if val in texgyre_fonts:
1165 preamble = "\\usepackage{%s}" % val
1166 add_to_preamble(document, [preamble])
1167 document.header[i] = "\\font_typewriter default"
1170 def revert_ipadeco(document):
1171 " Revert IPA decorations to ERT "
1174 i = find_token(document.body, "\\begin_inset IPADeco", i)
1177 end = find_end_of_inset(document.body, i)
1179 document.warning("Can't find end of inset at line " + str(i))
1182 line = document.body[i]
1183 rx = re.compile(r'\\begin_inset IPADeco (.*)$')
1185 decotype = m.group(1)
1186 if decotype != "toptiebar" and decotype != "bottomtiebar":
1187 document.warning("Invalid IPADeco type: " + decotype)
1190 blay = find_token(document.body, "\\begin_layout Plain Layout", i, end)
1192 document.warning("Can't find layout for inset at line " + str(i))
1195 bend = find_end_of_layout(document.body, blay)
1197 document.warning("Malformed LyX document: Could not find end of IPADeco inset's layout.")
1200 substi = ["\\begin_inset ERT", "status collapsed", "",
1201 "\\begin_layout Plain Layout", "", "", "\\backslash",
1202 decotype + "{", "\\end_layout", "", "\\end_inset"]
1203 substj = ["\\size default", "", "\\begin_inset ERT", "status collapsed", "",
1204 "\\begin_layout Plain Layout", "", "}", "\\end_layout", "", "\\end_inset"]
1205 # do the later one first so as not to mess up the numbering
1206 document.body[bend:end + 1] = substj
1207 document.body[i:blay + 1] = substi
1208 i = end + len(substi) + len(substj) - (end - bend) - (blay - i) - 2
1209 add_to_preamble(document, "\\usepackage{tipa}")
1212 def revert_ipachar(document):
1213 ' Revert \\IPAChar to ERT '
1216 while i < len(document.body):
1217 m = re.match(r'(.*)\\IPAChar \\(\w+\{\w+\})(.*)', document.body[i])
1221 ipachar = m.group(2)
1224 '\\begin_inset ERT',
1225 'status collapsed', '',
1226 '\\begin_layout Standard',
1227 '', '', '\\backslash',
1232 document.body[i: i+1] = subst
1237 add_to_preamble(document, "\\usepackage{tone}")
1240 def revert_minionpro(document):
1241 " Revert native MinionPro font definition to LaTeX "
1243 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1244 i = find_token(document.header, "\\font_roman minionpro", 0)
1247 j = find_token(document.header, "\\font_osf true", 0)
1250 preamble = "\\usepackage"
1252 document.header[j] = "\\font_osf false"
1255 preamble += "{MinionPro}"
1256 add_to_preamble(document, [preamble])
1257 document.header[i] = "\\font_roman default"
1260 def revert_mathfonts(document):
1261 " Revert native math font definitions to LaTeX "
1263 i = find_token(document.header, "\\font_math", 0)
1266 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1267 val = get_value(document.header, "\\font_math", i)
1268 if val == "eulervm":
1269 add_to_preamble(document, "\\usepackage{eulervm}")
1270 elif val == "default":
1272 "lmodern": "\\renewcommand{\\rmdefault}{lmr}",
1273 "minionpro": "\\usepackage[onlytext,lf]{MinionPro}",
1274 "minionpro-osf": "\\usepackage[onlytext]{MinionPro}",
1275 "palatino": "\\renewcommand{\\rmdefault}{ppl}",
1276 "palatino-osf": "\\renewcommand{\\rmdefault}{pplj}",
1277 "times": "\\renewcommand{\\rmdefault}{ptm}",
1278 "utopia": "\\renewcommand{\\rmdefault}{futs}",
1279 "utopia-osf": "\\renewcommand{\\rmdefault}{futj}",
1281 j = find_token(document.header, "\\font_roman", 0)
1283 rm = get_value(document.header, "\\font_roman", j)
1284 k = find_token(document.header, "\\font_osf true", 0)
1287 if rm in mathfont_dict.keys():
1288 add_to_preamble(document, mathfont_dict[rm])
1289 document.header[j] = "\\font_roman default"
1291 document.header[k] = "\\font_osf false"
1292 del document.header[i]
1295 def revert_mdnomath(document):
1296 " Revert mathdesign and fourier without math "
1298 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1300 "md-charter": "mdbch",
1301 "md-utopia": "mdput",
1302 "md-garamond": "mdugm"
1304 i = find_token(document.header, "\\font_roman", 0)
1307 val = get_value(document.header, "\\font_roman", i)
1308 if val in mathdesign_dict.keys():
1309 j = find_token(document.header, "\\font_math", 0)
1311 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1312 mval = get_value(document.header, "\\font_math", j)
1313 if mval == "default":
1314 document.header[i] = "\\font_roman default"
1315 add_to_preamble(document, "\\renewcommand{\\rmdefault}{%s}" % mathdesign_dict[val])
1317 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1320 def convert_mdnomath(document):
1321 " Change mathdesign font name "
1323 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1325 "mdbch": "md-charter",
1326 "mdput": "md-utopia",
1327 "mdugm": "md-garamond"
1329 i = find_token(document.header, "\\font_roman", 0)
1332 val = get_value(document.header, "\\font_roman", i)
1333 if val in mathdesign_dict.keys():
1334 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1337 def revert_newtxmath(document):
1338 " Revert native newtxmath definitions to LaTeX "
1340 i = find_token(document.header, "\\font_math", 0)
1343 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1344 val = get_value(document.header, "\\font_math", i)
1346 "libertine-ntxm": "\\usepackage[libertine]{newtxmath}",
1347 "minion-ntxm": "\\usepackage[minion]{newtxmath}",
1348 "newtxmath": "\\usepackage{newtxmath}",
1350 if val in mathfont_dict.keys():
1351 add_to_preamble(document, mathfont_dict[val])
1352 document.header[i] = "\\font_math auto"
1355 def revert_biolinum(document):
1356 " Revert native biolinum font definition to LaTeX "
1358 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1359 i = find_token(document.header, "\\font_sans biolinum", 0)
1362 j = find_token(document.header, "\\font_osf true", 0)
1365 preamble = "\\usepackage"
1368 preamble += "{biolinum-type1}"
1369 add_to_preamble(document, [preamble])
1370 document.header[i] = "\\font_sans default"
1373 def revert_uop(document):
1374 " Revert native URW Classico (Optima) font definition to LaTeX "
1376 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1377 i = find_token(document.header, "\\font_sans uop", 0)
1379 preamble = "\\renewcommand{\\sfdefault}{uop}"
1380 add_to_preamble(document, [preamble])
1381 document.header[i] = "\\font_sans default"
1384 def convert_latexargs(document):
1385 " Convert InsetArgument to new syntax "
1387 if find_token(document.body, "\\begin_inset Argument", 0) == -1:
1391 # A list of layouts (document classes) with only optional or no arguments.
1392 # These can be safely converted to the new syntax
1393 # (I took the liberty to add some of my personal layouts/modules here; JSP)
1394 safe_layouts = ["aa", "aapaper", "aastex", "achemso", "acmsiggraph", "AEA",
1395 "agu-dtd", "agums", "agutex", "amsart", "amsbook", "apa",
1396 "arab-article", "armenian-article", "article-beamer", "article",
1397 "beamer", "book", "broadway", "chess", "cl2emult", "ctex-article",
1398 "ctex-book", "ctex-report", "dinbrief", "docbook-book", "docbook-chapter",
1399 "docbook", "docbook-section", "doublecol-new", "dtk", "ectaart", "egs",
1400 "elsarticle", "elsart", "entcs", "europecv", "extarticle", "extbook",
1401 "extletter", "extreport", "foils", "frletter", "g-brief2", "g-brief",
1402 "heb-article", "heb-letter", "hollywood", "IEEEtran", "ijmpc", "ijmpd",
1403 "iopart", "isprs", "jarticle", "jasatex", "jbook", "jgrga", "jreport",
1404 "jsarticle", "jsbeamer", "jsbook", "jss", "kluwer", "latex8", "letter", "lettre",
1405 "literate-article", "literate-book", "literate-report", "llncs", "ltugboat",
1406 "memoir", "moderncv", "mwart", "mwbk", "mwrep", "paper", "powerdot",
1407 "recipebook", "report", "revtex4", "revtex", "scrartcl", "scrarticle-beamer",
1408 "scrbook", "scrlettr", "scrlttr2", "scrreprt", "seminar", "siamltex",
1409 "sigplanconf", "simplecv", "singlecol", "singlecol-new", "slides", "spie",
1410 "svglobal3", "svglobal", "svjog", "svmono", "svmult", "svprobth", "tarticle",
1411 "tbook", "treport", "tufte-book", "tufte-handout"]
1412 # A list of "safe" modules, same as above
1413 safe_modules = ["biblatex", "beameraddons", "beamersession", "braille", "customHeadersFooters",
1414 "endnotes", "enumitem", "eqs-within-sections", "figs-within-sections", "fix-cm",
1415 "fixltx2e", "foottoend", "hanging", "jscharstyles", "knitr", "lilypond",
1416 "linguistics", "linguisticx", "logicalmkup", "minimalistic", "nomindex", "noweb",
1417 "pdfcomment", "sweave", "tabs-within-sections", "theorems-ams-bytype",
1418 "theorems-ams-extended-bytype", "theorems-ams-extended", "theorems-ams", "theorems-bytype",
1419 "theorems-chap-bytype", "theorems-chap", "theorems-named", "theorems-sec-bytype",
1420 "theorems-sec", "theorems-starred", "theorems-std", "todonotes"]
1421 # Modules we need to take care of
1422 caveat_modules = ["initials"]
1423 # information about the relevant styles in caveat_modules (number of opt and req args)
1424 # use this if we get more caveat_modules. For now, use hard coding (see below).
1425 # initials = [{'Layout' : 'Initial', 'opt' : 1, 'req' : 1}]
1427 # Is this a known safe layout?
1428 safe_layout = document.textclass in safe_layouts
1430 document.warning("Lyx2lyx knows nothing about textclass '%s'. "
1431 "Please check if short title insets have been converted correctly."
1432 % document.textclass)
1433 # Do we use unsafe or unknown modules
1434 mods = document.get_module_list()
1435 unknown_modules = False
1436 used_caveat_modules = list()
1438 if mod in safe_modules:
1440 if mod in caveat_modules:
1441 used_caveat_modules.append(mod)
1443 unknown_modules = True
1444 document.warning("Lyx2lyx knows nothing about module '%s'. "
1445 "Please check if short title insets have been converted correctly."
1450 i = find_token(document.body, "\\begin_inset Argument", i)
1454 if not safe_layout or unknown_modules:
1455 # We cannot do more here since we have no access to this layout.
1456 # InsetArgument itself will do the real work
1457 # (see InsetArgument::updateBuffer())
1458 document.body[i] = "\\begin_inset Argument 999"
1462 # Find containing paragraph layout
1463 parent = get_containing_layout(document.body, i)
1465 document.warning("Malformed LyX document: Can't find parent paragraph layout")
1472 if len(used_caveat_modules) > 0:
1473 # We know for now that this must be the initials module with the Initial layout
1474 # If we get more such modules, we need some automating.
1475 if parent[0] == "Initial":
1476 # Layout has 1 opt and 1 req arg.
1477 # Count the actual arguments
1479 for p in range(parbeg, parend):
1480 if document.body[p] == "\\begin_inset Argument":
1485 # Collect all arguments in this paragraph
1487 for p in range(parbeg, parend):
1488 if document.body[p] == "\\begin_inset Argument":
1490 if allowed_opts != -1:
1491 # We have less arguments than opt + required.
1492 # required must take precedence.
1493 if argnr > allowed_opts and argnr < first_req:
1495 document.body[p] = "\\begin_inset Argument %d" % argnr
1499 def revert_latexargs(document):
1500 " Revert InsetArgument to old syntax "
1503 rx = re.compile(r'^\\begin_inset Argument (\d+)$')
1506 # Search for Argument insets
1507 i = find_token(document.body, "\\begin_inset Argument", i)
1510 m = rx.match(document.body[i])
1512 # No ID: inset already reverted
1515 # Find containing paragraph layout
1516 parent = get_containing_layout(document.body, i)
1518 document.warning("Malformed LyX document: Can't find parent paragraph layout")
1523 realparbeg = parent[3]
1524 # Collect all arguments in this paragraph
1526 for p in range(parbeg, parend):
1527 m = rx.match(document.body[p])
1529 val = int(m.group(1))
1530 j = find_end_of_inset(document.body, p)
1531 # Revert to old syntax
1532 document.body[p] = "\\begin_inset Argument"
1534 document.warning("Malformed LyX document: Can't find end of Argument inset")
1537 args[val] = document.body[p : j + 1]
1539 realparend = realparend - len(document.body[p : j + 1])
1540 # Remove arg inset at this position
1541 del document.body[p : j + 1]
1544 # Now sort the arg insets
1546 for f in sorted(args):
1549 # Insert the sorted arg insets at paragraph begin
1550 document.body[realparbeg : realparbeg] = subst
1552 i = realparbeg + 1 + len(subst)
1555 def revert_IEEEtran(document):
1557 Reverts InsetArgument of
1560 Biography without photo
1563 if document.textclass == "IEEEtran":
1570 i = find_token(document.body, "\\begin_layout Page headings", i)
1572 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1575 i2 = find_token(document.body, "\\begin_inset Flex Paragraph Start", i2)
1577 revert_Argument_to_TeX_brace(document, i2, 0, 1, 1, False, False)
1580 j = find_token(document.body, "\\begin_layout Biography without photo", j)
1582 revert_Argument_to_TeX_brace(document, j, 0, 1, 1, True, False)
1585 k = find_token(document.body, "\\begin_layout Biography", k)
1586 kA = find_token(document.body, "\\begin_layout Biography without photo", k)
1587 if k == kA and k != -1:
1591 # start with the second argument, therefore 2
1592 revert_Argument_to_TeX_brace(document, k, 0, 2, 2, True, False)
1594 if i == -1 and i2 == -1 and j == -1 and k == -1:
1598 def revert_IEEEtran_2(document):
1600 Reverts Flex Paragraph Start to TeX-code
1602 if document.textclass == "IEEEtran":
1606 begin = find_token(document.body, "\\begin_inset Flex Paragraph Start", begin)
1608 end1 = find_end_of_inset(document.body, begin)
1609 document.body[end1 - 2 : end1 + 1] = put_cmd_in_ert("}")
1610 document.body[begin : begin + 4] = put_cmd_in_ert("\\IEEEPARstart{")
1616 def convert_IEEEtran(document):
1621 Biography without photo
1624 if document.textclass == "IEEEtran":
1630 i = find_token(document.body, "\\begin_layout Page headings", i)
1632 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1635 j = find_token(document.body, "\\begin_layout Biography without photo", j)
1637 convert_TeX_brace_to_Argument(document, j, 1, 1, False, True)
1640 # assure that we don't handle Biography Biography without photo
1641 k = find_token(document.body, "\\begin_layout Biography", k)
1642 kA = find_token(document.body, "\\begin_layout Biography without photo", k - 1)
1643 if k == kA and k != -1:
1647 # the argument we want to convert is the second one
1648 convert_TeX_brace_to_Argument(document, k, 2, 2, False, True)
1650 if i == -1 and j == -1 and k == -1:
1654 def revert_AASTeX(document):
1655 " Reverts InsetArgument of Altaffilation to TeX-code "
1656 if document.textclass == "aastex":
1660 i = find_token(document.body, "\\begin_layout Altaffilation", i)
1662 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1668 def convert_AASTeX(document):
1669 " Converts ERT of Altaffilation to InsetArgument "
1670 if document.textclass == "aastex":
1674 i = find_token(document.body, "\\begin_layout Altaffilation", i)
1676 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1682 def revert_AGUTeX(document):
1683 " Reverts InsetArgument of Author affiliation to TeX-code "
1684 if document.textclass == "agutex":
1688 i = find_token(document.body, "\\begin_layout Author affiliation", i)
1690 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1696 def convert_AGUTeX(document):
1697 " Converts ERT of Author affiliation to InsetArgument "
1698 if document.textclass == "agutex":
1702 i = find_token(document.body, "\\begin_layout Author affiliation", i)
1704 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1710 def revert_IJMP(document):
1711 " Reverts InsetArgument of MarkBoth to TeX-code "
1712 if document.textclass == "ijmpc" or document.textclass == "ijmpd":
1716 i = find_token(document.body, "\\begin_layout MarkBoth", i)
1718 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1724 def convert_IJMP(document):
1725 " Converts ERT of MarkBoth to InsetArgument "
1726 if document.textclass == "ijmpc" or document.textclass == "ijmpd":
1730 i = find_token(document.body, "\\begin_layout MarkBoth", i)
1732 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1738 def revert_SIGPLAN(document):
1739 " Reverts InsetArguments of SIGPLAN to TeX-code "
1740 if document.textclass == "sigplanconf":
1745 i = find_token(document.body, "\\begin_layout Conference", i)
1747 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1750 j = find_token(document.body, "\\begin_layout Author", j)
1752 revert_Argument_to_TeX_brace(document, j, 0, 1, 2, False, False)
1754 if i == -1 and j == -1:
1758 def convert_SIGPLAN(document):
1759 " Converts ERT of SIGPLAN to InsetArgument "
1760 if document.textclass == "sigplanconf":
1765 i = find_token(document.body, "\\begin_layout Conference", i)
1767 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1770 j = find_token(document.body, "\\begin_layout Author", j)
1772 convert_TeX_brace_to_Argument(document, j, 1, 2, False, False)
1774 if i == -1 and j == -1:
1778 def revert_SIGGRAPH(document):
1779 " Reverts InsetArgument of Flex CRcat to TeX-code "
1780 if document.textclass == "acmsiggraph":
1784 i = find_token(document.body, "\\begin_inset Flex CRcat", i)
1786 revert_Argument_to_TeX_brace(document, i, 0, 1, 3, False, False)
1792 def convert_SIGGRAPH(document):
1793 " Converts ERT of Flex CRcat to InsetArgument "
1794 if document.textclass == "acmsiggraph":
1798 i = find_token(document.body, "\\begin_inset Flex CRcat", i)
1800 convert_TeX_brace_to_Argument(document, i, 1, 3, True, False)
1806 def revert_EuropeCV(document):
1807 " Reverts InsetArguments of europeCV to TeX-code "
1808 if document.textclass == "europecv":
1815 i = find_token(document.body, "\\begin_layout Item", i)
1817 revert_Argument_to_TeX_brace(document, i, 0, 2, 2, False, False)
1820 j = find_token(document.body, "\\begin_layout BulletedItem", j)
1822 revert_Argument_to_TeX_brace(document, j, 0, 2, 2, False, False)
1825 k = find_token(document.body, "\\begin_layout Language", k)
1827 revert_Argument_to_TeX_brace(document, k, 0, 2, 6, False, False)
1830 m = find_token(document.body, "\\begin_layout LastLanguage", m)
1832 revert_Argument_to_TeX_brace(document, m, 0, 2, 6, False, False)
1834 if i == -1 and j == -1 and k == -1 and m == -1:
1838 def convert_EuropeCV(document):
1839 " Converts ERT of europeCV to InsetArgument "
1840 if document.textclass == "europecv":
1847 i = find_token(document.body, "\\begin_layout Item", i)
1849 convert_TeX_brace_to_Argument(document, i, 2, 2, False, False)
1852 j = find_token(document.body, "\\begin_layout BulletedItem", j)
1854 convert_TeX_brace_to_Argument(document, j, 2, 2, False, False)
1857 k = find_token(document.body, "\\begin_layout Language", k)
1859 convert_TeX_brace_to_Argument(document, k, 2, 6, False, False)
1862 m = find_token(document.body, "\\begin_layout LastLanguage", m)
1864 convert_TeX_brace_to_Argument(document, m, 2, 6, False, False)
1866 if i == -1 and j == -1 and k == -1 and m == -1:
1870 def revert_ModernCV(document):
1871 " Reverts InsetArguments of modernCV to TeX-code "
1872 if document.textclass == "moderncv":
1880 j = find_token(document.body, "\\begin_layout Entry", j)
1882 revert_Argument_to_TeX_brace(document, j, 0, 1, 5, False, False)
1885 k = find_token(document.body, "\\begin_layout Item", k)
1887 revert_Argument_to_TeX_brace(document, k, 0, 1, 1, False, False)
1890 m = find_token(document.body, "\\begin_layout ItemWithComment", m)
1892 revert_Argument_to_TeX_brace(document, m, 0, 1, 2, False, False)
1893 document.body[m] = document.body[m].replace("\\begin_layout ItemWithComment", "\\begin_layout Language")
1896 o = find_token(document.body, "\\begin_layout DoubleItem", o)
1898 revert_Argument_to_TeX_brace(document, o, 0, 1, 3, False, False)
1899 document.body[o] = document.body[o].replace("\\begin_layout DoubleItem", "\\begin_layout Computer")
1902 p = find_token(document.body, "\\begin_layout Social", p)
1904 revert_Argument_to_TeX_brace(document, p, 0, 1, 1, False, True)
1906 if j == -1 and k == -1 and m == -1 and o == -1 and p == -1:
1910 def revert_ModernCV_2(document):
1911 " Reverts the Flex:Column inset of modernCV to TeX-code "
1912 if document.textclass == "moderncv":
1917 flex = find_token(document.body, "\\begin_inset Flex Column", flex)
1919 flexEnd = find_end_of_inset(document.body, flex)
1920 wasOpt = revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, False, True)
1921 revert_Argument_to_TeX_brace(document, flex, 0, 2, 2, False, False)
1922 flexEnd = find_end_of_inset(document.body, flex)
1924 document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\cvcolumn")
1926 document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\cvcolumn{")
1927 document.body[flexEnd + 4 : flexEnd + 7] = put_cmd_in_ert("}")
1933 def revert_ModernCV_3(document):
1934 " Reverts the Column style of modernCV to TeX-code "
1935 if document.textclass == "moderncv":
1936 # revert the layouts
1937 revert_ModernCV(document)
1939 # get the position of the end of the last column inset
1940 LastFlexEnd = revert_ModernCV_2(document)
1943 p = find_token(document.body, "\\begin_layout Columns", p)
1945 pEnd = find_end_of_layout(document.body, p)
1946 document.body[p] = document.body[p].replace("\\begin_layout Columns", "\\begin_layout Standard")
1947 if LastFlexEnd != -1:
1948 document.body[p + 1 : p + 1] = put_cmd_in_ert("\\begin{cvcolumns}")
1949 document.body[LastFlexEnd + 24 : LastFlexEnd + 24] = put_cmd_in_ert("\\end{cvcolumns}")
1955 def revert_ModernCV_4(document):
1956 " Reverts the style Social to TeX-code "
1957 if document.textclass == "moderncv":
1958 # revert the layouts
1959 revert_ModernCV(document)
1963 p = find_token(document.body, "\\begin_layout Social", p)
1965 pEnd = find_end_of_layout(document.body, p)
1966 document.body[p] = document.body[p].replace("\\begin_layout Social", "\\begin_layout Standard")
1967 document.body[p + 1 : p + 1] = put_cmd_in_ert("\\social")
1968 hasOpt = find_token(document.body, "[", p + 9)
1970 document.body[p + 30 : p + 30] = put_cmd_in_ert("{")
1971 document.body[p + 41 : p + 41] = put_cmd_in_ert("}")
1973 document.body[p + 11 : p + 11] = put_cmd_in_ert("{")
1974 document.body[p + 21 : p + 21] = put_cmd_in_ert("}")
1980 def convert_ModernCV(document):
1981 " Converts ERT of modernCV to InsetArgument "
1982 if document.textclass == "moderncv":
1990 i = find_token(document.body, "\\begin_layout DoubleItem", i)
1992 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1993 document.body[o] = document.body[o].replace("\\begin_layout DoubleItem", "\\begin_layout DoubleListItem")
1996 j = find_token(document.body, "\\begin_layout Entry", j)
1998 convert_TeX_brace_to_Argument(document, j, 1, 5, False, False)
2001 k = find_token(document.body, "\\begin_layout Item", k)
2003 convert_TeX_brace_to_Argument(document, k, 1, 1, False, False)
2006 m = find_token(document.body, "\\begin_layout Language", m)
2008 convert_TeX_brace_to_Argument(document, m, 1, 2, False, False)
2010 if i == -1 and j == -1 and k == -1 and m == -1:
2014 def revert_Initials(document):
2015 " Reverts InsetArgument of Initial to TeX-code "
2018 i = find_token(document.body, "\\begin_layout Initial", i)
2021 # first arg (optional) and second arg (first mandatory) are supported in LyX 2.0.x
2022 revert_Argument_to_TeX_brace(document, i, 0, 3, 3, False, False)
2026 def convert_Initials(document):
2027 " Converts ERT of Initial to InsetArgument "
2030 i = find_token(document.body, "\\begin_layout Initial", i)
2033 convert_TeX_brace_to_Argument(document, i, 3, 3, False, False)
2037 def revert_literate(document):
2038 " Revert Literate document to old format "
2039 if del_token(document.header, "noweb", 0):
2040 document.textclass = "literate-" + document.textclass
2043 i = find_token(document.body, "\\begin_layout Chunk", i)
2046 document.body[i] = "\\begin_layout Scrap"
2050 def convert_literate(document):
2051 " Convert Literate document to new format"
2052 i = find_token(document.header, "\\textclass", 0)
2053 if (i != -1) and "literate-" in document.header[i]:
2054 document.textclass = document.header[i].replace("\\textclass literate-", "")
2055 j = find_token(document.header, "\\begin_modules", 0)
2057 document.header.insert(j + 1, "noweb")
2059 document.header.insert(i + 1, "\\end_modules")
2060 document.header.insert(i + 1, "noweb")
2061 document.header.insert(i + 1, "\\begin_modules")
2064 i = find_token(document.body, "\\begin_layout Scrap", i)
2067 document.body[i] = "\\begin_layout Chunk"
2071 def revert_itemargs(document):
2072 " Reverts \\item arguments to TeX-code "
2075 i = find_token(document.body, "\\begin_inset Argument item:", i)
2078 j = find_end_of_inset(document.body, i)
2079 # Find containing paragraph layout
2080 parent = get_containing_layout(document.body, i)
2082 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2086 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2087 endPlain = find_end_of_layout(document.body, beginPlain)
2088 content = document.body[beginPlain + 1 : endPlain]
2089 del document.body[i:j+1]
2090 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2091 document.body[parbeg : parbeg] = subst
2095 def revert_garamondx_newtxmath(document):
2096 " Revert native garamond newtxmath definition to LaTeX "
2098 i = find_token(document.header, "\\font_math", 0)
2101 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
2102 val = get_value(document.header, "\\font_math", i)
2103 if val == "garamondx-ntxm":
2104 add_to_preamble(document, "\\usepackage[garamondx]{newtxmath}")
2105 document.header[i] = "\\font_math auto"
2108 def revert_garamondx(document):
2109 " Revert native garamond font definition to LaTeX "
2111 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
2112 i = find_token(document.header, "\\font_roman garamondx", 0)
2115 j = find_token(document.header, "\\font_osf true", 0)
2118 preamble = "\\usepackage"
2120 preamble += "[osfI]"
2121 preamble += "{garamondx}"
2122 add_to_preamble(document, [preamble])
2123 document.header[i] = "\\font_roman default"
2126 def convert_beamerargs(document):
2127 " Converts beamer arguments to new layout "
2129 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2130 if document.textclass not in beamer_classes:
2133 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
2134 list_layouts = ["Itemize", "Enumerate", "Description"]
2135 rx = re.compile(r'^\\begin_inset Argument (\d+)$')
2139 i = find_token(document.body, "\\begin_inset Argument", i)
2142 # Find containing paragraph layout
2143 parent = get_containing_layout(document.body, i)
2145 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2150 layoutname = parent[0]
2151 for p in range(parbeg, parend):
2152 if layoutname in shifted_layouts:
2153 m = rx.match(document.body[p])
2155 argnr = int(m.group(1))
2157 document.body[p] = "\\begin_inset Argument %d" % argnr
2158 if layoutname == "AgainFrame":
2159 m = rx.match(document.body[p])
2161 document.body[p] = "\\begin_inset Argument 3"
2162 if document.body[p + 4] == "\\begin_inset ERT":
2163 if document.body[p + 9].startswith("<"):
2164 # This is an overlay specification
2166 document.body[p + 9] = document.body[p + 9][1:]
2167 if document.body[p + 9].endswith(">"):
2169 document.body[p + 9] = document.body[p + 9][:-1]
2171 document.body[p] = "\\begin_inset Argument 2"
2172 if layoutname in list_layouts:
2173 m = rx.match(document.body[p])
2175 if m.group(1) == "1":
2176 if document.body[p + 4] == "\\begin_inset ERT":
2177 if document.body[p + 9].startswith("<"):
2178 # This is an overlay specification
2180 document.body[p + 9] = document.body[p + 9][1:]
2181 if document.body[p + 9].endswith(">"):
2183 document.body[p + 9] = document.body[p + 9][:-1]
2184 elif layoutname != "Itemize":
2186 document.body[p] = "\\begin_inset Argument 2"
2190 def convert_againframe_args(document):
2191 " Converts beamer AgainFrame to new layout "
2193 # FIXME: This currently only works if the arguments are in one single ERT
2195 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2196 if document.textclass not in beamer_classes:
2201 i = find_token(document.body, "\\begin_layout AgainFrame", i)
2204 parent = get_containing_layout(document.body, i)
2206 document.warning("Wrong parent layout!")
2210 if document.body[parbeg] == "\\begin_inset ERT":
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
2228 # Convert to ArgInset
2229 document.body[parbeg] = "\\begin_inset Argument 2"
2232 elif document.body[ertcont].startswith("<"):
2233 # This is an overlay specification
2235 document.body[ertcont] = document.body[ertcont][1:]
2236 if document.body[ertcont].endswith(">"):
2238 document.body[ertcont] = document.body[ertcont][:-1]
2239 # Convert to ArgInset
2240 document.body[parbeg] = "\\begin_inset Argument 1"
2241 elif document.body[ertcont].endswith(">]"):
2243 tok = document.body[ertcont].find('>[<')
2245 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2246 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2247 'status collapsed', '', '\\begin_layout Plain Layout',
2248 document.body[ertcont][tok + 3:-2]]
2249 # Convert to ArgInset
2250 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]]
2266 tokk = document.body[ertcont].find('>[')
2268 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tokk],
2269 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2270 'status collapsed', '', '\\begin_layout Plain Layout',
2271 document.body[ertcont][tokk + 2:-1]]
2272 # Convert to ArgInset
2273 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_corollary_args(document):
2291 " Converts beamer corrolary-style ERT arguments native InsetArgs "
2293 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2294 if document.textclass not in beamer_classes:
2297 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2298 for lay in corollary_layouts:
2301 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2304 parent = get_containing_layout(document.body, i)
2306 document.warning("Wrong parent layout!")
2310 if document.body[parbeg] == "\\begin_inset ERT":
2311 ertcont = parbeg + 5
2312 if document.body[ertcont].startswith("<"):
2313 # This is an overlay specification
2315 document.body[ertcont] = document.body[ertcont][1:]
2316 if document.body[ertcont].endswith(">"):
2318 document.body[ertcont] = document.body[ertcont][:-1]
2319 elif document.body[ertcont].endswith("]"):
2321 tok = document.body[ertcont].find('>[')
2323 subst = [document.body[ertcont][:tok],
2324 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2325 'status collapsed', '', '\\begin_layout Plain Layout',
2326 document.body[ertcont][tok + 2:-1]]
2327 document.body[ertcont : ertcont + 1] = subst
2328 # Convert to ArgInset
2329 document.body[parbeg] = "\\begin_inset Argument 1"
2332 elif document.body[ertcont].startswith("["):
2333 # This is an ERT option
2335 document.body[ertcont] = document.body[ertcont][1:]
2336 if document.body[ertcont].endswith("]"):
2338 document.body[ertcont] = document.body[ertcont][:-1]
2339 # Convert to ArgInset
2340 document.body[parbeg] = "\\begin_inset Argument 2"
2347 def convert_quote_args(document):
2348 " Converts beamer quote style ERT args to native InsetArgs "
2350 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2351 if document.textclass not in beamer_classes:
2354 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2355 for lay in quote_layouts:
2358 i = find_token(document.body, "\\begin_layout " + lay, i)
2361 parent = get_containing_layout(document.body, i)
2363 document.warning("Wrong parent layout!")
2367 if document.body[parbeg] == "\\begin_inset ERT":
2368 if document.body[i + 6].startswith("<"):
2369 # This is an overlay specification
2371 document.body[i + 6] = document.body[i + 6][1:]
2372 if document.body[i + 6].endswith(">"):
2374 document.body[i + 6] = document.body[i + 6][:-1]
2375 # Convert to ArgInset
2376 document.body[i + 1] = "\\begin_inset Argument 1"
2380 def revert_beamerargs(document):
2381 " Reverts beamer arguments to old layout "
2383 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2384 if document.textclass not in beamer_classes:
2388 list_layouts = ["Itemize", "Enumerate", "Description"]
2389 headings = ["Part", "Section", "Section*", "Subsection", "Subsection*",
2390 "Subsubsection", "Subsubsection*", "FrameSubtitle", "NoteItem"]
2391 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2392 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2393 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2396 i = find_token(document.body, "\\begin_inset Argument", i)
2399 # Find containing paragraph layout
2400 parent = get_containing_layout(document.body, i)
2402 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2407 realparbeg = parent[3]
2408 layoutname = parent[0]
2410 for p in range(parbeg, parend):
2414 if layoutname in headings:
2415 m = rx.match(document.body[p])
2419 # Find containing paragraph layout
2420 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2421 endPlain = find_end_of_layout(document.body, beginPlain)
2422 endInset = find_end_of_inset(document.body, p)
2423 argcontent = document.body[beginPlain + 1 : endPlain]
2425 realparend = realparend - len(document.body[p : endInset + 1])
2427 del document.body[p : endInset + 1]
2428 if layoutname == "FrameSubtitle":
2429 pre = put_cmd_in_ert("\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2430 elif layoutname == "NoteItem":
2431 pre = put_cmd_in_ert("\\note<") + argcontent + put_cmd_in_ert(">[item]")
2432 elif layoutname.endswith('*'):
2433 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower()[:-1] + "<") + argcontent + put_cmd_in_ert(">*")
2435 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2436 secarg = find_token(document.body, "\\begin_inset Argument 2", parbeg, parend)
2438 # Find containing paragraph layout
2439 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", secarg)
2440 endPlain = find_end_of_layout(document.body, beginPlain)
2441 endInset = find_end_of_inset(document.body, secarg)
2442 argcontent = document.body[beginPlain + 1 : endPlain]
2444 realparend = realparend - len(document.body[secarg : endInset + 1])
2445 del document.body[secarg : endInset + 1]
2446 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2447 pre += put_cmd_in_ert("{")
2448 document.body[parbeg] = "\\begin_layout Standard"
2449 document.body[realparbeg : realparbeg] = pre
2450 pe = find_end_of_layout(document.body, parbeg)
2451 post = put_cmd_in_ert("}")
2452 document.body[pe : pe] = post
2453 realparend += len(pre) + len(post)
2454 if layoutname == "AgainFrame":
2455 m = rx.match(document.body[p])
2459 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2460 endPlain = find_end_of_layout(document.body, beginPlain)
2461 endInset = find_end_of_inset(document.body, p)
2462 content = document.body[beginPlain + 1 : endPlain]
2464 realparend = realparend - len(document.body[p : endInset + 1])
2466 del document.body[p : endInset + 1]
2467 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2468 document.body[realparbeg : realparbeg] = subst
2469 if layoutname == "Overprint":
2470 m = rx.match(document.body[p])
2474 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2475 endPlain = find_end_of_layout(document.body, beginPlain)
2476 endInset = find_end_of_inset(document.body, p)
2477 content = document.body[beginPlain + 1 : endPlain]
2479 realparend = realparend - len(document.body[p : endInset + 1])
2481 del document.body[p : endInset + 1]
2482 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2483 document.body[realparbeg : realparbeg] = subst
2484 if layoutname == "OverlayArea":
2485 m = rx.match(document.body[p])
2489 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2490 endPlain = find_end_of_layout(document.body, beginPlain)
2491 endInset = find_end_of_inset(document.body, p)
2492 content = document.body[beginPlain + 1 : endPlain]
2494 realparend = realparend - len(document.body[p : endInset + 1])
2496 del document.body[p : endInset + 1]
2497 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2498 document.body[realparbeg : realparbeg] = subst
2499 if layoutname in list_layouts:
2500 m = rx.match(document.body[p])
2504 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2505 endPlain = find_end_of_layout(document.body, beginPlain)
2506 endInset = find_end_of_inset(document.body, p)
2507 content = document.body[beginPlain + 1 : endPlain]
2508 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2509 realparend = realparend + len(subst) - len(content)
2510 document.body[beginPlain + 1 : endPlain] = subst
2511 elif argnr == "item:1":
2512 j = find_end_of_inset(document.body, i)
2513 # Find containing paragraph layout
2514 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2515 endPlain = find_end_of_layout(document.body, beginPlain)
2516 content = document.body[beginPlain + 1 : endPlain]
2517 del document.body[i:j+1]
2518 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2519 document.body[realparbeg : realparbeg] = subst
2520 elif argnr == "item:2":
2521 j = find_end_of_inset(document.body, i)
2522 # Find containing paragraph layout
2523 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2524 endPlain = find_end_of_layout(document.body, beginPlain)
2525 content = document.body[beginPlain + 1 : endPlain]
2526 del document.body[i:j+1]
2527 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2528 document.body[realparbeg : realparbeg] = subst
2529 if layoutname in quote_layouts:
2530 m = rx.match(document.body[p])
2534 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2535 endPlain = find_end_of_layout(document.body, beginPlain)
2536 endInset = find_end_of_inset(document.body, p)
2537 content = document.body[beginPlain + 1 : endPlain]
2539 realparend = realparend - len(document.body[p : endInset + 1])
2541 del document.body[p : endInset + 1]
2542 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2543 document.body[realparbeg : realparbeg] = subst
2544 if layoutname in corollary_layouts:
2545 m = rx.match(document.body[p])
2549 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2550 endPlain = find_end_of_layout(document.body, beginPlain)
2551 endInset = find_end_of_inset(document.body, p)
2552 content = document.body[beginPlain + 1 : endPlain]
2554 realparend = realparend - len(document.body[p : endInset + 1])
2556 del document.body[p : endInset + 1]
2557 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2558 document.body[realparbeg : realparbeg] = subst
2563 def revert_beamerargs2(document):
2564 " Reverts beamer arguments to old layout, step 2 "
2566 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2567 if document.textclass not in beamer_classes:
2571 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
2572 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2573 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2576 i = find_token(document.body, "\\begin_inset Argument", i)
2579 # Find containing paragraph layout
2580 parent = get_containing_layout(document.body, i)
2582 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2587 realparbeg = parent[3]
2588 layoutname = parent[0]
2590 for p in range(parbeg, parend):
2594 if layoutname in shifted_layouts:
2595 m = rx.match(document.body[p])
2599 document.body[p] = "\\begin_inset Argument 1"
2600 if layoutname in corollary_layouts:
2601 m = rx.match(document.body[p])
2605 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2606 endPlain = find_end_of_layout(document.body, beginPlain)
2607 endInset = find_end_of_inset(document.body, p)
2608 content = document.body[beginPlain + 1 : endPlain]
2610 realparend = realparend - len(document.body[p : endInset + 1])
2612 del document.body[p : endInset + 1]
2613 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2614 document.body[realparbeg : realparbeg] = subst
2615 if layoutname == "OverlayArea":
2616 m = rx.match(document.body[p])
2620 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2621 endPlain = find_end_of_layout(document.body, beginPlain)
2622 endInset = find_end_of_inset(document.body, p)
2623 content = document.body[beginPlain + 1 : endPlain]
2625 realparend = realparend - len(document.body[p : endInset + 1])
2627 del document.body[p : endInset + 1]
2628 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2629 document.body[realparbeg : realparbeg] = subst
2630 if layoutname == "AgainFrame":
2631 m = rx.match(document.body[p])
2635 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2636 endPlain = find_end_of_layout(document.body, beginPlain)
2637 endInset = find_end_of_inset(document.body, p)
2638 content = document.body[beginPlain + 1 : endPlain]
2640 realparend = realparend - len(document.body[p : endInset + 1])
2642 del document.body[p : endInset + 1]
2643 subst = put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
2644 document.body[realparbeg : realparbeg] = subst
2648 def revert_beamerargs3(document):
2649 " Reverts beamer arguments to old layout, step 3 "
2651 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2652 if document.textclass not in beamer_classes:
2655 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2658 i = find_token(document.body, "\\begin_inset Argument", i)
2661 # Find containing paragraph layout
2662 parent = get_containing_layout(document.body, i)
2664 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2669 realparbeg = parent[3]
2670 layoutname = parent[0]
2672 for p in range(parbeg, parend):
2676 if layoutname == "AgainFrame":
2677 m = rx.match(document.body[p])
2681 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2682 endPlain = find_end_of_layout(document.body, beginPlain)
2683 endInset = find_end_of_inset(document.body, p)
2684 content = document.body[beginPlain + 1 : endPlain]
2686 realparend = realparend - len(document.body[p : endInset + 1])
2688 del document.body[p : endInset + 1]
2689 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2690 document.body[realparbeg : realparbeg] = subst
2694 def revert_beamerflex(document):
2695 " Reverts beamer Flex insets "
2697 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2698 if document.textclass not in beamer_classes:
2701 new_flexes = {"Bold" : "\\textbf", "Emphasize" : "\\emph", "Only" : "\\only",
2702 "Uncover" : "\\uncover", "Visible" : "\\visible",
2703 "Invisible" : "\\invisible", "Alternative" : "\\alt",
2704 "Beamer_Note" : "\\note"}
2705 old_flexes = {"Alert" : "\\alert", "Structure" : "\\structure"}
2706 rx = re.compile(r'^\\begin_inset Flex (.+)$')
2710 i = find_token(document.body, "\\begin_inset Flex", i)
2713 m = rx.match(document.body[i])
2715 flextype = m.group(1)
2716 z = find_end_of_inset(document.body, i)
2718 document.warning("Can't find end of Flex " + flextype + " inset.")
2721 if flextype in new_flexes:
2722 pre = put_cmd_in_ert(new_flexes[flextype])
2723 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2725 argend = find_end_of_inset(document.body, arg)
2727 document.warning("Can't find end of Argument!")
2730 # Find containing paragraph layout
2731 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2732 endPlain = find_end_of_layout(document.body, beginPlain)
2733 argcontent = document.body[beginPlain + 1 : endPlain]
2735 z = z - len(document.body[arg : argend + 1])
2737 del document.body[arg : argend + 1]
2738 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2739 arg = find_token(document.body, "\\begin_inset Argument 2", i, z)
2741 argend = find_end_of_inset(document.body, arg)
2743 document.warning("Can't find end of Argument!")
2746 # Find containing paragraph layout
2747 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2748 endPlain = find_end_of_layout(document.body, beginPlain)
2749 argcontent = document.body[beginPlain + 1 : endPlain]
2751 z = z - len(document.body[arg : argend + 1])
2753 del document.body[arg : argend + 1]
2754 if flextype == "Alternative":
2755 pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
2757 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2758 pre += put_cmd_in_ert("{")
2759 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2760 endPlain = find_end_of_layout(document.body, beginPlain)
2762 z = z - len(document.body[i : beginPlain + 1])
2764 document.body[i : beginPlain + 1] = pre
2765 post = put_cmd_in_ert("}")
2766 document.body[z - 2 : z + 1] = post
2767 elif flextype in old_flexes:
2768 pre = put_cmd_in_ert(old_flexes[flextype])
2769 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2773 argend = find_end_of_inset(document.body, arg)
2775 document.warning("Can't find end of Argument!")
2778 # Find containing paragraph layout
2779 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2780 endPlain = find_end_of_layout(document.body, beginPlain)
2781 argcontent = document.body[beginPlain + 1 : endPlain]
2783 z = z - len(document.body[arg : argend + 1])
2785 del document.body[arg : argend + 1]
2786 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2787 pre += put_cmd_in_ert("{")
2788 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2789 endPlain = find_end_of_layout(document.body, beginPlain)
2791 z = z - len(document.body[i : beginPlain + 1])
2793 document.body[i : beginPlain + 1] = pre
2794 post = put_cmd_in_ert("}")
2795 document.body[z - 2 : z + 1] = post
2800 def revert_beamerblocks(document):
2801 " Reverts beamer block arguments to ERT "
2803 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2804 if document.textclass not in beamer_classes:
2807 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2809 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2812 i = find_token(document.body, "\\begin_inset Argument", i)
2815 # Find containing paragraph layout
2816 parent = get_containing_layout(document.body, i)
2818 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2823 realparbeg = parent[3]
2824 layoutname = parent[0]
2826 for p in range(parbeg, parend):
2830 if layoutname in blocks:
2831 m = rx.match(document.body[p])
2835 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2836 endPlain = find_end_of_layout(document.body, beginPlain)
2837 endInset = find_end_of_inset(document.body, p)
2838 content = document.body[beginPlain + 1 : endPlain]
2840 realparend = realparend - len(document.body[p : endInset + 1])
2842 del document.body[p : endInset + 1]
2843 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2844 document.body[realparbeg : realparbeg] = subst
2846 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2847 endPlain = find_end_of_layout(document.body, beginPlain)
2848 endInset = find_end_of_inset(document.body, p)
2849 content = document.body[beginPlain + 1 : endPlain]
2851 realparend = realparend - len(document.body[p : endInset + 1])
2853 del document.body[p : endInset + 1]
2854 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2855 document.body[realparbeg : realparbeg] = subst
2860 def convert_beamerblocks(document):
2861 " Converts beamer block ERT args to native InsetArgs "
2863 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2864 if document.textclass not in beamer_classes:
2867 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2871 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2874 parent = get_containing_layout(document.body, i)
2875 if parent == False or parent[1] != i:
2876 document.warning("Wrong parent layout!")
2882 if document.body[parbeg] == "\\begin_inset ERT":
2883 ertcont = parbeg + 5
2885 if document.body[ertcont].startswith("<"):
2886 # This is an overlay specification
2888 document.body[ertcont] = document.body[ertcont][1:]
2889 if document.body[ertcont].endswith(">"):
2891 document.body[ertcont] = document.body[ertcont][:-1]
2892 # Convert to ArgInset
2893 document.body[parbeg] = "\\begin_inset Argument 1"
2894 elif document.body[ertcont].endswith("}"):
2896 tok = document.body[ertcont].find('>{')
2898 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2899 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2900 'status collapsed', '', '\\begin_layout Plain Layout',
2901 document.body[ertcont][tok + 2:-1]]
2902 # Convert to ArgInset
2903 document.body[parbeg] = "\\begin_inset Argument 1"
2904 elif document.body[ertcont].startswith("{"):
2905 # This is the block title
2906 if document.body[ertcont].endswith("}"):
2907 # strip off the braces
2908 document.body[ertcont] = document.body[ertcont][1:-1]
2909 # Convert to ArgInset
2910 document.body[parbeg] = "\\begin_inset Argument 2"
2911 elif count_pars_in_inset(document.body, ertcont) > 1:
2912 # Multipar ERT. Skip this.
2915 convert_TeX_brace_to_Argument(document, i, 2, 2, False, True)
2918 j = find_end_of_layout(document.body, i)
2920 document.warning("end of layout not found!")
2921 k = find_token(document.body, "\\begin_inset Argument", i, j)
2923 document.warning("InsetArgument not found!")
2925 l = find_end_of_inset(document.body, k)
2926 m = find_token(document.body, "\\begin_inset ERT", l, j)
2934 def convert_overprint(document):
2935 " Convert old beamer overprint layouts to ERT "
2937 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2938 if document.textclass not in beamer_classes:
2943 i = find_token(document.body, "\\begin_layout Overprint", i)
2946 # Find end of sequence
2947 j = find_end_of_sequence(document.body, i)
2949 document.warning("Malformed LyX document. Cannot find end of Overprint sequence!")
2953 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
2955 if document.body[j] == "\\end_deeper":
2956 esubst = ["", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
2958 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
2959 endseq = endseq + len(esubst) - len(document.body[j : j])
2960 document.body[j : j] = esubst
2961 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
2963 argend = find_end_of_layout(document.body, argbeg)
2965 document.warning("Malformed LyX document. Cannot find end of Overprint argument!")
2968 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
2969 endPlain = find_end_of_layout(document.body, beginPlain)
2970 content = document.body[beginPlain + 1 : endPlain]
2972 endseq = endseq - len(document.body[argbeg : argend + 1])
2974 del document.body[argbeg : argend + 1]
2975 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2977 endseq = endseq - len(document.body[i : i])
2978 document.body[i : i] = subst + ["\\end_layout"]
2979 endseq += len(subst)
2981 for p in range(i, endseq):
2982 if document.body[p] == "\\begin_layout Overprint":
2983 document.body[p] = "\\begin_layout Standard"
2988 def revert_overprint(document):
2989 " Revert old beamer overprint layouts to ERT "
2991 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2992 if document.textclass not in beamer_classes:
2997 i = find_token(document.body, "\\begin_layout Overprint", i)
3000 # Find end of sequence
3001 j = find_end_of_sequence(document.body, i)
3003 document.warning("Malformed LyX document. Cannot find end of Overprint sequence!")
3007 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
3008 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}")
3009 endseq = endseq + len(esubst) - len(document.body[j : j])
3010 if document.body[j] == "\\end_deeper":
3011 document.body[j : j] = ["\\end_deeper", ""] + esubst
3013 document.body[j : j] = esubst
3016 if document.body[r] == "\\begin_deeper":
3017 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3019 document.body[r] = ""
3020 document.body[s] = ""
3024 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
3026 argend = find_end_of_inset(document.body, argbeg)
3028 document.warning("Malformed LyX document. Cannot find end of Overprint argument!")
3031 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3032 endPlain = find_end_of_layout(document.body, beginPlain)
3033 content = document.body[beginPlain + 1 : endPlain]
3035 endseq = endseq - len(document.body[argbeg : argend])
3037 del document.body[argbeg : argend + 1]
3038 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3040 endseq = endseq - len(document.body[i : i])
3041 document.body[i : i] = subst + ["\\end_layout"]
3042 endseq += len(subst)
3048 if document.body[p] == "\\begin_layout Overprint":
3049 q = find_end_of_layout(document.body, p)
3051 document.warning("Malformed LyX document. Cannot find end of Overprint layout!")
3054 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\onslide")
3055 argbeg = find_token(document.body, "\\begin_inset Argument item:1", p, q)
3057 argend = find_end_of_inset(document.body, argbeg)
3059 document.warning("Malformed LyX document. Cannot find end of Overprint item argument!")
3062 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3063 endPlain = find_end_of_layout(document.body, beginPlain)
3064 content = document.body[beginPlain + 1 : endPlain]
3066 endseq = endseq - len(document.body[argbeg : argend + 1])
3068 del document.body[argbeg : argend + 1]
3069 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3070 endseq = endseq - len(document.body[p : p + 1]) + len(subst)
3071 document.body[p : p + 1] = subst
3077 def revert_frametitle(document):
3078 " Reverts beamer frametitle layout to ERT "
3080 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3081 if document.textclass not in beamer_classes:
3084 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
3087 i = find_token(document.body, "\\begin_layout FrameTitle", i)
3090 j = find_end_of_layout(document.body, i)
3092 document.warning("Malformed LyX document: Can't find end of FrameTitle layout")
3096 document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
3097 endlay += len(put_cmd_in_ert("}"))
3098 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\frametitle")
3099 for p in range(i, j):
3102 m = rx.match(document.body[p])
3106 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3107 endPlain = find_end_of_layout(document.body, beginPlain)
3108 endInset = find_end_of_inset(document.body, p)
3109 content = document.body[beginPlain + 1 : endPlain]
3111 endlay = endlay - len(document.body[p : endInset + 1])
3113 del document.body[p : endInset + 1]
3114 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3116 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3117 endPlain = find_end_of_layout(document.body, beginPlain)
3118 endInset = find_end_of_inset(document.body, p)
3119 content = document.body[beginPlain + 1 : endPlain]
3121 endlay = endlay - len(document.body[p : endInset + 1])
3123 del document.body[p : endInset + 1]
3124 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3126 subst += put_cmd_in_ert("{")
3127 document.body[i : i + 1] = subst
3131 def convert_epigraph(document):
3132 " Converts memoir epigraph to new syntax "
3134 if document.textclass != "memoir":
3139 i = find_token(document.body, "\\begin_layout Epigraph", i)
3142 j = find_end_of_layout(document.body, i)
3144 document.warning("Malformed LyX document: Can't find end of Epigraph layout")
3149 ert = find_token(document.body, "\\begin_inset ERT", i, j)
3151 endInset = find_end_of_inset(document.body, ert)
3152 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", ert)
3153 endPlain = find_end_of_layout(document.body, beginPlain)
3154 ertcont = beginPlain + 2
3155 if document.body[ertcont] == "}{":
3157 # Convert to ArgInset
3158 endlay = endlay - 2 * len(document.body[j])
3159 begsubst = ['\\begin_inset Argument post:1', 'status collapsed', '',
3160 '\\begin_layout Plain Layout']
3161 endsubst = ['\\end_layout', '', '\\end_inset', '', document.body[j]]
3162 document.body[j : j + 1] = endsubst
3163 document.body[endInset + 1 : endInset + 1] = begsubst
3165 endlay += len(begsubst) + len(endsubst)
3166 endlay = endlay - len(document.body[ert : endInset + 1])
3167 del document.body[ert : endInset + 1]
3172 def revert_epigraph(document):
3173 " Reverts memoir epigraph argument to ERT "
3175 if document.textclass != "memoir":
3180 i = find_token(document.body, "\\begin_layout Epigraph", i)
3183 j = find_end_of_layout(document.body, i)
3185 document.warning("Malformed LyX document: Can't find end of Epigraph layout")
3190 p = find_token(document.body, "\\begin_layout Argument post:1", i, j)
3192 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3193 endPlain = find_end_of_layout(document.body, beginPlain)
3194 endInset = find_end_of_inset(document.body, p)
3195 content = document.body[beginPlain + 1 : endPlain]
3197 endlay = endlay - len(document.body[p : endInset + 1])
3199 del document.body[p : endInset + 1]
3200 subst += put_cmd_in_ert("}{") + content
3202 subst += put_cmd_in_ert("}{")
3204 document.body[j : j] = subst + document.body[j : j]
3208 def convert_captioninsets(document):
3209 " Converts caption insets to new syntax "
3213 i = find_token(document.body, "\\begin_inset Caption", i)
3216 document.body[i] = "\\begin_inset Caption Standard"
3220 def revert_captioninsets(document):
3221 " Reverts caption insets to old syntax "
3225 i = find_token(document.body, "\\begin_inset Caption Standard", i)
3228 document.body[i] = "\\begin_inset Caption"
3232 def convert_captionlayouts(document):
3233 " Convert caption layouts to caption insets. "
3236 "Captionabove": "Above",
3237 "Captionbelow": "Below",
3238 "FigCaption" : "FigCaption",
3239 "Table_Caption" : "Table",
3240 "CenteredCaption" : "Centered",
3241 "Bicaption" : "Bicaption",
3246 i = find_token(document.body, "\\begin_layout", i)
3249 val = get_value(document.body, "\\begin_layout", i)
3250 if val in caption_dict.keys():
3251 j = find_end_of_layout(document.body, i)
3253 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3256 document.body[j:j] = ["\\end_layout", "", "\\end_inset", "", ""]
3257 document.body[i:i+1] = ["\\begin_layout %s" % document.default_layout,
3258 "\\begin_inset Caption %s" % caption_dict[val], "",
3259 "\\begin_layout %s" % document.default_layout]
3263 def revert_captionlayouts(document):
3264 " Revert caption insets to caption layouts. "
3267 "Above" : "Captionabove",
3268 "Below" : "Captionbelow",
3269 "FigCaption" : "FigCaption",
3270 "Table" : "Table_Caption",
3271 "Centered" : "CenteredCaption",
3272 "Bicaption" : "Bicaption",
3276 rx = re.compile(r'^\\begin_inset Caption (\S+)$')
3278 i = find_token(document.body, "\\begin_inset Caption", i)
3282 m = rx.match(document.body[i])
3286 if val not in caption_dict.keys():
3290 # We either need to delete the previous \begin_layout line, or we
3291 # need to end the previous layout if this inset is not in the first
3292 # position of the paragraph.
3293 layout_before = find_token_backwards(document.body, "\\begin_layout", i)
3294 if layout_before == -1:
3295 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3297 layout_line = document.body[layout_before]
3298 del_layout_before = True
3299 l = layout_before + 1
3301 if document.body[l] != "":
3302 del_layout_before = False
3305 if del_layout_before:
3306 del document.body[layout_before:i]
3309 document.body[i:i] = ["\\end_layout", ""]
3312 # Find start of layout in the inset and end of inset
3313 j = find_token(document.body, "\\begin_layout", i)
3315 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3317 k = find_end_of_inset(document.body, i)
3319 document.warning("Malformed LyX document: Missing `\\end_inset'.")
3322 # We either need to delete the following \end_layout line, or we need
3323 # to restart the old layout if this inset is not at the paragraph end.
3324 layout_after = find_token(document.body, "\\end_layout", k)
3325 if layout_after == -1:
3326 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3328 del_layout_after = True
3330 while l < layout_after:
3331 if document.body[l] != "":
3332 del_layout_after = False
3335 if del_layout_after:
3336 del document.body[k+1:layout_after+1]
3338 document.body[k+1:k+1] = [layout_line, ""]
3340 # delete \begin_layout and \end_inset and replace \begin_inset with
3341 # "\begin_layout XXX". This works because we can only have one
3342 # paragraph in the caption inset: The old \end_layout will be recycled.
3343 del document.body[k]
3344 if document.body[k] == "":
3345 del document.body[k]
3346 del document.body[j]
3347 if document.body[j] == "":
3348 del document.body[j]
3349 document.body[i] = "\\begin_layout %s" % caption_dict[val]
3350 if document.body[i+1] == "":
3351 del document.body[i+1]
3355 def revert_fragileframe(document):
3356 " Reverts beamer FragileFrame layout to ERT "
3358 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3359 if document.textclass not in beamer_classes:
3364 i = find_token(document.body, "\\begin_layout FragileFrame", i)
3367 # Find end of sequence
3368 j = find_end_of_sequence(document.body, i)
3370 document.warning("Malformed LyX document. Cannot find end of FragileFrame sequence!")
3374 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{frame}")
3375 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{frame}")
3376 endseq = endseq + len(esubst) - len(document.body[j : j])
3377 if document.body[j] == "\\end_deeper":
3378 document.body[j : j] = ["\\end_deeper", ""] + esubst
3380 document.body[j : j] = esubst
3381 for q in range(i, j):
3382 if document.body[q] == "\\begin_layout FragileFrame":
3383 document.body[q] = "\\begin_layout %s" % document.default_layout
3386 if document.body[r] == "\\begin_deeper":
3387 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3389 document.body[r] = ""
3390 document.body[s] = ""
3394 for p in range(1, 5):
3395 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, j)
3398 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3399 endPlain = find_end_of_layout(document.body, beginPlain)
3400 endInset = find_end_of_inset(document.body, arg)
3401 content = document.body[beginPlain + 1 : endPlain]
3403 j = j - len(document.body[arg : endInset + 1])
3405 del document.body[arg : endInset + 1]
3406 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3408 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3409 endPlain = find_end_of_layout(document.body, beginPlain)
3410 endInset = find_end_of_inset(document.body, arg)
3411 content = document.body[beginPlain + 1 : endPlain]
3413 j = j - len(document.body[arg : endInset + 1])
3415 del document.body[arg : endInset + 1]
3416 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3418 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3419 endPlain = find_end_of_layout(document.body, beginPlain)
3420 endInset = find_end_of_inset(document.body, arg)
3421 content = document.body[beginPlain + 1 : endPlain]
3423 j = j - len(document.body[arg : endInset + 1])
3425 del document.body[arg : endInset + 1]
3426 subst += put_cmd_in_ert("[fragile,") + content + put_cmd_in_ert("]")
3428 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3429 endPlain = find_end_of_layout(document.body, beginPlain)
3430 endInset = find_end_of_inset(document.body, arg)
3431 content = document.body[beginPlain + 1 : endPlain]
3433 j = j - len(document.body[arg : endInset + 1])
3435 del document.body[arg : endInset + 1]
3436 subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
3438 subst += put_cmd_in_ert("[fragile]")
3440 document.body[i : i + 1] = subst
3444 def revert_newframes(document):
3445 " Reverts beamer Frame and PlainFrame layouts to old forms "
3447 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3448 if document.textclass not in beamer_classes:
3452 "Frame" : "BeginFrame",
3453 "PlainFrame" : "BeginPlainFrame",
3456 rx = re.compile(r'^\\begin_layout (\S+)$')
3459 i = find_token(document.body, "\\begin_layout", i)
3463 m = rx.match(document.body[i])
3467 if val not in frame_dict.keys():
3470 # Find end of sequence
3471 j = find_end_of_sequence(document.body, i)
3473 document.warning("Malformed LyX document. Cannot find end of Frame sequence!")
3477 subst = ["\\begin_layout %s" % frame_dict[val]]
3478 esubst = ["\\end_layout", "", "\\begin_layout EndFrame", "", "\\end_layout"]
3479 endseq = endseq + len(esubst) - len(document.body[j : j])
3480 if document.body[j] == "\\end_deeper":
3481 document.body[j : j] = ["\\end_deeper", ""] + esubst
3483 document.body[j : j] = esubst
3484 for q in range(i, j):
3485 if document.body[q] == "\\begin_layout %s" % val:
3486 document.body[q] = "\\begin_layout %s" % document.default_layout
3489 if document.body[r] == "\\begin_deeper":
3490 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3492 document.body[r] = ""
3493 document.body[s] = ""
3497 l = find_end_of_layout(document.body, i)
3498 for p in range(1, 5):
3499 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, l)
3502 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3503 endPlain = find_end_of_layout(document.body, beginPlain)
3504 endInset = find_end_of_inset(document.body, arg)
3505 content = document.body[beginPlain + 1 : endPlain]
3507 l = l - len(document.body[arg : endInset + 1])
3509 del document.body[arg : endInset + 1]
3510 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3512 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3513 endPlain = find_end_of_layout(document.body, beginPlain)
3514 endInset = find_end_of_inset(document.body, arg)
3515 content = document.body[beginPlain + 1 : endPlain]
3517 l = l - len(document.body[arg : endInset + 1])
3519 del document.body[arg : endInset + 1]
3520 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3522 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3523 endPlain = find_end_of_layout(document.body, beginPlain)
3524 endInset = find_end_of_inset(document.body, arg)
3525 content = document.body[beginPlain + 1 : endPlain]
3527 l = l - len(document.body[arg : endInset + 1])
3529 del document.body[arg : endInset + 1]
3530 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3532 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3533 endPlain = find_end_of_layout(document.body, beginPlain)
3534 endInset = find_end_of_inset(document.body, arg)
3535 content = document.body[beginPlain + 1 : endPlain]
3537 l = l - len(document.body[arg : endInset + 1])
3539 del document.body[arg : endInset + 1]
3542 document.body[i : i + 1] = subst
3545 # known encodings that do not change their names (same LyX and LaTeX names)
3546 known_enc_tuple = ("auto", "default", "ansinew", "applemac", "armscii8", "ascii",
3547 "cp437", "cp437de", "cp850", "cp852", "cp855", "cp858", "cp862", "cp865", "cp866",
3548 "cp1250", "cp1251", "cp1252", "cp1255", "cp1256", "cp1257", "koi8-r", "koi8-u",
3549 "pt154", "pt254", "tis620-0", "utf8", "utf8x", "utf8-plain")
3551 def convert_encodings(document):
3552 "Use the LyX names of the encodings instead of the LaTeX names."
3553 LaTeX2LyX_enc_dict = {
3554 "8859-6": "iso8859-6",
3555 "8859-8": "iso8859-8",
3557 "euc": "euc-jp-platex",
3562 "iso88595": "iso8859-5",
3563 "iso-8859-7": "iso8859-7",
3565 "jis": "jis-platex",
3567 "l7xenc": "iso8859-13",
3568 "latin1": "iso8859-1",
3569 "latin2": "iso8859-2",
3570 "latin3": "iso8859-3",
3571 "latin4": "iso8859-4",
3572 "latin5": "iso8859-9",
3573 "latin9": "iso8859-15",
3574 "latin10": "iso8859-16",
3575 "SJIS": "shift-jis",
3576 "sjis": "shift-jis-platex",
3579 i = find_token(document.header, "\\inputencoding" , 0)
3582 val = get_value(document.header, "\\inputencoding", i)
3583 if val in LaTeX2LyX_enc_dict.keys():
3584 document.header[i] = "\\inputencoding %s" % LaTeX2LyX_enc_dict[val]
3585 elif val not in known_enc_tuple:
3586 document.warning("Ignoring unknown input encoding: `%s'" % val)
3589 def revert_encodings(document):
3590 """Revert to using the LaTeX names of the encodings instead of the LyX names.
3591 Also revert utf8-platex to sjis, the language default when using Japanese.
3593 LyX2LaTeX_enc_dict = {
3598 "euc-jp-platex": "euc",
3601 "iso8859-1": "latin1",
3602 "iso8859-2": "latin2",
3603 "iso8859-3": "latin3",
3604 "iso8859-4": "latin4",
3605 "iso8859-5": "iso88595",
3606 "iso8859-6": "8859-6",
3607 "iso8859-7": "iso-8859-7",
3608 "iso8859-8": "8859-8",
3609 "iso8859-9": "latin5",
3610 "iso8859-13": "l7xenc",
3611 "iso8859-15": "latin9",
3612 "iso8859-16": "latin10",
3614 "jis-platex": "jis",
3615 "shift-jis": "SJIS",
3616 "shift-jis-platex": "sjis",
3618 "utf8-platex": "sjis"
3620 i = find_token(document.header, "\\inputencoding" , 0)
3623 val = get_value(document.header, "\\inputencoding", i)
3624 if val in LyX2LaTeX_enc_dict.keys():
3625 document.header[i] = "\\inputencoding %s" % LyX2LaTeX_enc_dict[val]
3626 elif val not in known_enc_tuple:
3627 document.warning("Ignoring unknown input encoding: `%s'" % val)
3630 def revert_IEEEtran_3(document):
3632 Reverts Flex Insets to TeX-code
3634 if document.textclass == "IEEEtran":
3640 h = find_token(document.body, "\\begin_inset Flex Author Mark", h)
3642 endh = find_end_of_inset(document.body, h)
3643 document.body[endh - 2 : endh + 1] = put_cmd_in_ert("}")
3644 document.body[h : h + 4] = put_cmd_in_ert("\\IEEEauthorrefmark{")
3647 i = find_token(document.body, "\\begin_inset Flex Author Name", i)
3649 endi = find_end_of_inset(document.body, i)
3650 document.body[endi - 2 : endi + 1] = put_cmd_in_ert("}")
3651 document.body[i : i + 4] = put_cmd_in_ert("\\IEEEauthorblockN{")
3654 j = find_token(document.body, "\\begin_inset Flex Author Affiliation", j)
3656 endj = find_end_of_inset(document.body, j)
3657 document.body[endj - 2 : endj + 1] = put_cmd_in_ert("}")
3658 document.body[j : j + 4] = put_cmd_in_ert("\\IEEEauthorblockA{")
3660 if i == -1 and j == -1 and h == -1:
3664 def revert_kurier_fonts(document):
3665 " Revert kurier font definition to LaTeX "
3667 i = find_token(document.header, "\\font_math", 0)
3669 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3670 val = get_value(document.header, "\\font_math", i)
3671 if val == "kurier-math":
3672 add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
3673 "\\usepackage[math]{kurier}\n" \
3674 "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
3675 document.header[i] = "\\font_math auto"
3677 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3678 kurier_fonts = ["kurier", "kurierc", "kurierl", "kurierlc"]
3679 k = find_token(document.header, "\\font_sans kurier", 0)
3681 sf = get_value(document.header, "\\font_sans", k)
3682 if sf in kurier_fonts:
3683 add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
3684 document.header[k] = "\\font_sans default"
3686 def revert_iwona_fonts(document):
3687 " Revert iwona font definition to LaTeX "
3689 i = find_token(document.header, "\\font_math", 0)
3691 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3692 val = get_value(document.header, "\\font_math", i)
3693 if val == "iwona-math":
3694 add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
3695 "\\usepackage[math]{iwona}\n" \
3696 "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
3697 document.header[i] = "\\font_math auto"
3699 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3700 iwona_fonts = ["iwona", "iwonac", "iwonal", "iwonalc"]
3701 k = find_token(document.header, "\\font_sans iwona", 0)
3703 sf = get_value(document.header, "\\font_sans", k)
3704 if sf in iwona_fonts:
3705 add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
3706 document.header[k] = "\\font_sans default"
3709 def revert_new_libertines(document):
3710 " Revert new libertine font definition to LaTeX "
3712 if find_token(document.header, "\\use_non_tex_fonts true", 0) != -1:
3715 i = find_token(document.header, "\\font_typewriter libertine-mono", 0)
3717 preamble = "\\usepackage"
3718 sc = find_token(document.header, "\\font_tt_scale", 0)
3720 scval = get_value(document.header, "\\font_tt_scale", sc)
3722 preamble += "[scale=%f]" % (float(scval) / 100)
3723 document.header[sc] = "\\font_tt_scale 100"
3724 preamble += "{libertineMono-type1}"
3725 add_to_preamble(document, [preamble])
3726 document.header[i] = "\\font_typewriter default"
3728 k = find_token(document.header, "\\font_sans biolinum", 0)
3730 preamble = "\\usepackage"
3732 j = find_token(document.header, "\\font_osf true", 0)
3737 sc = find_token(document.header, "\\font_sf_scale", 0)
3739 scval = get_value(document.header, "\\font_sf_scale", sc)
3741 options += ",scale=%f" % (float(scval) / 100)
3742 document.header[sc] = "\\font_sf_scale 100"
3744 preamble += "[" + options +"]"
3745 preamble += "{biolinum-type1}"
3746 add_to_preamble(document, [preamble])
3747 document.header[k] = "\\font_sans default"
3750 def convert_lyxframes(document):
3751 " Converts old beamer frames to new style "
3753 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3754 if document.textclass not in beamer_classes:
3757 framebeg = ["BeginFrame", "BeginPlainFrame"]
3758 frameend = ["Frame", "PlainFrame", "EndFrame", "BeginFrame", "BeginPlainFrame", "AgainFrame",
3759 "Section", "Section*", "Subsection", "Subsection*", "Subsubsection", "Subsubsection*"]
3760 for lay in framebeg:
3763 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
3766 parent = get_containing_layout(document.body, i)
3767 if parent == False or parent[1] != i:
3768 document.warning("Wrong parent layout!")
3771 frametype = parent[0]
3775 # Step I: Convert ERT arguments
3776 # FIXME: This currently only works if the arguments are in one single ERT
3778 if document.body[parbeg] == "\\begin_inset ERT":
3779 ertend = find_end_of_inset(document.body, parbeg)
3781 document.warning("Malformed LyX document: missing ERT \\end_inset")
3783 ertcont = parbeg + 5
3784 if document.body[ertcont].startswith("[<"):
3785 # This is a default overlay specification
3787 document.body[ertcont] = document.body[ertcont][2:]
3788 if document.body[ertcont].endswith(">]"):
3790 document.body[ertcont] = document.body[ertcont][:-2]
3791 elif document.body[ertcont].endswith("]"):
3793 tok = document.body[ertcont].find('>][')
3795 subst = [document.body[ertcont][:tok],
3796 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
3797 'status collapsed', '', '\\begin_layout Plain Layout',
3798 document.body[ertcont][tok + 3:-1]]
3799 document.body[ertcont : ertcont + 1] = subst
3801 # Convert to ArgInset
3802 document.body[parbeg] = "\\begin_inset Argument 2"
3803 elif document.body[ertcont].startswith("<"):
3804 # This is an overlay specification
3806 document.body[ertcont] = document.body[ertcont][1:]
3807 if document.body[ertcont].endswith(">"):
3809 document.body[ertcont] = document.body[ertcont][:-1]
3810 # Convert to ArgInset
3811 document.body[parbeg] = "\\begin_inset Argument 1"
3812 elif document.body[ertcont].endswith(">]"):
3814 tok = document.body[ertcont].find('>[<')
3816 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
3817 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
3818 'status collapsed', '', '\\begin_layout Plain Layout',
3819 document.body[ertcont][tok + 3:-2]]
3820 # Convert to ArgInset
3821 document.body[parbeg] = "\\begin_inset Argument 1"
3823 elif document.body[ertcont].endswith("]"):
3825 tok = document.body[ertcont].find('>[<')
3828 tokk = document.body[ertcont].find('>][')
3830 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
3831 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
3832 'status collapsed', '', '\\begin_layout Plain Layout',
3833 document.body[ertcont][tok + 3:tokk],
3834 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
3835 'status collapsed', '', '\\begin_layout Plain Layout',
3836 document.body[ertcont][tokk + 3:-1]]
3839 tokk = document.body[ertcont].find('>[')
3841 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tokk],
3842 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
3843 'status collapsed', '', '\\begin_layout Plain Layout',
3844 document.body[ertcont][tokk + 2:-1]]
3846 # Convert to ArgInset
3847 document.body[parbeg] = "\\begin_inset Argument 1"
3848 elif document.body[ertcont].startswith("["):
3849 # This is an ERT option
3851 document.body[ertcont] = document.body[ertcont][1:]
3852 if document.body[ertcont].endswith("]"):
3854 document.body[ertcont] = document.body[ertcont][:-1]
3855 # Convert to ArgInset
3856 document.body[parbeg] = "\\begin_inset Argument 3"
3857 # End of argument conversion
3858 # Step II: Now rename the layout and convert the title to an argument
3859 j = find_end_of_layout(document.body, i)
3860 document.body[j : j + 1] = ['\\end_layout', '', '\\end_inset', '', '\\end_layout']
3861 if lay == "BeginFrame":
3862 document.body[i] = "\\begin_layout Frame"
3864 document.body[i] = "\\begin_layout PlainFrame"
3865 document.body[ertend + 1 : ertend + 1] = ['\\begin_inset Argument 4',
3866 'status open', '', '\\begin_layout Plain Layout']
3867 # Step III: find real frame end
3871 fend = find_token(document.body, "\\begin_layout", jj)
3873 document.warning("Malformed LyX document: No real frame end!")
3875 val = get_value(document.body, "\\begin_layout", fend)
3876 if val not in frameend:
3879 old = document.body[fend]
3880 if val == frametype:
3881 document.body[fend : fend] = ['\\end_deeper', '', '\\begin_layout Separator', '', '\\end_layout']
3883 document.body[fend : fend] = ['\\end_deeper']
3884 document.body[j + 1 : j + 1] = ['', '\\begin_deeper']
3889 def remove_endframes(document):
3890 " Remove deprecated beamer endframes "
3892 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3893 if document.textclass not in beamer_classes:
3898 i = find_token_exact(document.body, "\\begin_layout EndFrame", i)
3901 j = find_end_of_layout(document.body, i)
3903 document.warning("Malformed LyX document: Missing \\end_layout to EndFrame")
3906 del document.body[i : j + 1]
3909 def revert_powerdot_flexes(document):
3910 " Reverts powerdot flex insets "
3912 if document.textclass != "powerdot":
3915 flexes = {"Onslide" : "\\onslide",
3916 "Onslide*" : "\\onslide*",
3917 "Onslide+" : "\\onslide+"}
3918 rx = re.compile(r'^\\begin_inset Flex (.+)$')
3922 i = find_token(document.body, "\\begin_inset Flex", i)
3925 m = rx.match(document.body[i])
3927 flextype = m.group(1)
3928 z = find_end_of_inset(document.body, i)
3930 document.warning("Can't find end of Flex " + flextype + " inset.")
3933 if flextype in flexes:
3934 pre = put_cmd_in_ert(flexes[flextype])
3935 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
3937 argend = find_end_of_inset(document.body, arg)
3939 document.warning("Can't find end of Argument!")
3942 # Find containing paragraph layout
3943 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3944 endPlain = find_end_of_layout(document.body, beginPlain)
3945 argcontent = document.body[beginPlain + 1 : endPlain]
3947 z = z - len(document.body[arg : argend + 1])
3949 del document.body[arg : argend + 1]
3950 pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
3951 pre += put_cmd_in_ert("{")
3952 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
3953 endPlain = find_end_of_layout(document.body, beginPlain)
3955 z = z - len(document.body[i : beginPlain + 1])
3957 document.body[i : beginPlain + 1] = pre
3958 post = put_cmd_in_ert("}")
3959 document.body[z - 2 : z + 1] = post
3963 def revert_powerdot_pause(document):
3964 " Reverts powerdot pause layout to ERT "
3966 if document.textclass != "powerdot":
3971 i = find_token(document.body, "\\begin_layout Pause", i)
3974 j = find_end_of_layout(document.body, i)
3976 document.warning("Malformed LyX document: Can't find end of Pause layout")
3980 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\pause")
3981 for p in range(i, j):
3984 arg = find_token(document.body, "\\begin_inset Argument 1", i, j)
3986 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3987 endPlain = find_end_of_layout(document.body, beginPlain)
3988 endInset = find_end_of_inset(document.body, p)
3989 content = document.body[beginPlain + 1 : endPlain]
3991 endlay = endlay - len(document.body[p : endInset + 1])
3993 del document.body[p : endInset + 1]
3994 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3996 document.body[i : i + 1] = subst
4000 def revert_powerdot_itemargs(document):
4001 " Reverts powerdot item arguments to ERT "
4003 if document.textclass != "powerdot":
4007 list_layouts = ["Itemize", "ItemizeType1", "Enumerate", "EnumerateType1"]
4008 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
4011 i = find_token(document.body, "\\begin_inset Argument", i)
4014 # Find containing paragraph layout
4015 parent = get_containing_layout(document.body, i)
4017 document.warning("Malformed LyX document: Can't find parent paragraph layout")
4022 realparbeg = parent[3]
4023 layoutname = parent[0]
4025 for p in range(parbeg, parend):
4029 if layoutname in list_layouts:
4030 m = rx.match(document.body[p])
4033 if argnr == "item:1":
4034 j = find_end_of_inset(document.body, i)
4035 # Find containing paragraph layout
4036 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
4037 endPlain = find_end_of_layout(document.body, beginPlain)
4038 content = document.body[beginPlain + 1 : endPlain]
4039 del document.body[i:j+1]
4040 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
4041 document.body[realparbeg : realparbeg] = subst
4042 elif argnr == "item:2":
4043 j = find_end_of_inset(document.body, i)
4044 # Find containing paragraph layout
4045 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
4046 endPlain = find_end_of_layout(document.body, beginPlain)
4047 content = document.body[beginPlain + 1 : endPlain]
4048 del document.body[i:j+1]
4049 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
4050 document.body[realparbeg : realparbeg] = subst
4055 def revert_powerdot_columns(document):
4056 " Reverts powerdot twocolumn to TeX-code "
4057 if document.textclass != "powerdot":
4060 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
4063 i = find_token(document.body, "\\begin_layout Twocolumn", i)
4066 j = find_end_of_layout(document.body, i)
4068 document.warning("Malformed LyX document: Can't find end of Twocolumn layout")
4072 document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
4073 endlay += len(put_cmd_in_ert("}"))
4074 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\twocolumn")
4075 for p in range(i, j):
4078 m = rx.match(document.body[p])
4082 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
4083 endPlain = find_end_of_layout(document.body, beginPlain)
4084 endInset = find_end_of_inset(document.body, p)
4085 content = document.body[beginPlain + 1 : endPlain]
4087 endlay = endlay - len(document.body[p : endInset + 1])
4089 del document.body[p : endInset + 1]
4090 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
4092 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
4093 endPlain = find_end_of_layout(document.body, beginPlain)
4094 endInset = find_end_of_inset(document.body, p)
4095 content = document.body[beginPlain + 1 : endPlain]
4097 endlay = endlay - len(document.body[p : endInset + 1])
4099 del document.body[p : endInset + 1]
4100 subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
4102 subst += put_cmd_in_ert("{")
4103 document.body[i : i + 1] = subst
4107 def revert_mbox_fbox(document):
4108 'Convert revert mbox/fbox boxes to TeX-code'
4111 i = find_token(document.body, "\\begin_inset Box", i)
4114 j = find_token(document.body, "width", i)
4116 document.warning("Malformed LyX document: Can't find box width")
4118 width = get_value(document.body, "width", j)
4119 k = find_end_of_inset(document.body, j)
4121 document.warning("Malformed LyX document: Can't find end of box inset")
4124 BeginLayout = find_token(document.body, "\\begin_layout Plain Layout", j)
4125 EndLayout = find_token(document.body, "\\end_layout", BeginLayout)
4126 # replace if width is ""
4128 document.body[EndLayout:k + 1] = put_cmd_in_ert("}")
4129 if document.body[i] == "\\begin_inset Box Frameless":
4130 document.body[i:BeginLayout + 1] = put_cmd_in_ert("\\mbox{")
4131 if document.body[i] == "\\begin_inset Box Boxed":
4132 document.body[i:BeginLayout + 1] = put_cmd_in_ert("\\fbox{")
4136 def revert_starred_caption(document):
4137 " Reverts unnumbered longtable caption insets "
4141 i = find_token(document.body, "\\begin_inset Caption LongTableNoNumber", i)
4144 # This is not equivalent, but since the caption inset is a full blown
4145 # text inset a true conversion to ERT is too difficult.
4146 document.body[i] = "\\begin_inset Caption Standard"
4150 def revert_forced_local_layout(document):
4153 i = find_token(document.header, "\\begin_forced_local_layout", i)
4156 j = find_end_of(document.header, i, "\\begin_forced_local_layout", "\\end_forced_local_layout")
4158 # this should not happen
4160 regexp = re.compile(r'\s*forcelocal', re.IGNORECASE)
4161 k = find_re(document.header, regexp, i, j)
4163 del document.header[k]
4165 k = find_re(document.header, regexp, i, j)
4166 k = find_token(document.header, "\\begin_local_layout", 0)
4168 document.header[i] = "\\begin_local_layout"
4169 document.header[j] = "\\end_local_layout"
4171 l = find_end_of(document.header, k, "\\begin_local_layout", "\\end_local_layout")
4173 # this should not happen
4175 lines = document.header[i+1 : j]
4177 document.header[k+1 : k+1] = lines
4178 document.header[i : j ] = []
4180 document.header[i : j ] = []
4181 document.header[k+1 : k+1] = lines
4184 def revert_aa1(document):
4185 " Reverts InsetArguments of aa to TeX-code "
4186 if document.textclass == "aa":
4190 i = find_token(document.body, "\\begin_layout Abstract (structured)", i)
4192 revert_Argument_to_TeX_brace(document, i, 0, 1, 4, False, False)
4198 def revert_aa2(document):
4199 " Reverts InsetArguments of aa to TeX-code "
4200 if document.textclass == "aa":
4204 i = find_token(document.body, "\\begin_layout Abstract (structured)", i)
4206 document.body[i] = "\\begin_layout Abstract"
4212 def revert_tibetan(document):
4213 "Set the document language for Tibetan to English"
4215 if document.language == "tibetan":
4216 document.language = "english"
4217 i = find_token(document.header, "\\language", 0)
4219 document.header[i] = "\\language english"
4221 while j < len(document.body):
4222 j = find_token(document.body, "\\lang tibetan", j)
4224 document.body[j] = document.body[j].replace("\\lang tibetan", "\\lang english")
4227 j = len(document.body)
4236 # the idea here is that we will have a sequence of chunk paragraphs
4237 # we want to convert them to paragraphs in a chunk inset
4238 # the last will be discarded
4239 # the first should look like: <<FROGS>>=
4240 # will will discard the delimiters, and put the contents into the
4241 # optional argument of the inset
4242 def convert_chunks(document):
4243 first_re = re.compile(r'<<(.*)>>=')
4246 # the beginning of this sequence
4248 # find start of a block of chunks
4249 i = find_token(document.body, "\\begin_layout Chunk", i)
4257 # process the one we just found
4258 j = find_end_of_layout(document.body, i)
4260 document.warning("Malformed LyX documents. Can't find end of Chunk layout!")
4262 thischunk = "".join(document.body[i + 1:j])
4263 contents.append(document.body[i + 1:j])
4265 if thischunk == "@":
4268 # look for the next one
4270 i = find_token(document.body, "\\begin_layout", i)
4274 layout = get_value(document.body, "\\begin_layout", i)
4275 #sys.stderr.write(layout+ '\n')
4276 if layout != "Chunk":
4280 # error, but we can try to continue
4287 # the last chunk should simply have an "@" in it
4289 if ''.join(contents[-1]) != "@":
4290 document.warning("Unexpected chunk contents.")
4295 # the first item should look like: <<FROGS>>=
4296 # we want the inside
4297 optarg = ' '.join(contents[0])
4299 match = first_re.search(optarg)
4301 optarg = match.groups()[0]
4304 newstuff = ['\\begin_layout Standard',
4305 '\\begin_inset Flex Chunk',
4307 '\\begin_layout Plain Layout', '']
4311 ['\\begin_inset Argument 1',
4313 '\\begin_layout Plain Layout',
4321 newstuff.extend(['', '\\begin_layout Plain Layout', ''])
4325 newstuff.append('\\end_layout')
4327 newstuff.extend(['', '\\end_inset', '', '\\end_layout', ''])
4329 document.body[start:end] = newstuff
4331 k += len(newstuff) - (end - start)
4334 def revert_chunks(document):
4337 i = find_token(document.body, "\\begin_inset Flex Chunk", i)
4341 iend = find_end_of_inset(document.body, i)
4343 document.warning("Can't find end of Chunk!")
4347 # Look for optional argument
4349 ostart = find_token(document.body, "\\begin_inset Argument 1", i, iend)
4351 oend = find_end_of_inset(document.body, ostart)
4352 k = find_token(document.body, "\\begin_layout Plain Layout", ostart, oend)
4354 document.warning("Malformed LyX document: Can't find argument contents!")
4356 m = find_end_of_layout(document.body, k)
4357 optarg = "".join(document.body[k+1:m])
4360 # We now remove the optional argument, so we have something
4361 # uniform on which to work
4362 document.body[ostart : oend + 1] = []
4363 # iend is now invalid
4364 iend = find_end_of_inset(document.body, i)
4366 retval = get_containing_layout(document.body, i)
4368 document.warning("Can't find containing layout for Chunk!")
4371 (lname, lstart, lend, pstart) = retval
4372 # we now want to work through the various paragraphs, and collect their contents
4376 k = find_token(document.body, "\\begin_layout Plain Layout", k, lend)
4379 j = find_end_of_layout(document.body, k)
4381 document.warning("Can't find end of layout inside chunk!")
4383 parlist.append(document.body[k+1:j])
4385 # we now need to wrap all of these paragraphs in chunks
4388 newlines.extend(["\\begin_layout Chunk", "", "<<" + optarg + ">>=", "\\end_layout", ""])
4389 for stuff in parlist:
4390 newlines.extend(["\\begin_layout Chunk"] + stuff + ["\\end_layout", ""])
4391 newlines.extend(["\\begin_layout Chunk", "", "@", "\\end_layout", ""])
4392 # replace old content with new content
4393 document.body[lstart : lend + 1] = newlines
4394 i = lstart + len(newlines)
4401 supported_versions = ["2.1.0","2.1"]
4404 [415, [convert_undertilde]],
4406 [417, [convert_japanese_encodings]],
4409 [420, [convert_biblio_style]],
4410 [421, [convert_longtable_captions]],
4411 [422, [convert_use_packages]],
4412 [423, [convert_use_mathtools]],
4413 [424, [convert_cite_engine_type]],
4417 [428, [convert_cell_rotation]],
4418 [429, [convert_table_rotation]],
4419 [430, [convert_listoflistings]],
4420 [431, [convert_use_amssymb]],
4422 [433, [convert_armenian]],
4430 [441, [convert_mdnomath]],
4435 [446, [convert_latexargs]],
4436 [447, [convert_IEEEtran, convert_AASTeX, convert_AGUTeX, convert_IJMP, convert_SIGPLAN, convert_SIGGRAPH, convert_EuropeCV, convert_Initials, convert_ModernCV]],
4437 [448, [convert_literate]],
4440 [451, [convert_beamerargs, convert_againframe_args, convert_corollary_args, convert_quote_args]],
4441 [452, [convert_beamerblocks]],
4442 [453, [convert_use_stmaryrd]],
4443 [454, [convert_overprint]],
4445 [456, [convert_epigraph]],
4446 [457, [convert_use_stackrel]],
4447 [458, [convert_captioninsets, convert_captionlayouts]],
4452 [463, [convert_encodings]],
4453 [464, [convert_use_cancel]],
4454 [465, [convert_lyxframes, remove_endframes]],
4460 [471, [convert_cite_engine_type_default]],
4463 [474, [convert_chunks]],
4467 [473, [revert_chunks]],
4468 [472, [revert_tibetan]],
4469 [471, [revert_aa1,revert_aa2]],
4470 [470, [revert_cite_engine_type_default]],
4471 [469, [revert_forced_local_layout]],
4472 [468, [revert_starred_caption]],
4473 [467, [revert_mbox_fbox]],
4474 [466, [revert_iwona_fonts]],
4475 [465, [revert_powerdot_flexes, revert_powerdot_pause, revert_powerdot_itemargs, revert_powerdot_columns]],
4477 [463, [revert_use_cancel]],
4478 [462, [revert_encodings]],
4479 [461, [revert_new_libertines]],
4480 [460, [revert_kurier_fonts]],
4481 [459, [revert_IEEEtran_3]],
4482 [458, [revert_fragileframe, revert_newframes]],
4483 [457, [revert_captioninsets, revert_captionlayouts]],
4484 [456, [revert_use_stackrel]],
4485 [455, [revert_epigraph]],
4486 [454, [revert_frametitle]],
4487 [453, [revert_overprint]],
4488 [452, [revert_use_stmaryrd]],
4489 [451, [revert_beamerblocks]],
4490 [450, [revert_beamerargs, revert_beamerargs2, revert_beamerargs3, revert_beamerflex]],
4491 [449, [revert_garamondx, revert_garamondx_newtxmath]],
4492 [448, [revert_itemargs]],
4493 [447, [revert_literate]],
4494 [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]],
4495 [445, [revert_latexargs]],
4496 [444, [revert_uop]],
4497 [443, [revert_biolinum]],
4499 [441, [revert_newtxmath]],
4500 [440, [revert_mdnomath]],
4501 [439, [revert_mathfonts]],
4502 [438, [revert_minionpro]],
4503 [437, [revert_ipadeco, revert_ipachar]],
4504 [436, [revert_texgyre]],
4505 [435, [revert_mathdesign]],
4506 [434, [revert_txtt]],
4507 [433, [revert_libertine]],
4508 [432, [revert_armenian]],
4509 [431, [revert_languages, revert_ancientgreek]],
4510 [430, [revert_use_amssymb]],
4511 [429, [revert_listoflistings]],
4512 [428, [revert_table_rotation]],
4513 [427, [revert_cell_rotation]],
4514 [426, [revert_tipa]],
4515 [425, [revert_verbatim]],
4516 [424, [revert_cancel]],
4517 [423, [revert_cite_engine_type]],
4518 [422, [revert_use_mathtools]],
4519 [421, [revert_use_packages]],
4520 [420, [revert_longtable_captions]],
4521 [419, [revert_biblio_style]],
4522 [418, [revert_australian]],
4523 [417, [revert_justification]],
4524 [416, [revert_japanese_encodings]],
4525 [415, [revert_negative_space, revert_math_spaces]],
4526 [414, [revert_undertilde]],
4527 [413, [revert_visible_space]]
4531 if __name__ == "__main__":