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":
1605 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{")
1614 def convert_IEEEtran(document):
1619 Biography without photo
1622 if document.textclass == "IEEEtran":
1628 i = find_token(document.body, "\\begin_layout Page headings", i)
1630 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1633 j = find_token(document.body, "\\begin_layout Biography without photo", j)
1635 convert_TeX_brace_to_Argument(document, j, 1, 1, False, True)
1638 # assure that we don't handle Biography Biography without photo
1639 k = find_token(document.body, "\\begin_layout Biography", k)
1640 kA = find_token(document.body, "\\begin_layout Biography without photo", k - 1)
1641 if k == kA and k != -1:
1645 # the argument we want to convert is the second one
1646 convert_TeX_brace_to_Argument(document, k, 2, 2, False, True)
1648 if i == -1 and j == -1 and k == -1:
1652 def revert_AASTeX(document):
1653 " Reverts InsetArgument of Altaffilation to TeX-code "
1654 if document.textclass == "aastex":
1657 i = find_token(document.body, "\\begin_layout Altaffilation", i)
1660 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1664 def convert_AASTeX(document):
1665 " Converts ERT of Altaffilation to InsetArgument "
1666 if document.textclass == "aastex":
1669 i = find_token(document.body, "\\begin_layout Altaffilation", i)
1672 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1676 def revert_AGUTeX(document):
1677 " Reverts InsetArgument of Author affiliation to TeX-code "
1678 if document.textclass == "agutex":
1681 i = find_token(document.body, "\\begin_layout Author affiliation", i)
1684 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1688 def convert_AGUTeX(document):
1689 " Converts ERT of Author affiliation to InsetArgument "
1690 if document.textclass == "agutex":
1693 i = find_token(document.body, "\\begin_layout Author affiliation", i)
1696 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1700 def revert_IJMP(document):
1701 " Reverts InsetArgument of MarkBoth to TeX-code "
1702 if document.textclass == "ijmpc" or document.textclass == "ijmpd":
1705 i = find_token(document.body, "\\begin_layout MarkBoth", i)
1708 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1712 def convert_IJMP(document):
1713 " Converts ERT of MarkBoth to InsetArgument "
1714 if document.textclass == "ijmpc" or document.textclass == "ijmpd":
1717 i = find_token(document.body, "\\begin_layout MarkBoth", i)
1720 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1724 def revert_SIGPLAN(document):
1725 " Reverts InsetArguments of SIGPLAN to TeX-code "
1726 if document.textclass == "sigplanconf":
1731 i = find_token(document.body, "\\begin_layout Conference", i)
1733 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1736 j = find_token(document.body, "\\begin_layout Author", j)
1738 revert_Argument_to_TeX_brace(document, j, 0, 1, 2, False, False)
1740 if i == -1 and j == -1:
1744 def convert_SIGPLAN(document):
1745 " Converts ERT of SIGPLAN to InsetArgument "
1746 if document.textclass == "sigplanconf":
1751 i = find_token(document.body, "\\begin_layout Conference", i)
1753 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1756 j = find_token(document.body, "\\begin_layout Author", j)
1758 convert_TeX_brace_to_Argument(document, j, 1, 2, False, False)
1760 if i == -1 and j == -1:
1764 def revert_SIGGRAPH(document):
1765 " Reverts InsetArgument of Flex CRcat to TeX-code "
1766 if document.textclass == "acmsiggraph":
1769 i = find_token(document.body, "\\begin_inset Flex CRcat", i)
1772 revert_Argument_to_TeX_brace(document, i, 0, 1, 3, False, False)
1776 def convert_SIGGRAPH(document):
1777 " Converts ERT of Flex CRcat to InsetArgument "
1778 if document.textclass == "acmsiggraph":
1781 i = find_token(document.body, "\\begin_inset Flex CRcat", i)
1784 convert_TeX_brace_to_Argument(document, i, 1, 3, True, False)
1788 def revert_EuropeCV(document):
1789 " Reverts InsetArguments of europeCV to TeX-code "
1790 if document.textclass == "europecv":
1797 i = find_token(document.body, "\\begin_layout Item", i)
1799 revert_Argument_to_TeX_brace(document, i, 0, 2, 2, False, False)
1802 j = find_token(document.body, "\\begin_layout BulletedItem", j)
1804 revert_Argument_to_TeX_brace(document, j, 0, 2, 2, False, False)
1807 k = find_token(document.body, "\\begin_layout Language", k)
1809 revert_Argument_to_TeX_brace(document, k, 0, 2, 6, False, False)
1812 m = find_token(document.body, "\\begin_layout LastLanguage", m)
1814 revert_Argument_to_TeX_brace(document, m, 0, 2, 6, False, False)
1816 if i == -1 and j == -1 and k == -1 and m == -1:
1820 def convert_EuropeCV(document):
1821 " Converts ERT of europeCV to InsetArgument "
1822 if document.textclass == "europecv":
1829 i = find_token(document.body, "\\begin_layout Item", i)
1831 convert_TeX_brace_to_Argument(document, i, 2, 2, False, False)
1834 j = find_token(document.body, "\\begin_layout BulletedItem", j)
1836 convert_TeX_brace_to_Argument(document, j, 2, 2, False, False)
1839 k = find_token(document.body, "\\begin_layout Language", k)
1841 convert_TeX_brace_to_Argument(document, k, 2, 6, False, False)
1844 m = find_token(document.body, "\\begin_layout LastLanguage", m)
1846 convert_TeX_brace_to_Argument(document, m, 2, 6, False, False)
1848 if i == -1 and j == -1 and k == -1 and m == -1:
1852 def revert_ModernCV(document):
1853 " Reverts InsetArguments of modernCV to TeX-code "
1854 if document.textclass == "moderncv":
1862 j = find_token(document.body, "\\begin_layout Entry", j)
1864 revert_Argument_to_TeX_brace(document, j, 0, 1, 5, False, False)
1867 k = find_token(document.body, "\\begin_layout Item", k)
1869 revert_Argument_to_TeX_brace(document, k, 0, 1, 1, False, False)
1872 m = find_token(document.body, "\\begin_layout ItemWithComment", m)
1874 revert_Argument_to_TeX_brace(document, m, 0, 1, 2, False, False)
1875 document.body[m] = document.body[m].replace("\\begin_layout ItemWithComment", "\\begin_layout Language")
1878 o = find_token(document.body, "\\begin_layout DoubleItem", o)
1880 revert_Argument_to_TeX_brace(document, o, 0, 1, 3, False, False)
1881 document.body[o] = document.body[o].replace("\\begin_layout DoubleItem", "\\begin_layout Computer")
1884 p = find_token(document.body, "\\begin_layout Social", p)
1886 revert_Argument_to_TeX_brace(document, p, 0, 1, 1, False, True)
1888 if j == -1 and k == -1 and m == -1 and o == -1 and p == -1:
1892 def revert_ModernCV_2(document):
1893 " Reverts the Flex:Column inset of modernCV to TeX-code "
1894 if document.textclass == "moderncv":
1898 flex = find_token(document.body, "\\begin_inset Flex Column", flex)
1901 flexEnd = find_end_of_inset(document.body, flex)
1902 wasOpt = revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, False, True)
1903 revert_Argument_to_TeX_brace(document, flex, 0, 2, 2, False, False)
1904 flexEnd = find_end_of_inset(document.body, flex)
1906 document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\cvcolumn")
1908 document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\cvcolumn{")
1909 document.body[flexEnd + 4 : flexEnd + 7] = put_cmd_in_ert("}")
1913 def revert_ModernCV_3(document):
1914 " Reverts the Column style of modernCV to TeX-code "
1915 if document.textclass == "moderncv":
1916 # revert the layouts
1917 revert_ModernCV(document)
1919 # get the position of the end of the last column inset
1920 LastFlexEnd = revert_ModernCV_2(document)
1922 p = find_token(document.body, "\\begin_layout Columns", p)
1925 pEnd = find_end_of_layout(document.body, p)
1926 document.body[p] = document.body[p].replace("\\begin_layout Columns", "\\begin_layout Standard")
1927 if LastFlexEnd != -1:
1928 document.body[p + 1 : p + 1] = put_cmd_in_ert("\\begin{cvcolumns}")
1929 document.body[LastFlexEnd + 24 : LastFlexEnd + 24] = put_cmd_in_ert("\\end{cvcolumns}")
1933 def revert_ModernCV_4(document):
1934 " Reverts the style Social to TeX-code "
1935 if document.textclass == "moderncv":
1936 # revert the layouts
1937 revert_ModernCV(document)
1940 p = find_token(document.body, "\\begin_layout Social", p)
1943 pEnd = find_end_of_layout(document.body, p)
1944 document.body[p] = document.body[p].replace("\\begin_layout Social", "\\begin_layout Standard")
1945 document.body[p + 1 : p + 1] = put_cmd_in_ert("\\social")
1946 hasOpt = find_token(document.body, "[", p + 9)
1948 document.body[p + 30 : p + 30] = put_cmd_in_ert("{")
1949 document.body[p + 41 : p + 41] = put_cmd_in_ert("}")
1951 document.body[p + 11 : p + 11] = put_cmd_in_ert("{")
1952 document.body[p + 21 : p + 21] = put_cmd_in_ert("}")
1956 def convert_ModernCV(document):
1957 " Converts ERT of modernCV to InsetArgument "
1958 if document.textclass == "moderncv":
1966 i = find_token(document.body, "\\begin_layout DoubleItem", i)
1968 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1969 document.body[o] = document.body[o].replace("\\begin_layout DoubleItem", "\\begin_layout DoubleListItem")
1972 j = find_token(document.body, "\\begin_layout Entry", j)
1974 convert_TeX_brace_to_Argument(document, j, 1, 5, False, False)
1977 k = find_token(document.body, "\\begin_layout Item", k)
1979 convert_TeX_brace_to_Argument(document, k, 1, 1, False, False)
1982 m = find_token(document.body, "\\begin_layout Language", m)
1984 convert_TeX_brace_to_Argument(document, m, 1, 2, False, False)
1986 if i == -1 and j == -1 and k == -1 and m == -1:
1990 def revert_Initials(document):
1991 " Reverts InsetArgument of Initial to TeX-code "
1994 i = find_token(document.body, "\\begin_layout Initial", i)
1997 # first arg (optional) and second arg (first mandatory) are supported in LyX 2.0.x
1998 revert_Argument_to_TeX_brace(document, i, 0, 3, 3, False, False)
2002 def convert_Initials(document):
2003 " Converts ERT of Initial to InsetArgument "
2006 i = find_token(document.body, "\\begin_layout Initial", i)
2009 convert_TeX_brace_to_Argument(document, i, 3, 3, False, False)
2013 def revert_literate(document):
2014 " Revert Literate document to old format "
2015 if del_token(document.header, "noweb", 0):
2016 document.textclass = "literate-" + document.textclass
2019 i = find_token(document.body, "\\begin_layout Chunk", i)
2022 document.body[i] = "\\begin_layout Scrap"
2026 def convert_literate(document):
2027 " Convert Literate document to new format"
2028 i = find_token(document.header, "\\textclass", 0)
2029 if (i != -1) and "literate-" in document.header[i]:
2030 document.textclass = document.header[i].replace("\\textclass literate-", "")
2031 j = find_token(document.header, "\\begin_modules", 0)
2033 document.header.insert(j + 1, "noweb")
2035 document.header.insert(i + 1, "\\end_modules")
2036 document.header.insert(i + 1, "noweb")
2037 document.header.insert(i + 1, "\\begin_modules")
2040 i = find_token(document.body, "\\begin_layout Scrap", i)
2043 document.body[i] = "\\begin_layout Chunk"
2047 def revert_itemargs(document):
2048 " Reverts \\item arguments to TeX-code "
2051 i = find_token(document.body, "\\begin_inset Argument item:", i)
2054 j = find_end_of_inset(document.body, i)
2055 # Find containing paragraph layout
2056 parent = get_containing_layout(document.body, i)
2058 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2062 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2063 endPlain = find_end_of_layout(document.body, beginPlain)
2064 content = document.body[beginPlain + 1 : endPlain]
2065 del document.body[i:j+1]
2066 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2067 document.body[parbeg : parbeg] = subst
2071 def revert_garamondx_newtxmath(document):
2072 " Revert native garamond newtxmath definition to LaTeX "
2074 i = find_token(document.header, "\\font_math", 0)
2077 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
2078 val = get_value(document.header, "\\font_math", i)
2079 if val == "garamondx-ntxm":
2080 add_to_preamble(document, "\\usepackage[garamondx]{newtxmath}")
2081 document.header[i] = "\\font_math auto"
2084 def revert_garamondx(document):
2085 " Revert native garamond font definition to LaTeX "
2087 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
2088 i = find_token(document.header, "\\font_roman garamondx", 0)
2091 j = find_token(document.header, "\\font_osf true", 0)
2094 preamble = "\\usepackage"
2096 preamble += "[osfI]"
2097 preamble += "{garamondx}"
2098 add_to_preamble(document, [preamble])
2099 document.header[i] = "\\font_roman default"
2102 def convert_beamerargs(document):
2103 " Converts beamer arguments to new layout "
2105 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2106 if document.textclass not in beamer_classes:
2109 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
2110 list_layouts = ["Itemize", "Enumerate", "Description"]
2111 rx = re.compile(r'^\\begin_inset Argument (\d+)$')
2115 i = find_token(document.body, "\\begin_inset Argument", i)
2118 # Find containing paragraph layout
2119 parent = get_containing_layout(document.body, i)
2121 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2126 layoutname = parent[0]
2127 for p in range(parbeg, parend):
2128 if layoutname in shifted_layouts:
2129 m = rx.match(document.body[p])
2131 argnr = int(m.group(1))
2133 document.body[p] = "\\begin_inset Argument %d" % argnr
2134 if layoutname == "AgainFrame":
2135 m = rx.match(document.body[p])
2137 document.body[p] = "\\begin_inset Argument 3"
2138 if document.body[p + 4] == "\\begin_inset ERT":
2139 if document.body[p + 9].startswith("<"):
2140 # This is an overlay specification
2142 document.body[p + 9] = document.body[p + 9][1:]
2143 if document.body[p + 9].endswith(">"):
2145 document.body[p + 9] = document.body[p + 9][:-1]
2147 document.body[p] = "\\begin_inset Argument 2"
2148 if layoutname in list_layouts:
2149 m = rx.match(document.body[p])
2151 if m.group(1) == "1":
2152 if document.body[p + 4] == "\\begin_inset ERT":
2153 if document.body[p + 9].startswith("<"):
2154 # This is an overlay specification
2156 document.body[p + 9] = document.body[p + 9][1:]
2157 if document.body[p + 9].endswith(">"):
2159 document.body[p + 9] = document.body[p + 9][:-1]
2160 elif layoutname != "Itemize":
2162 document.body[p] = "\\begin_inset Argument 2"
2166 def convert_againframe_args(document):
2167 " Converts beamer AgainFrame to new layout "
2169 # FIXME: This currently only works if the arguments are in one single ERT
2171 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2172 if document.textclass not in beamer_classes:
2177 i = find_token(document.body, "\\begin_layout AgainFrame", i)
2180 parent = get_containing_layout(document.body, i)
2182 document.warning("Wrong parent layout!")
2186 if document.body[parbeg] == "\\begin_inset ERT":
2187 ertcont = parbeg + 5
2188 if document.body[ertcont].startswith("[<"):
2189 # This is a default overlay specification
2191 document.body[ertcont] = document.body[ertcont][2:]
2192 if document.body[ertcont].endswith(">]"):
2194 document.body[ertcont] = document.body[ertcont][:-2]
2195 elif document.body[ertcont].endswith("]"):
2197 tok = document.body[ertcont].find('>][')
2199 subst = [document.body[ertcont][:tok],
2200 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2201 'status collapsed', '', '\\begin_layout Plain Layout',
2202 document.body[ertcont][tok + 3:-1]]
2203 document.body[ertcont : ertcont + 1] = subst
2204 # Convert to ArgInset
2205 document.body[parbeg] = "\\begin_inset Argument 2"
2208 elif document.body[ertcont].startswith("<"):
2209 # This is an overlay specification
2211 document.body[ertcont] = document.body[ertcont][1:]
2212 if document.body[ertcont].endswith(">"):
2214 document.body[ertcont] = document.body[ertcont][:-1]
2215 # Convert to ArgInset
2216 document.body[parbeg] = "\\begin_inset Argument 1"
2217 elif document.body[ertcont].endswith(">]"):
2219 tok = document.body[ertcont].find('>[<')
2221 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2222 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2223 'status collapsed', '', '\\begin_layout Plain Layout',
2224 document.body[ertcont][tok + 3:-2]]
2225 # Convert to ArgInset
2226 document.body[parbeg] = "\\begin_inset Argument 1"
2227 elif document.body[ertcont].endswith("]"):
2229 tok = document.body[ertcont].find('>[<')
2232 tokk = document.body[ertcont].find('>][')
2234 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2235 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2236 'status collapsed', '', '\\begin_layout Plain Layout',
2237 document.body[ertcont][tok + 3:tokk],
2238 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2239 'status collapsed', '', '\\begin_layout Plain Layout',
2240 document.body[ertcont][tokk + 3:-1]]
2242 tokk = document.body[ertcont].find('>[')
2244 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tokk],
2245 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2246 'status collapsed', '', '\\begin_layout Plain Layout',
2247 document.body[ertcont][tokk + 2:-1]]
2248 # Convert to ArgInset
2249 document.body[parbeg] = "\\begin_inset Argument 1"
2252 elif document.body[ertcont].startswith("["):
2253 # This is an ERT option
2255 document.body[ertcont] = document.body[ertcont][1:]
2256 if document.body[ertcont].endswith("]"):
2258 document.body[ertcont] = document.body[ertcont][:-1]
2259 # Convert to ArgInset
2260 document.body[parbeg] = "\\begin_inset Argument 3"
2266 def convert_corollary_args(document):
2267 " Converts beamer corrolary-style ERT arguments native InsetArgs "
2269 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2270 if document.textclass not in beamer_classes:
2273 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2274 for lay in corollary_layouts:
2277 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2280 parent = get_containing_layout(document.body, i)
2282 document.warning("Wrong parent layout!")
2286 if document.body[parbeg] == "\\begin_inset ERT":
2287 ertcont = parbeg + 5
2288 if document.body[ertcont].startswith("<"):
2289 # This is an overlay specification
2291 document.body[ertcont] = document.body[ertcont][1:]
2292 if document.body[ertcont].endswith(">"):
2294 document.body[ertcont] = document.body[ertcont][:-1]
2295 elif document.body[ertcont].endswith("]"):
2297 tok = document.body[ertcont].find('>[')
2299 subst = [document.body[ertcont][:tok],
2300 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2301 'status collapsed', '', '\\begin_layout Plain Layout',
2302 document.body[ertcont][tok + 2:-1]]
2303 document.body[ertcont : ertcont + 1] = subst
2304 # Convert to ArgInset
2305 document.body[parbeg] = "\\begin_inset Argument 1"
2308 elif document.body[ertcont].startswith("["):
2309 # This is an ERT option
2311 document.body[ertcont] = document.body[ertcont][1:]
2312 if document.body[ertcont].endswith("]"):
2314 document.body[ertcont] = document.body[ertcont][:-1]
2315 # Convert to ArgInset
2316 document.body[parbeg] = "\\begin_inset Argument 2"
2323 def convert_quote_args(document):
2324 " Converts beamer quote style ERT args to native InsetArgs "
2326 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2327 if document.textclass not in beamer_classes:
2330 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2331 for lay in quote_layouts:
2334 i = find_token(document.body, "\\begin_layout " + lay, i)
2337 parent = get_containing_layout(document.body, i)
2339 document.warning("Wrong parent layout!")
2343 if document.body[parbeg] == "\\begin_inset ERT":
2344 if document.body[i + 6].startswith("<"):
2345 # This is an overlay specification
2347 document.body[i + 6] = document.body[i + 6][1:]
2348 if document.body[i + 6].endswith(">"):
2350 document.body[i + 6] = document.body[i + 6][:-1]
2351 # Convert to ArgInset
2352 document.body[i + 1] = "\\begin_inset Argument 1"
2356 def revert_beamerargs(document):
2357 " Reverts beamer arguments to old layout "
2359 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2360 if document.textclass not in beamer_classes:
2364 list_layouts = ["Itemize", "Enumerate", "Description"]
2365 headings = ["Part", "Section", "Section*", "Subsection", "Subsection*",
2366 "Subsubsection", "Subsubsection*", "FrameSubtitle", "NoteItem"]
2367 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2368 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2369 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2372 i = find_token(document.body, "\\begin_inset Argument", i)
2375 # Find containing paragraph layout
2376 parent = get_containing_layout(document.body, i)
2378 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2383 realparbeg = parent[3]
2384 layoutname = parent[0]
2386 for p in range(parbeg, parend):
2390 if layoutname in headings:
2391 m = rx.match(document.body[p])
2395 # Find containing paragraph layout
2396 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2397 endPlain = find_end_of_layout(document.body, beginPlain)
2398 endInset = find_end_of_inset(document.body, p)
2399 argcontent = document.body[beginPlain + 1 : endPlain]
2401 realparend = realparend - len(document.body[p : endInset + 1])
2403 del document.body[p : endInset + 1]
2404 if layoutname == "FrameSubtitle":
2405 pre = put_cmd_in_ert("\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2406 elif layoutname == "NoteItem":
2407 pre = put_cmd_in_ert("\\note<") + argcontent + put_cmd_in_ert(">[item]")
2408 elif layoutname.endswith('*'):
2409 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower()[:-1] + "<") + argcontent + put_cmd_in_ert(">*")
2411 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2412 secarg = find_token(document.body, "\\begin_inset Argument 2", parbeg, parend)
2414 # Find containing paragraph layout
2415 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", secarg)
2416 endPlain = find_end_of_layout(document.body, beginPlain)
2417 endInset = find_end_of_inset(document.body, secarg)
2418 argcontent = document.body[beginPlain + 1 : endPlain]
2420 realparend = realparend - len(document.body[secarg : endInset + 1])
2421 del document.body[secarg : endInset + 1]
2422 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2423 pre += put_cmd_in_ert("{")
2424 document.body[parbeg] = "\\begin_layout Standard"
2425 document.body[realparbeg : realparbeg] = pre
2426 pe = find_end_of_layout(document.body, parbeg)
2427 post = put_cmd_in_ert("}")
2428 document.body[pe : pe] = post
2429 realparend += len(pre) + len(post)
2430 if layoutname == "AgainFrame":
2431 m = rx.match(document.body[p])
2435 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2436 endPlain = find_end_of_layout(document.body, beginPlain)
2437 endInset = find_end_of_inset(document.body, p)
2438 content = document.body[beginPlain + 1 : endPlain]
2440 realparend = realparend - len(document.body[p : endInset + 1])
2442 del document.body[p : endInset + 1]
2443 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2444 document.body[realparbeg : realparbeg] = subst
2445 if layoutname == "Overprint":
2446 m = rx.match(document.body[p])
2450 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2451 endPlain = find_end_of_layout(document.body, beginPlain)
2452 endInset = find_end_of_inset(document.body, p)
2453 content = document.body[beginPlain + 1 : endPlain]
2455 realparend = realparend - len(document.body[p : endInset + 1])
2457 del document.body[p : endInset + 1]
2458 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2459 document.body[realparbeg : realparbeg] = subst
2460 if layoutname == "OverlayArea":
2461 m = rx.match(document.body[p])
2465 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2466 endPlain = find_end_of_layout(document.body, beginPlain)
2467 endInset = find_end_of_inset(document.body, p)
2468 content = document.body[beginPlain + 1 : endPlain]
2470 realparend = realparend - len(document.body[p : endInset + 1])
2472 del document.body[p : endInset + 1]
2473 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2474 document.body[realparbeg : realparbeg] = subst
2475 if layoutname in list_layouts:
2476 m = rx.match(document.body[p])
2480 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2481 endPlain = find_end_of_layout(document.body, beginPlain)
2482 endInset = find_end_of_inset(document.body, p)
2483 content = document.body[beginPlain + 1 : endPlain]
2484 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2485 realparend = realparend + len(subst) - len(content)
2486 document.body[beginPlain + 1 : endPlain] = subst
2487 elif argnr == "item:1":
2488 j = find_end_of_inset(document.body, i)
2489 # Find containing paragraph layout
2490 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2491 endPlain = find_end_of_layout(document.body, beginPlain)
2492 content = document.body[beginPlain + 1 : endPlain]
2493 del document.body[i:j+1]
2494 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2495 document.body[realparbeg : realparbeg] = subst
2496 elif argnr == "item:2":
2497 j = find_end_of_inset(document.body, i)
2498 # Find containing paragraph layout
2499 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2500 endPlain = find_end_of_layout(document.body, beginPlain)
2501 content = document.body[beginPlain + 1 : endPlain]
2502 del document.body[i:j+1]
2503 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2504 document.body[realparbeg : realparbeg] = subst
2505 if layoutname in quote_layouts:
2506 m = rx.match(document.body[p])
2510 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2511 endPlain = find_end_of_layout(document.body, beginPlain)
2512 endInset = find_end_of_inset(document.body, p)
2513 content = document.body[beginPlain + 1 : endPlain]
2515 realparend = realparend - len(document.body[p : endInset + 1])
2517 del document.body[p : endInset + 1]
2518 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2519 document.body[realparbeg : realparbeg] = subst
2520 if layoutname in corollary_layouts:
2521 m = rx.match(document.body[p])
2525 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2526 endPlain = find_end_of_layout(document.body, beginPlain)
2527 endInset = find_end_of_inset(document.body, p)
2528 content = document.body[beginPlain + 1 : endPlain]
2530 realparend = realparend - len(document.body[p : endInset + 1])
2532 del document.body[p : endInset + 1]
2533 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2534 document.body[realparbeg : realparbeg] = subst
2539 def revert_beamerargs2(document):
2540 " Reverts beamer arguments to old layout, step 2 "
2542 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2543 if document.textclass not in beamer_classes:
2547 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
2548 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2549 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2552 i = find_token(document.body, "\\begin_inset Argument", i)
2555 # Find containing paragraph layout
2556 parent = get_containing_layout(document.body, i)
2558 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2563 realparbeg = parent[3]
2564 layoutname = parent[0]
2566 for p in range(parbeg, parend):
2570 if layoutname in shifted_layouts:
2571 m = rx.match(document.body[p])
2575 document.body[p] = "\\begin_inset Argument 1"
2576 if layoutname in corollary_layouts:
2577 m = rx.match(document.body[p])
2581 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2582 endPlain = find_end_of_layout(document.body, beginPlain)
2583 endInset = find_end_of_inset(document.body, p)
2584 content = document.body[beginPlain + 1 : endPlain]
2586 realparend = realparend - len(document.body[p : endInset + 1])
2588 del document.body[p : endInset + 1]
2589 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2590 document.body[realparbeg : realparbeg] = subst
2591 if layoutname == "OverlayArea":
2592 m = rx.match(document.body[p])
2596 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2597 endPlain = find_end_of_layout(document.body, beginPlain)
2598 endInset = find_end_of_inset(document.body, p)
2599 content = document.body[beginPlain + 1 : endPlain]
2601 realparend = realparend - len(document.body[p : endInset + 1])
2603 del document.body[p : endInset + 1]
2604 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2605 document.body[realparbeg : realparbeg] = subst
2606 if layoutname == "AgainFrame":
2607 m = rx.match(document.body[p])
2611 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2612 endPlain = find_end_of_layout(document.body, beginPlain)
2613 endInset = find_end_of_inset(document.body, p)
2614 content = document.body[beginPlain + 1 : endPlain]
2616 realparend = realparend - len(document.body[p : endInset + 1])
2618 del document.body[p : endInset + 1]
2619 subst = put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
2620 document.body[realparbeg : realparbeg] = subst
2624 def revert_beamerargs3(document):
2625 " Reverts beamer arguments to old layout, step 3 "
2627 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2628 if document.textclass not in beamer_classes:
2631 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2634 i = find_token(document.body, "\\begin_inset Argument", i)
2637 # Find containing paragraph layout
2638 parent = get_containing_layout(document.body, i)
2640 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2645 realparbeg = parent[3]
2646 layoutname = parent[0]
2648 for p in range(parbeg, parend):
2652 if layoutname == "AgainFrame":
2653 m = rx.match(document.body[p])
2657 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2658 endPlain = find_end_of_layout(document.body, beginPlain)
2659 endInset = find_end_of_inset(document.body, p)
2660 content = document.body[beginPlain + 1 : endPlain]
2662 realparend = realparend - len(document.body[p : endInset + 1])
2664 del document.body[p : endInset + 1]
2665 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2666 document.body[realparbeg : realparbeg] = subst
2670 def revert_beamerflex(document):
2671 " Reverts beamer Flex insets "
2673 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2674 if document.textclass not in beamer_classes:
2677 new_flexes = {"Bold" : "\\textbf", "Emphasize" : "\\emph", "Only" : "\\only",
2678 "Uncover" : "\\uncover", "Visible" : "\\visible",
2679 "Invisible" : "\\invisible", "Alternative" : "\\alt",
2680 "Beamer_Note" : "\\note"}
2681 old_flexes = {"Alert" : "\\alert", "Structure" : "\\structure"}
2682 rx = re.compile(r'^\\begin_inset Flex (.+)$')
2686 i = find_token(document.body, "\\begin_inset Flex", i)
2689 m = rx.match(document.body[i])
2691 flextype = m.group(1)
2692 z = find_end_of_inset(document.body, i)
2694 document.warning("Can't find end of Flex " + flextype + " inset.")
2697 if flextype in new_flexes:
2698 pre = put_cmd_in_ert(new_flexes[flextype])
2699 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2701 argend = find_end_of_inset(document.body, arg)
2703 document.warning("Can't find end of Argument!")
2706 # Find containing paragraph layout
2707 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2708 endPlain = find_end_of_layout(document.body, beginPlain)
2709 argcontent = document.body[beginPlain + 1 : endPlain]
2711 z = z - len(document.body[arg : argend + 1])
2713 del document.body[arg : argend + 1]
2714 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2715 arg = find_token(document.body, "\\begin_inset Argument 2", i, z)
2717 argend = find_end_of_inset(document.body, arg)
2719 document.warning("Can't find end of Argument!")
2722 # Find containing paragraph layout
2723 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2724 endPlain = find_end_of_layout(document.body, beginPlain)
2725 argcontent = document.body[beginPlain + 1 : endPlain]
2727 z = z - len(document.body[arg : argend + 1])
2729 del document.body[arg : argend + 1]
2730 if flextype == "Alternative":
2731 pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
2733 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2734 pre += put_cmd_in_ert("{")
2735 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2736 endPlain = find_end_of_layout(document.body, beginPlain)
2738 z = z - len(document.body[i : beginPlain + 1])
2740 document.body[i : beginPlain + 1] = pre
2741 post = put_cmd_in_ert("}")
2742 document.body[z - 2 : z + 1] = post
2743 elif flextype in old_flexes:
2744 pre = put_cmd_in_ert(old_flexes[flextype])
2745 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2749 argend = find_end_of_inset(document.body, arg)
2751 document.warning("Can't find end of Argument!")
2754 # Find containing paragraph layout
2755 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2756 endPlain = find_end_of_layout(document.body, beginPlain)
2757 argcontent = document.body[beginPlain + 1 : endPlain]
2759 z = z - len(document.body[arg : argend + 1])
2761 del document.body[arg : argend + 1]
2762 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2763 pre += put_cmd_in_ert("{")
2764 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2765 endPlain = find_end_of_layout(document.body, beginPlain)
2767 z = z - len(document.body[i : beginPlain + 1])
2769 document.body[i : beginPlain + 1] = pre
2770 post = put_cmd_in_ert("}")
2771 document.body[z - 2 : z + 1] = post
2776 def revert_beamerblocks(document):
2777 " Reverts beamer block arguments to ERT "
2779 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2780 if document.textclass not in beamer_classes:
2783 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2785 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2788 i = find_token(document.body, "\\begin_inset Argument", i)
2791 # Find containing paragraph layout
2792 parent = get_containing_layout(document.body, i)
2794 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2799 realparbeg = parent[3]
2800 layoutname = parent[0]
2802 for p in range(parbeg, parend):
2806 if layoutname in blocks:
2807 m = rx.match(document.body[p])
2811 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2812 endPlain = find_end_of_layout(document.body, beginPlain)
2813 endInset = find_end_of_inset(document.body, p)
2814 content = document.body[beginPlain + 1 : endPlain]
2816 realparend = realparend - len(document.body[p : endInset + 1])
2818 del document.body[p : endInset + 1]
2819 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2820 document.body[realparbeg : realparbeg] = subst
2822 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2823 endPlain = find_end_of_layout(document.body, beginPlain)
2824 endInset = find_end_of_inset(document.body, p)
2825 content = document.body[beginPlain + 1 : endPlain]
2827 realparend = realparend - len(document.body[p : endInset + 1])
2829 del document.body[p : endInset + 1]
2830 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2831 document.body[realparbeg : realparbeg] = subst
2836 def convert_beamerblocks(document):
2837 " Converts beamer block ERT args to native InsetArgs "
2839 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2840 if document.textclass not in beamer_classes:
2843 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2847 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2850 parent = get_containing_layout(document.body, i)
2851 if parent == False or parent[1] != i:
2852 document.warning("Wrong parent layout!")
2858 if document.body[parbeg] == "\\begin_inset ERT":
2859 ertcont = parbeg + 5
2861 if document.body[ertcont].startswith("<"):
2862 # This is an overlay specification
2864 document.body[ertcont] = document.body[ertcont][1:]
2865 if document.body[ertcont].endswith(">"):
2867 document.body[ertcont] = document.body[ertcont][:-1]
2868 # Convert to ArgInset
2869 document.body[parbeg] = "\\begin_inset Argument 1"
2870 elif document.body[ertcont].endswith("}"):
2872 tok = document.body[ertcont].find('>{')
2874 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2875 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2876 'status collapsed', '', '\\begin_layout Plain Layout',
2877 document.body[ertcont][tok + 2:-1]]
2878 # Convert to ArgInset
2879 document.body[parbeg] = "\\begin_inset Argument 1"
2880 elif document.body[ertcont].startswith("{"):
2881 # This is the block title
2882 if document.body[ertcont].endswith("}"):
2883 # strip off the braces
2884 document.body[ertcont] = document.body[ertcont][1:-1]
2885 # Convert to ArgInset
2886 document.body[parbeg] = "\\begin_inset Argument 2"
2887 elif count_pars_in_inset(document.body, ertcont) > 1:
2888 # Multipar ERT. Skip this.
2891 convert_TeX_brace_to_Argument(document, i, 2, 2, False, True)
2894 j = find_end_of_layout(document.body, i)
2896 document.warning("end of layout not found!")
2897 k = find_token(document.body, "\\begin_inset Argument", i, j)
2899 document.warning("InsetArgument not found!")
2901 l = find_end_of_inset(document.body, k)
2902 m = find_token(document.body, "\\begin_inset ERT", l, j)
2910 def convert_overprint(document):
2911 " Convert old beamer overprint layouts to ERT "
2913 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2914 if document.textclass not in beamer_classes:
2919 i = find_token(document.body, "\\begin_layout Overprint", i)
2922 # Find end of sequence
2923 j = find_end_of_sequence(document.body, i)
2925 document.warning("Malformed LyX document. Cannot find end of Overprint sequence!")
2929 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
2931 if document.body[j] == "\\end_deeper":
2932 esubst = ["", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
2934 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
2935 endseq = endseq + len(esubst) - len(document.body[j : j])
2936 document.body[j : j] = esubst
2937 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
2939 argend = find_end_of_layout(document.body, argbeg)
2941 document.warning("Malformed LyX document. Cannot find end of Overprint argument!")
2944 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
2945 endPlain = find_end_of_layout(document.body, beginPlain)
2946 content = document.body[beginPlain + 1 : endPlain]
2948 endseq = endseq - len(document.body[argbeg : argend + 1])
2950 del document.body[argbeg : argend + 1]
2951 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2953 endseq = endseq - len(document.body[i : i])
2954 document.body[i : i] = subst + ["\\end_layout"]
2955 endseq += len(subst)
2957 for p in range(i, endseq):
2958 if document.body[p] == "\\begin_layout Overprint":
2959 document.body[p] = "\\begin_layout Standard"
2964 def revert_overprint(document):
2965 " Revert old beamer overprint layouts to ERT "
2967 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2968 if document.textclass not in beamer_classes:
2973 i = find_token(document.body, "\\begin_layout Overprint", i)
2976 # Find end of sequence
2977 j = find_end_of_sequence(document.body, i)
2979 document.warning("Malformed LyX document. Cannot find end of Overprint sequence!")
2983 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
2984 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}")
2985 endseq = endseq + len(esubst) - len(document.body[j : j])
2986 if document.body[j] == "\\end_deeper":
2987 document.body[j : j] = ["\\end_deeper", ""] + esubst
2989 document.body[j : j] = esubst
2992 if document.body[r] == "\\begin_deeper":
2993 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
2995 document.body[r] = ""
2996 document.body[s] = ""
3000 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
3002 argend = find_end_of_inset(document.body, argbeg)
3004 document.warning("Malformed LyX document. Cannot find end of Overprint argument!")
3007 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3008 endPlain = find_end_of_layout(document.body, beginPlain)
3009 content = document.body[beginPlain + 1 : endPlain]
3011 endseq = endseq - len(document.body[argbeg : argend])
3013 del document.body[argbeg : argend + 1]
3014 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3016 endseq = endseq - len(document.body[i : i])
3017 document.body[i : i] = subst + ["\\end_layout"]
3018 endseq += len(subst)
3024 if document.body[p] == "\\begin_layout Overprint":
3025 q = find_end_of_layout(document.body, p)
3027 document.warning("Malformed LyX document. Cannot find end of Overprint layout!")
3030 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\onslide")
3031 argbeg = find_token(document.body, "\\begin_inset Argument item:1", p, q)
3033 argend = find_end_of_inset(document.body, argbeg)
3035 document.warning("Malformed LyX document. Cannot find end of Overprint item argument!")
3038 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3039 endPlain = find_end_of_layout(document.body, beginPlain)
3040 content = document.body[beginPlain + 1 : endPlain]
3042 endseq = endseq - len(document.body[argbeg : argend + 1])
3044 del document.body[argbeg : argend + 1]
3045 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3046 endseq = endseq - len(document.body[p : p + 1]) + len(subst)
3047 document.body[p : p + 1] = subst
3053 def revert_frametitle(document):
3054 " Reverts beamer frametitle layout to ERT "
3056 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3057 if document.textclass not in beamer_classes:
3060 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
3063 i = find_token(document.body, "\\begin_layout FrameTitle", i)
3066 j = find_end_of_layout(document.body, i)
3068 document.warning("Malformed LyX document: Can't find end of FrameTitle layout")
3072 document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
3073 endlay += len(put_cmd_in_ert("}"))
3074 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\frametitle")
3075 for p in range(i, j):
3078 m = rx.match(document.body[p])
3082 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3083 endPlain = find_end_of_layout(document.body, beginPlain)
3084 endInset = find_end_of_inset(document.body, p)
3085 content = document.body[beginPlain + 1 : endPlain]
3087 endlay = endlay - len(document.body[p : endInset + 1])
3089 del document.body[p : endInset + 1]
3090 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3092 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3093 endPlain = find_end_of_layout(document.body, beginPlain)
3094 endInset = find_end_of_inset(document.body, p)
3095 content = document.body[beginPlain + 1 : endPlain]
3097 endlay = endlay - len(document.body[p : endInset + 1])
3099 del document.body[p : endInset + 1]
3100 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3102 subst += put_cmd_in_ert("{")
3103 document.body[i : i + 1] = subst
3107 def convert_epigraph(document):
3108 " Converts memoir epigraph to new syntax "
3110 if document.textclass != "memoir":
3115 i = find_token(document.body, "\\begin_layout Epigraph", i)
3118 j = find_end_of_layout(document.body, i)
3120 document.warning("Malformed LyX document: Can't find end of Epigraph layout")
3125 ert = find_token(document.body, "\\begin_inset ERT", i, j)
3127 endInset = find_end_of_inset(document.body, ert)
3128 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", ert)
3129 endPlain = find_end_of_layout(document.body, beginPlain)
3130 ertcont = beginPlain + 2
3131 if document.body[ertcont] == "}{":
3133 # Convert to ArgInset
3134 endlay = endlay - 2 * len(document.body[j])
3135 begsubst = ['\\begin_inset Argument post:1', 'status collapsed', '',
3136 '\\begin_layout Plain Layout']
3137 endsubst = ['\\end_layout', '', '\\end_inset', '', document.body[j]]
3138 document.body[j : j + 1] = endsubst
3139 document.body[endInset + 1 : endInset + 1] = begsubst
3141 endlay += len(begsubst) + len(endsubst)
3142 endlay = endlay - len(document.body[ert : endInset + 1])
3143 del document.body[ert : endInset + 1]
3148 def revert_epigraph(document):
3149 " Reverts memoir epigraph argument to ERT "
3151 if document.textclass != "memoir":
3156 i = find_token(document.body, "\\begin_layout Epigraph", i)
3159 j = find_end_of_layout(document.body, i)
3161 document.warning("Malformed LyX document: Can't find end of Epigraph layout")
3166 p = find_token(document.body, "\\begin_layout Argument post:1", i, j)
3168 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3169 endPlain = find_end_of_layout(document.body, beginPlain)
3170 endInset = find_end_of_inset(document.body, p)
3171 content = document.body[beginPlain + 1 : endPlain]
3173 endlay = endlay - len(document.body[p : endInset + 1])
3175 del document.body[p : endInset + 1]
3176 subst += put_cmd_in_ert("}{") + content
3178 subst += put_cmd_in_ert("}{")
3180 document.body[j : j] = subst + document.body[j : j]
3184 def convert_captioninsets(document):
3185 " Converts caption insets to new syntax "
3189 i = find_token(document.body, "\\begin_inset Caption", i)
3192 document.body[i] = "\\begin_inset Caption Standard"
3196 def revert_captioninsets(document):
3197 " Reverts caption insets to old syntax "
3201 i = find_token(document.body, "\\begin_inset Caption Standard", i)
3204 document.body[i] = "\\begin_inset Caption"
3208 def convert_captionlayouts(document):
3209 " Convert caption layouts to caption insets. "
3212 "Captionabove": "Above",
3213 "Captionbelow": "Below",
3214 "FigCaption" : "FigCaption",
3215 "Table_Caption" : "Table",
3216 "CenteredCaption" : "Centered",
3217 "Bicaption" : "Bicaption",
3222 i = find_token(document.body, "\\begin_layout", i)
3225 val = get_value(document.body, "\\begin_layout", i)
3226 if val in caption_dict.keys():
3227 j = find_end_of_layout(document.body, i)
3229 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3232 document.body[j:j] = ["\\end_layout", "", "\\end_inset", "", ""]
3233 document.body[i:i+1] = ["\\begin_layout %s" % document.default_layout,
3234 "\\begin_inset Caption %s" % caption_dict[val], "",
3235 "\\begin_layout %s" % document.default_layout]
3239 def revert_captionlayouts(document):
3240 " Revert caption insets to caption layouts. "
3243 "Above" : "Captionabove",
3244 "Below" : "Captionbelow",
3245 "FigCaption" : "FigCaption",
3246 "Table" : "Table_Caption",
3247 "Centered" : "CenteredCaption",
3248 "Bicaption" : "Bicaption",
3252 rx = re.compile(r'^\\begin_inset Caption (\S+)$')
3254 i = find_token(document.body, "\\begin_inset Caption", i)
3258 m = rx.match(document.body[i])
3262 if val not in caption_dict.keys():
3266 # We either need to delete the previous \begin_layout line, or we
3267 # need to end the previous layout if this inset is not in the first
3268 # position of the paragraph.
3269 layout_before = find_token_backwards(document.body, "\\begin_layout", i)
3270 if layout_before == -1:
3271 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3273 layout_line = document.body[layout_before]
3274 del_layout_before = True
3275 l = layout_before + 1
3277 if document.body[l] != "":
3278 del_layout_before = False
3281 if del_layout_before:
3282 del document.body[layout_before:i]
3285 document.body[i:i] = ["\\end_layout", ""]
3288 # Find start of layout in the inset and end of inset
3289 j = find_token(document.body, "\\begin_layout", i)
3291 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3293 k = find_end_of_inset(document.body, i)
3295 document.warning("Malformed LyX document: Missing `\\end_inset'.")
3298 # We either need to delete the following \end_layout line, or we need
3299 # to restart the old layout if this inset is not at the paragraph end.
3300 layout_after = find_token(document.body, "\\end_layout", k)
3301 if layout_after == -1:
3302 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3304 del_layout_after = True
3306 while l < layout_after:
3307 if document.body[l] != "":
3308 del_layout_after = False
3311 if del_layout_after:
3312 del document.body[k+1:layout_after+1]
3314 document.body[k+1:k+1] = [layout_line, ""]
3316 # delete \begin_layout and \end_inset and replace \begin_inset with
3317 # "\begin_layout XXX". This works because we can only have one
3318 # paragraph in the caption inset: The old \end_layout will be recycled.
3319 del document.body[k]
3320 if document.body[k] == "":
3321 del document.body[k]
3322 del document.body[j]
3323 if document.body[j] == "":
3324 del document.body[j]
3325 document.body[i] = "\\begin_layout %s" % caption_dict[val]
3326 if document.body[i+1] == "":
3327 del document.body[i+1]
3331 def revert_fragileframe(document):
3332 " Reverts beamer FragileFrame layout to ERT "
3334 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3335 if document.textclass not in beamer_classes:
3340 i = find_token(document.body, "\\begin_layout FragileFrame", i)
3343 # Find end of sequence
3344 j = find_end_of_sequence(document.body, i)
3346 document.warning("Malformed LyX document. Cannot find end of FragileFrame sequence!")
3350 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{frame}")
3351 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{frame}")
3352 endseq = endseq + len(esubst) - len(document.body[j : j])
3353 if document.body[j] == "\\end_deeper":
3354 document.body[j : j] = ["\\end_deeper", ""] + esubst
3356 document.body[j : j] = esubst
3357 for q in range(i, j):
3358 if document.body[q] == "\\begin_layout FragileFrame":
3359 document.body[q] = "\\begin_layout %s" % document.default_layout
3362 if document.body[r] == "\\begin_deeper":
3363 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3365 document.body[r] = ""
3366 document.body[s] = ""
3370 for p in range(1, 5):
3371 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, j)
3374 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3375 endPlain = find_end_of_layout(document.body, beginPlain)
3376 endInset = find_end_of_inset(document.body, arg)
3377 content = document.body[beginPlain + 1 : endPlain]
3379 j = j - len(document.body[arg : endInset + 1])
3381 del document.body[arg : endInset + 1]
3382 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3384 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3385 endPlain = find_end_of_layout(document.body, beginPlain)
3386 endInset = find_end_of_inset(document.body, arg)
3387 content = document.body[beginPlain + 1 : endPlain]
3389 j = j - len(document.body[arg : endInset + 1])
3391 del document.body[arg : endInset + 1]
3392 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3394 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3395 endPlain = find_end_of_layout(document.body, beginPlain)
3396 endInset = find_end_of_inset(document.body, arg)
3397 content = document.body[beginPlain + 1 : endPlain]
3399 j = j - len(document.body[arg : endInset + 1])
3401 del document.body[arg : endInset + 1]
3402 subst += put_cmd_in_ert("[fragile,") + content + put_cmd_in_ert("]")
3404 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3405 endPlain = find_end_of_layout(document.body, beginPlain)
3406 endInset = find_end_of_inset(document.body, arg)
3407 content = document.body[beginPlain + 1 : endPlain]
3409 j = j - len(document.body[arg : endInset + 1])
3411 del document.body[arg : endInset + 1]
3412 subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
3414 subst += put_cmd_in_ert("[fragile]")
3416 document.body[i : i + 1] = subst
3420 def revert_newframes(document):
3421 " Reverts beamer Frame and PlainFrame layouts to old forms "
3423 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3424 if document.textclass not in beamer_classes:
3428 "Frame" : "BeginFrame",
3429 "PlainFrame" : "BeginPlainFrame",
3432 rx = re.compile(r'^\\begin_layout (\S+)$')
3435 i = find_token(document.body, "\\begin_layout", i)
3439 m = rx.match(document.body[i])
3443 if val not in frame_dict.keys():
3446 # Find end of sequence
3447 j = find_end_of_sequence(document.body, i)
3449 document.warning("Malformed LyX document. Cannot find end of Frame sequence!")
3453 subst = ["\\begin_layout %s" % frame_dict[val]]
3454 esubst = ["\\end_layout", "", "\\begin_layout EndFrame", "", "\\end_layout"]
3455 endseq = endseq + len(esubst) - len(document.body[j : j])
3456 if document.body[j] == "\\end_deeper":
3457 document.body[j : j] = ["\\end_deeper", ""] + esubst
3459 document.body[j : j] = esubst
3460 for q in range(i, j):
3461 if document.body[q] == "\\begin_layout %s" % val:
3462 document.body[q] = "\\begin_layout %s" % document.default_layout
3465 if document.body[r] == "\\begin_deeper":
3466 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3468 document.body[r] = ""
3469 document.body[s] = ""
3473 l = find_end_of_layout(document.body, i)
3474 for p in range(1, 5):
3475 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, l)
3478 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3479 endPlain = find_end_of_layout(document.body, beginPlain)
3480 endInset = find_end_of_inset(document.body, arg)
3481 content = document.body[beginPlain + 1 : endPlain]
3483 l = l - len(document.body[arg : endInset + 1])
3485 del document.body[arg : endInset + 1]
3486 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3488 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3489 endPlain = find_end_of_layout(document.body, beginPlain)
3490 endInset = find_end_of_inset(document.body, arg)
3491 content = document.body[beginPlain + 1 : endPlain]
3493 l = l - len(document.body[arg : endInset + 1])
3495 del document.body[arg : endInset + 1]
3496 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3498 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3499 endPlain = find_end_of_layout(document.body, beginPlain)
3500 endInset = find_end_of_inset(document.body, arg)
3501 content = document.body[beginPlain + 1 : endPlain]
3503 l = l - len(document.body[arg : endInset + 1])
3505 del document.body[arg : endInset + 1]
3506 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3508 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3509 endPlain = find_end_of_layout(document.body, beginPlain)
3510 endInset = find_end_of_inset(document.body, arg)
3511 content = document.body[beginPlain + 1 : endPlain]
3513 l = l - len(document.body[arg : endInset + 1])
3515 del document.body[arg : endInset + 1]
3518 document.body[i : i + 1] = subst
3521 # known encodings that do not change their names (same LyX and LaTeX names)
3522 known_enc_tuple = ("auto", "default", "ansinew", "applemac", "armscii8", "ascii",
3523 "cp437", "cp437de", "cp850", "cp852", "cp855", "cp858", "cp862", "cp865", "cp866",
3524 "cp1250", "cp1251", "cp1252", "cp1255", "cp1256", "cp1257", "koi8-r", "koi8-u",
3525 "pt154", "pt254", "tis620-0", "utf8", "utf8x", "utf8-plain")
3527 def convert_encodings(document):
3528 "Use the LyX names of the encodings instead of the LaTeX names."
3529 LaTeX2LyX_enc_dict = {
3530 "8859-6": "iso8859-6",
3531 "8859-8": "iso8859-8",
3533 "euc": "euc-jp-platex",
3538 "iso88595": "iso8859-5",
3539 "iso-8859-7": "iso8859-7",
3541 "jis": "jis-platex",
3543 "l7xenc": "iso8859-13",
3544 "latin1": "iso8859-1",
3545 "latin2": "iso8859-2",
3546 "latin3": "iso8859-3",
3547 "latin4": "iso8859-4",
3548 "latin5": "iso8859-9",
3549 "latin9": "iso8859-15",
3550 "latin10": "iso8859-16",
3551 "SJIS": "shift-jis",
3552 "sjis": "shift-jis-platex",
3555 i = find_token(document.header, "\\inputencoding" , 0)
3558 val = get_value(document.header, "\\inputencoding", i)
3559 if val in LaTeX2LyX_enc_dict.keys():
3560 document.header[i] = "\\inputencoding %s" % LaTeX2LyX_enc_dict[val]
3561 elif val not in known_enc_tuple:
3562 document.warning("Ignoring unknown input encoding: `%s'" % val)
3565 def revert_encodings(document):
3566 """Revert to using the LaTeX names of the encodings instead of the LyX names.
3567 Also revert utf8-platex to sjis, the language default when using Japanese.
3569 LyX2LaTeX_enc_dict = {
3574 "euc-jp-platex": "euc",
3577 "iso8859-1": "latin1",
3578 "iso8859-2": "latin2",
3579 "iso8859-3": "latin3",
3580 "iso8859-4": "latin4",
3581 "iso8859-5": "iso88595",
3582 "iso8859-6": "8859-6",
3583 "iso8859-7": "iso-8859-7",
3584 "iso8859-8": "8859-8",
3585 "iso8859-9": "latin5",
3586 "iso8859-13": "l7xenc",
3587 "iso8859-15": "latin9",
3588 "iso8859-16": "latin10",
3590 "jis-platex": "jis",
3591 "shift-jis": "SJIS",
3592 "shift-jis-platex": "sjis",
3594 "utf8-platex": "sjis"
3596 i = find_token(document.header, "\\inputencoding" , 0)
3599 val = get_value(document.header, "\\inputencoding", i)
3600 if val in LyX2LaTeX_enc_dict.keys():
3601 document.header[i] = "\\inputencoding %s" % LyX2LaTeX_enc_dict[val]
3602 elif val not in known_enc_tuple:
3603 document.warning("Ignoring unknown input encoding: `%s'" % val)
3606 def revert_IEEEtran_3(document):
3608 Reverts Flex Insets to TeX-code
3610 if document.textclass == "IEEEtran":
3616 h = find_token(document.body, "\\begin_inset Flex Author Mark", h)
3618 endh = find_end_of_inset(document.body, h)
3619 document.body[endh - 2 : endh + 1] = put_cmd_in_ert("}")
3620 document.body[h : h + 4] = put_cmd_in_ert("\\IEEEauthorrefmark{")
3623 i = find_token(document.body, "\\begin_inset Flex Author Name", i)
3625 endi = find_end_of_inset(document.body, i)
3626 document.body[endi - 2 : endi + 1] = put_cmd_in_ert("}")
3627 document.body[i : i + 4] = put_cmd_in_ert("\\IEEEauthorblockN{")
3630 j = find_token(document.body, "\\begin_inset Flex Author Affiliation", j)
3632 endj = find_end_of_inset(document.body, j)
3633 document.body[endj - 2 : endj + 1] = put_cmd_in_ert("}")
3634 document.body[j : j + 4] = put_cmd_in_ert("\\IEEEauthorblockA{")
3636 if i == -1 and j == -1 and h == -1:
3640 def revert_kurier_fonts(document):
3641 " Revert kurier font definition to LaTeX "
3643 i = find_token(document.header, "\\font_math", 0)
3645 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3646 val = get_value(document.header, "\\font_math", i)
3647 if val == "kurier-math":
3648 add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
3649 "\\usepackage[math]{kurier}\n" \
3650 "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
3651 document.header[i] = "\\font_math auto"
3653 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3654 kurier_fonts = ["kurier", "kurierc", "kurierl", "kurierlc"]
3655 k = find_token(document.header, "\\font_sans kurier", 0)
3657 sf = get_value(document.header, "\\font_sans", k)
3658 if sf in kurier_fonts:
3659 add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
3660 document.header[k] = "\\font_sans default"
3662 def revert_iwona_fonts(document):
3663 " Revert iwona font definition to LaTeX "
3665 i = find_token(document.header, "\\font_math", 0)
3667 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3668 val = get_value(document.header, "\\font_math", i)
3669 if val == "iwona-math":
3670 add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
3671 "\\usepackage[math]{iwona}\n" \
3672 "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
3673 document.header[i] = "\\font_math auto"
3675 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3676 iwona_fonts = ["iwona", "iwonac", "iwonal", "iwonalc"]
3677 k = find_token(document.header, "\\font_sans iwona", 0)
3679 sf = get_value(document.header, "\\font_sans", k)
3680 if sf in iwona_fonts:
3681 add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
3682 document.header[k] = "\\font_sans default"
3685 def revert_new_libertines(document):
3686 " Revert new libertine font definition to LaTeX "
3688 if find_token(document.header, "\\use_non_tex_fonts true", 0) != -1:
3691 i = find_token(document.header, "\\font_typewriter libertine-mono", 0)
3693 preamble = "\\usepackage"
3694 sc = find_token(document.header, "\\font_tt_scale", 0)
3696 scval = get_value(document.header, "\\font_tt_scale", sc)
3698 preamble += "[scale=%f]" % (float(scval) / 100)
3699 document.header[sc] = "\\font_tt_scale 100"
3700 preamble += "{libertineMono-type1}"
3701 add_to_preamble(document, [preamble])
3702 document.header[i] = "\\font_typewriter default"
3704 k = find_token(document.header, "\\font_sans biolinum", 0)
3706 preamble = "\\usepackage"
3708 j = find_token(document.header, "\\font_osf true", 0)
3713 sc = find_token(document.header, "\\font_sf_scale", 0)
3715 scval = get_value(document.header, "\\font_sf_scale", sc)
3717 options += ",scale=%f" % (float(scval) / 100)
3718 document.header[sc] = "\\font_sf_scale 100"
3720 preamble += "[" + options +"]"
3721 preamble += "{biolinum-type1}"
3722 add_to_preamble(document, [preamble])
3723 document.header[k] = "\\font_sans default"
3726 def convert_lyxframes(document):
3727 " Converts old beamer frames to new style "
3729 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3730 if document.textclass not in beamer_classes:
3733 framebeg = ["BeginFrame", "BeginPlainFrame"]
3734 frameend = ["Frame", "PlainFrame", "EndFrame", "BeginFrame", "BeginPlainFrame", "AgainFrame",
3735 "Section", "Section*", "Subsection", "Subsection*", "Subsubsection", "Subsubsection*"]
3736 for lay in framebeg:
3739 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
3742 parent = get_containing_layout(document.body, i)
3743 if parent == False or parent[1] != i:
3744 document.warning("Wrong parent layout!")
3747 frametype = parent[0]
3751 # Step I: Convert ERT arguments
3752 # FIXME: This currently only works if the arguments are in one single ERT
3754 if document.body[parbeg] == "\\begin_inset ERT":
3755 ertend = find_end_of_inset(document.body, parbeg)
3757 document.warning("Malformed LyX document: missing ERT \\end_inset")
3759 ertcont = parbeg + 5
3760 if document.body[ertcont].startswith("[<"):
3761 # This is a default overlay specification
3763 document.body[ertcont] = document.body[ertcont][2:]
3764 if document.body[ertcont].endswith(">]"):
3766 document.body[ertcont] = document.body[ertcont][:-2]
3767 elif document.body[ertcont].endswith("]"):
3769 tok = document.body[ertcont].find('>][')
3771 subst = [document.body[ertcont][:tok],
3772 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
3773 'status collapsed', '', '\\begin_layout Plain Layout',
3774 document.body[ertcont][tok + 3:-1]]
3775 document.body[ertcont : ertcont + 1] = subst
3777 # Convert to ArgInset
3778 document.body[parbeg] = "\\begin_inset Argument 2"
3779 elif document.body[ertcont].startswith("<"):
3780 # This is an overlay specification
3782 document.body[ertcont] = document.body[ertcont][1:]
3783 if document.body[ertcont].endswith(">"):
3785 document.body[ertcont] = document.body[ertcont][:-1]
3786 # Convert to ArgInset
3787 document.body[parbeg] = "\\begin_inset Argument 1"
3788 elif document.body[ertcont].endswith(">]"):
3790 tok = document.body[ertcont].find('>[<')
3792 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
3793 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
3794 'status collapsed', '', '\\begin_layout Plain Layout',
3795 document.body[ertcont][tok + 3:-2]]
3796 # Convert to ArgInset
3797 document.body[parbeg] = "\\begin_inset Argument 1"
3799 elif document.body[ertcont].endswith("]"):
3801 tok = document.body[ertcont].find('>[<')
3804 tokk = document.body[ertcont].find('>][')
3806 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
3807 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
3808 'status collapsed', '', '\\begin_layout Plain Layout',
3809 document.body[ertcont][tok + 3:tokk],
3810 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
3811 'status collapsed', '', '\\begin_layout Plain Layout',
3812 document.body[ertcont][tokk + 3:-1]]
3815 tokk = document.body[ertcont].find('>[')
3817 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tokk],
3818 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
3819 'status collapsed', '', '\\begin_layout Plain Layout',
3820 document.body[ertcont][tokk + 2:-1]]
3822 # Convert to ArgInset
3823 document.body[parbeg] = "\\begin_inset Argument 1"
3824 elif document.body[ertcont].startswith("["):
3825 # This is an ERT option
3827 document.body[ertcont] = document.body[ertcont][1:]
3828 if document.body[ertcont].endswith("]"):
3830 document.body[ertcont] = document.body[ertcont][:-1]
3831 # Convert to ArgInset
3832 document.body[parbeg] = "\\begin_inset Argument 3"
3833 # End of argument conversion
3834 # Step II: Now rename the layout and convert the title to an argument
3835 j = find_end_of_layout(document.body, i)
3836 document.body[j : j + 1] = ['\\end_layout', '', '\\end_inset', '', '\\end_layout']
3837 if lay == "BeginFrame":
3838 document.body[i] = "\\begin_layout Frame"
3840 document.body[i] = "\\begin_layout PlainFrame"
3841 document.body[ertend + 1 : ertend + 1] = ['\\begin_inset Argument 4',
3842 'status open', '', '\\begin_layout Plain Layout']
3843 # Step III: find real frame end
3847 fend = find_token(document.body, "\\begin_layout", jj)
3849 document.warning("Malformed LyX document: No real frame end!")
3851 val = get_value(document.body, "\\begin_layout", fend)
3852 if val not in frameend:
3855 old = document.body[fend]
3856 if val == frametype:
3857 document.body[fend : fend] = ['\\end_deeper', '', '\\begin_layout Separator', '', '\\end_layout']
3859 document.body[fend : fend] = ['\\end_deeper']
3860 document.body[j + 1 : j + 1] = ['', '\\begin_deeper']
3865 def remove_endframes(document):
3866 " Remove deprecated beamer endframes "
3868 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3869 if document.textclass not in beamer_classes:
3874 i = find_token_exact(document.body, "\\begin_layout EndFrame", i)
3877 j = find_end_of_layout(document.body, i)
3879 document.warning("Malformed LyX document: Missing \\end_layout to EndFrame")
3882 del document.body[i : j + 1]
3885 def revert_powerdot_flexes(document):
3886 " Reverts powerdot flex insets "
3888 if document.textclass != "powerdot":
3891 flexes = {"Onslide" : "\\onslide",
3892 "Onslide*" : "\\onslide*",
3893 "Onslide+" : "\\onslide+"}
3894 rx = re.compile(r'^\\begin_inset Flex (.+)$')
3898 i = find_token(document.body, "\\begin_inset Flex", i)
3901 m = rx.match(document.body[i])
3903 flextype = m.group(1)
3904 z = find_end_of_inset(document.body, i)
3906 document.warning("Can't find end of Flex " + flextype + " inset.")
3909 if flextype in flexes:
3910 pre = put_cmd_in_ert(flexes[flextype])
3911 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
3913 argend = find_end_of_inset(document.body, arg)
3915 document.warning("Can't find end of Argument!")
3918 # Find containing paragraph layout
3919 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3920 endPlain = find_end_of_layout(document.body, beginPlain)
3921 argcontent = document.body[beginPlain + 1 : endPlain]
3923 z = z - len(document.body[arg : argend + 1])
3925 del document.body[arg : argend + 1]
3926 pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
3927 pre += put_cmd_in_ert("{")
3928 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
3929 endPlain = find_end_of_layout(document.body, beginPlain)
3931 z = z - len(document.body[i : beginPlain + 1])
3933 document.body[i : beginPlain + 1] = pre
3934 post = put_cmd_in_ert("}")
3935 document.body[z - 2 : z + 1] = post
3939 def revert_powerdot_pause(document):
3940 " Reverts powerdot pause layout to ERT "
3942 if document.textclass != "powerdot":
3947 i = find_token(document.body, "\\begin_layout Pause", i)
3950 j = find_end_of_layout(document.body, i)
3952 document.warning("Malformed LyX document: Can't find end of Pause layout")
3956 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\pause")
3957 for p in range(i, j):
3960 arg = find_token(document.body, "\\begin_inset Argument 1", i, j)
3962 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3963 endPlain = find_end_of_layout(document.body, beginPlain)
3964 endInset = find_end_of_inset(document.body, p)
3965 content = document.body[beginPlain + 1 : endPlain]
3967 endlay = endlay - len(document.body[p : endInset + 1])
3969 del document.body[p : endInset + 1]
3970 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3972 document.body[i : i + 1] = subst
3976 def revert_powerdot_itemargs(document):
3977 " Reverts powerdot item arguments to ERT "
3979 if document.textclass != "powerdot":
3983 list_layouts = ["Itemize", "ItemizeType1", "Enumerate", "EnumerateType1"]
3984 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
3987 i = find_token(document.body, "\\begin_inset Argument", i)
3990 # Find containing paragraph layout
3991 parent = get_containing_layout(document.body, i)
3993 document.warning("Malformed LyX document: Can't find parent paragraph layout")
3998 realparbeg = parent[3]
3999 layoutname = parent[0]
4001 for p in range(parbeg, parend):
4005 if layoutname in list_layouts:
4006 m = rx.match(document.body[p])
4009 if argnr == "item:1":
4010 j = find_end_of_inset(document.body, i)
4011 # Find containing paragraph layout
4012 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
4013 endPlain = find_end_of_layout(document.body, beginPlain)
4014 content = document.body[beginPlain + 1 : endPlain]
4015 del document.body[i:j+1]
4016 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
4017 document.body[realparbeg : realparbeg] = subst
4018 elif argnr == "item:2":
4019 j = find_end_of_inset(document.body, i)
4020 # Find containing paragraph layout
4021 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
4022 endPlain = find_end_of_layout(document.body, beginPlain)
4023 content = document.body[beginPlain + 1 : endPlain]
4024 del document.body[i:j+1]
4025 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
4026 document.body[realparbeg : realparbeg] = subst
4031 def revert_powerdot_columns(document):
4032 " Reverts powerdot twocolumn to TeX-code "
4033 if document.textclass != "powerdot":
4036 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
4039 i = find_token(document.body, "\\begin_layout Twocolumn", i)
4042 j = find_end_of_layout(document.body, i)
4044 document.warning("Malformed LyX document: Can't find end of Twocolumn layout")
4048 document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
4049 endlay += len(put_cmd_in_ert("}"))
4050 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\twocolumn")
4051 for p in range(i, j):
4054 m = rx.match(document.body[p])
4058 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
4059 endPlain = find_end_of_layout(document.body, beginPlain)
4060 endInset = find_end_of_inset(document.body, p)
4061 content = document.body[beginPlain + 1 : endPlain]
4063 endlay = endlay - len(document.body[p : endInset + 1])
4065 del document.body[p : endInset + 1]
4066 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
4068 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
4069 endPlain = find_end_of_layout(document.body, beginPlain)
4070 endInset = find_end_of_inset(document.body, p)
4071 content = document.body[beginPlain + 1 : endPlain]
4073 endlay = endlay - len(document.body[p : endInset + 1])
4075 del document.body[p : endInset + 1]
4076 subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
4078 subst += put_cmd_in_ert("{")
4079 document.body[i : i + 1] = subst
4083 def revert_mbox_fbox(document):
4084 'Convert revert mbox/fbox boxes to TeX-code'
4087 i = find_token(document.body, "\\begin_inset Box", i)
4090 j = find_token(document.body, "width", i)
4092 document.warning("Malformed LyX document: Can't find box width")
4094 width = get_value(document.body, "width", j)
4095 k = find_end_of_inset(document.body, j)
4097 document.warning("Malformed LyX document: Can't find end of box inset")
4100 BeginLayout = find_token(document.body, "\\begin_layout Plain Layout", j)
4101 EndLayout = find_token(document.body, "\\end_layout", BeginLayout)
4102 # replace if width is ""
4104 document.body[EndLayout:k + 1] = put_cmd_in_ert("}")
4105 if document.body[i] == "\\begin_inset Box Frameless":
4106 document.body[i:BeginLayout + 1] = put_cmd_in_ert("\\mbox{")
4107 if document.body[i] == "\\begin_inset Box Boxed":
4108 document.body[i:BeginLayout + 1] = put_cmd_in_ert("\\fbox{")
4112 def revert_starred_caption(document):
4113 " Reverts unnumbered longtable caption insets "
4117 i = find_token(document.body, "\\begin_inset Caption LongTableNoNumber", i)
4120 # This is not equivalent, but since the caption inset is a full blown
4121 # text inset a true conversion to ERT is too difficult.
4122 document.body[i] = "\\begin_inset Caption Standard"
4126 def revert_forced_local_layout(document):
4129 i = find_token(document.header, "\\begin_forced_local_layout", i)
4132 j = find_end_of(document.header, i, "\\begin_forced_local_layout", "\\end_forced_local_layout")
4134 # this should not happen
4136 regexp = re.compile(r'\s*forcelocal', re.IGNORECASE)
4137 k = find_re(document.header, regexp, i, j)
4139 del document.header[k]
4141 k = find_re(document.header, regexp, i, j)
4142 k = find_token(document.header, "\\begin_local_layout", 0)
4144 document.header[i] = "\\begin_local_layout"
4145 document.header[j] = "\\end_local_layout"
4147 l = find_end_of(document.header, k, "\\begin_local_layout", "\\end_local_layout")
4149 # this should not happen
4151 lines = document.header[i+1 : j]
4153 document.header[k+1 : k+1] = lines
4154 document.header[i : j ] = []
4156 document.header[i : j ] = []
4157 document.header[k+1 : k+1] = lines
4160 def revert_aa1(document):
4161 " Reverts InsetArguments of aa to TeX-code "
4162 if document.textclass == "aa":
4166 i = find_token(document.body, "\\begin_layout Abstract (structured)", i)
4168 revert_Argument_to_TeX_brace(document, i, 0, 1, 4, False, False)
4174 def revert_aa2(document):
4175 " Reverts InsetArguments of aa to TeX-code "
4176 if document.textclass == "aa":
4180 i = find_token(document.body, "\\begin_layout Abstract (structured)", i)
4182 document.body[i] = "\\begin_layout Abstract"
4188 def revert_tibetan(document):
4189 "Set the document language for Tibetan to English"
4191 if document.language == "tibetan":
4192 document.language = "english"
4193 i = find_token(document.header, "\\language", 0)
4195 document.header[i] = "\\language english"
4197 while j < len(document.body):
4198 j = find_token(document.body, "\\lang tibetan", j)
4200 document.body[j] = document.body[j].replace("\\lang tibetan", "\\lang english")
4203 j = len(document.body)
4212 # the idea here is that we will have a sequence of chunk paragraphs
4213 # we want to convert them to paragraphs in a chunk inset
4214 # the last will be discarded
4215 # the first should look like: <<FROGS>>=
4216 # will will discard the delimiters, and put the contents into the
4217 # optional argument of the inset
4218 def convert_chunks(document):
4219 first_re = re.compile(r'<<(.*)>>=')
4222 # the beginning of this sequence
4224 # find start of a block of chunks
4225 i = find_token(document.body, "\\begin_layout Chunk", i)
4233 # process the one we just found
4234 j = find_end_of_layout(document.body, i)
4236 document.warning("Malformed LyX documents. Can't find end of Chunk layout!")
4238 thischunk = "".join(document.body[i + 1:j])
4239 contents.append(document.body[i + 1:j])
4241 if thischunk == "@":
4244 # look for the next one
4246 i = find_token(document.body, "\\begin_layout", i)
4250 layout = get_value(document.body, "\\begin_layout", i)
4251 #sys.stderr.write(layout+ '\n')
4252 if layout != "Chunk":
4256 # error, but we can try to continue
4263 # the last chunk should simply have an "@" in it
4265 if ''.join(contents[-1]) != "@":
4266 document.warning("Unexpected chunk contents.")
4271 # the first item should look like: <<FROGS>>=
4272 # we want the inside
4273 optarg = ' '.join(contents[0])
4275 match = first_re.search(optarg)
4277 optarg = match.groups()[0]
4280 newstuff = ['\\begin_layout Standard',
4281 '\\begin_inset Flex Chunk',
4283 '\\begin_layout Plain Layout', '']
4287 ['\\begin_inset Argument 1',
4289 '\\begin_layout Plain Layout',
4297 newstuff.extend(['', '\\begin_layout Plain Layout', ''])
4301 newstuff.append('\\end_layout')
4303 newstuff.extend(['', '\\end_inset', '', '\\end_layout', ''])
4305 document.body[start:end] = newstuff
4307 k += len(newstuff) - (end - start)
4310 def revert_chunks(document):
4313 i = find_token(document.body, "\\begin_inset Flex Chunk", i)
4317 iend = find_end_of_inset(document.body, i)
4319 document.warning("Can't find end of Chunk!")
4323 # Look for optional argument
4325 ostart = find_token(document.body, "\\begin_inset Argument 1", i, iend)
4327 oend = find_end_of_inset(document.body, ostart)
4328 k = find_token(document.body, "\\begin_layout Plain Layout", ostart, oend)
4330 document.warning("Malformed LyX document: Can't find argument contents!")
4332 m = find_end_of_layout(document.body, k)
4333 optarg = "".join(document.body[k+1:m])
4336 # We now remove the optional argument, so we have something
4337 # uniform on which to work
4338 document.body[ostart : oend + 1] = []
4339 # iend is now invalid
4340 iend = find_end_of_inset(document.body, i)
4342 retval = get_containing_layout(document.body, i)
4344 document.warning("Can't find containing layout for Chunk!")
4347 (lname, lstart, lend, pstart) = retval
4348 # we now want to work through the various paragraphs, and collect their contents
4352 k = find_token(document.body, "\\begin_layout Plain Layout", k, lend)
4355 j = find_end_of_layout(document.body, k)
4357 document.warning("Can't find end of layout inside chunk!")
4359 parlist.append(document.body[k+1:j])
4361 # we now need to wrap all of these paragraphs in chunks
4364 newlines.extend(["\\begin_layout Chunk", "", "<<" + optarg + ">>=", "\\end_layout", ""])
4365 for stuff in parlist:
4366 newlines.extend(["\\begin_layout Chunk"] + stuff + ["\\end_layout", ""])
4367 newlines.extend(["\\begin_layout Chunk", "", "@", "\\end_layout", ""])
4368 # replace old content with new content
4369 document.body[lstart : lend + 1] = newlines
4370 i = lstart + len(newlines)
4377 supported_versions = ["2.1.0","2.1"]
4380 [415, [convert_undertilde]],
4382 [417, [convert_japanese_encodings]],
4385 [420, [convert_biblio_style]],
4386 [421, [convert_longtable_captions]],
4387 [422, [convert_use_packages]],
4388 [423, [convert_use_mathtools]],
4389 [424, [convert_cite_engine_type]],
4393 [428, [convert_cell_rotation]],
4394 [429, [convert_table_rotation]],
4395 [430, [convert_listoflistings]],
4396 [431, [convert_use_amssymb]],
4398 [433, [convert_armenian]],
4406 [441, [convert_mdnomath]],
4411 [446, [convert_latexargs]],
4412 [447, [convert_IEEEtran, convert_AASTeX, convert_AGUTeX, convert_IJMP, convert_SIGPLAN, convert_SIGGRAPH, convert_EuropeCV, convert_Initials, convert_ModernCV]],
4413 [448, [convert_literate]],
4416 [451, [convert_beamerargs, convert_againframe_args, convert_corollary_args, convert_quote_args]],
4417 [452, [convert_beamerblocks]],
4418 [453, [convert_use_stmaryrd]],
4419 [454, [convert_overprint]],
4421 [456, [convert_epigraph]],
4422 [457, [convert_use_stackrel]],
4423 [458, [convert_captioninsets, convert_captionlayouts]],
4428 [463, [convert_encodings]],
4429 [464, [convert_use_cancel]],
4430 [465, [convert_lyxframes, remove_endframes]],
4436 [471, [convert_cite_engine_type_default]],
4439 [474, [convert_chunks]],
4443 [473, [revert_chunks]],
4444 [472, [revert_tibetan]],
4445 [471, [revert_aa1,revert_aa2]],
4446 [470, [revert_cite_engine_type_default]],
4447 [469, [revert_forced_local_layout]],
4448 [468, [revert_starred_caption]],
4449 [467, [revert_mbox_fbox]],
4450 [466, [revert_iwona_fonts]],
4451 [465, [revert_powerdot_flexes, revert_powerdot_pause, revert_powerdot_itemargs, revert_powerdot_columns]],
4453 [463, [revert_use_cancel]],
4454 [462, [revert_encodings]],
4455 [461, [revert_new_libertines]],
4456 [460, [revert_kurier_fonts]],
4457 [459, [revert_IEEEtran_3]],
4458 [458, [revert_fragileframe, revert_newframes]],
4459 [457, [revert_captioninsets, revert_captionlayouts]],
4460 [456, [revert_use_stackrel]],
4461 [455, [revert_epigraph]],
4462 [454, [revert_frametitle]],
4463 [453, [revert_overprint]],
4464 [452, [revert_use_stmaryrd]],
4465 [451, [revert_beamerblocks]],
4466 [450, [revert_beamerargs, revert_beamerargs2, revert_beamerargs3, revert_beamerflex]],
4467 [449, [revert_garamondx, revert_garamondx_newtxmath]],
4468 [448, [revert_itemargs]],
4469 [447, [revert_literate]],
4470 [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]],
4471 [445, [revert_latexargs]],
4472 [444, [revert_uop]],
4473 [443, [revert_biolinum]],
4475 [441, [revert_newtxmath]],
4476 [440, [revert_mdnomath]],
4477 [439, [revert_mathfonts]],
4478 [438, [revert_minionpro]],
4479 [437, [revert_ipadeco, revert_ipachar]],
4480 [436, [revert_texgyre]],
4481 [435, [revert_mathdesign]],
4482 [434, [revert_txtt]],
4483 [433, [revert_libertine]],
4484 [432, [revert_armenian]],
4485 [431, [revert_languages, revert_ancientgreek]],
4486 [430, [revert_use_amssymb]],
4487 [429, [revert_listoflistings]],
4488 [428, [revert_table_rotation]],
4489 [427, [revert_cell_rotation]],
4490 [426, [revert_tipa]],
4491 [425, [revert_verbatim]],
4492 [424, [revert_cancel]],
4493 [423, [revert_cite_engine_type]],
4494 [422, [revert_use_mathtools]],
4495 [421, [revert_use_packages]],
4496 [420, [revert_longtable_captions]],
4497 [419, [revert_biblio_style]],
4498 [418, [revert_australian]],
4499 [417, [revert_justification]],
4500 [416, [revert_japanese_encodings]],
4501 [415, [revert_negative_space, revert_math_spaces]],
4502 [414, [revert_undertilde]],
4503 [413, [revert_visible_space]]
4507 if __name__ == "__main__":