1 # -*- coding: utf-8 -*-
2 # This file is part of lyx2lyx
3 # -*- coding: utf-8 -*-
4 # Copyright (C) 2011 The LyX team
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 2
9 # of the License, or (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 """ Convert files to the file format generated by LyX 2.1"""
26 # Uncomment only what you need to import, please.
28 from parser_tools import count_pars_in_inset, del_token, find_token, find_token_exact, \
29 find_token_backwards, find_end_of, find_end_of_inset, find_end_of_layout, \
30 find_end_of_sequence, find_re, get_option_value, get_containing_layout, \
31 get_value, get_quoted_value, set_option_value
33 #from parser_tools import find_token, find_end_of, find_tokens, \
34 #find_end_of_inset, find_end_of_layout, \
35 #is_in_inset, del_token, check_token
37 from lyx2lyx_tools import add_to_preamble, put_cmd_in_ert, get_ert
39 #from lyx2lyx_tools import insert_to_preamble, \
40 # lyx2latex, latex_length, revert_flex_inset, \
41 # revert_font_attrs, hex2ratio, str2bool
43 ####################################################################
44 # Private helper functions
46 #def remove_option(lines, m, option):
47 #''' removes option from line m. returns whether we did anything '''
48 #l = lines[m].find(option)
51 #val = lines[m][l:].split('"')[1]
52 #lines[m] = lines[m][:l - 1] + lines[m][l+len(option + '="' + val + '"'):]
56 def revert_Argument_to_TeX_brace(document, line, endline, n, nmax, environment, opt):
58 Reverts an InsetArgument to TeX-code
60 revert_Argument_to_TeX_brace(document, LineOfBegin, LineOfEnd, StartArgument, EndArgument, isEnvironment, isOpt)
61 LineOfBegin is the line of the \begin_layout or \begin_inset statement
62 LineOfEnd is the line of the \end_layout or \end_inset statement, if "0" is given, the end of the file is used instead
63 StartArgument is the number of the first argument that needs to be converted
64 EndArgument is the number of the last argument that needs to be converted or the last defined one
65 isEnvironment must be true, if the layout is for a LaTeX environment
66 isOpt must be true, if the argument is an optional one
70 while lineArg != -1 and n < nmax + 1:
71 lineArg = find_token(document.body, "\\begin_inset Argument " + str(n), line)
72 if lineArg > endline and endline != 0:
75 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", lineArg)
76 # we have to assure that no other inset is in the Argument
77 beginInset = find_token(document.body, "\\begin_inset", beginPlain)
78 endInset = find_token(document.body, "\\end_inset", beginPlain)
81 while beginInset < endInset and beginInset != -1:
82 beginInset = find_token(document.body, "\\begin_inset", k)
83 endInset = find_token(document.body, "\\end_inset", l)
86 if environment == False:
88 document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("}{")
89 del(document.body[lineArg : beginPlain + 1])
92 document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("]")
93 document.body[lineArg : beginPlain + 1] = put_cmd_in_ert("[")
96 document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("}")
97 document.body[lineArg : beginPlain + 1] = put_cmd_in_ert("{")
103 def convert_TeX_brace_to_Argument(document, line, n, nmax, inset, environment):
105 Converts TeX code for mandatory arguments to an InsetArgument
106 The conversion of TeX code for optional arguments must be done with another routine
107 !!! Be careful if the braces are different in your case as expected here:
108 - "}{" separates mandatory arguments of commands
109 - "}" + "{" separates mandatory arguments of commands
110 - "}" + " " + "{" separates mandatory arguments of commands
111 - { and } surround a mandatory argument of an environment
113 convert_TeX_brace_to_Argument(document, LineOfBeginLayout/Inset, StartArgument, EndArgument, isInset, isEnvironment)
114 LineOfBeginLayout/Inset is the line of the \begin_layout or \begin_inset statement
115 StartArgument is the number of the first ERT that needs to be converted
116 EndArgument is the number of the last ERT that needs to be converted
117 isInset must be true, if braces inside an InsetLayout needs to be converted
118 isEnvironment must be true, if the layout is for a LaTeX environment
120 Todo: this routine can currently handle only one mandatory argument of environments
125 while lineERT != -1 and n < nmax + 1:
126 lineERT = find_token(document.body, "\\begin_inset ERT", lineERT)
127 if environment == False and lineERT != -1:
128 bracePair = find_token(document.body, "}{", lineERT)
129 # assure that the "}{" is in this ERT
130 if bracePair == lineERT + 5:
131 end = find_token(document.body, "\\end_inset", bracePair)
132 document.body[lineERT : end + 1] = ["\\end_layout", "", "\\end_inset"]
134 # in the case that n > 1 we have optional arguments before
135 # therefore detect them if any
137 # first check if there is an argument
138 lineArg = find_token(document.body, "\\begin_inset Argument", line)
139 if lineArg < lineERT and lineArg != -1:
140 # we have an argument, so now search backwards for its end
141 # we must now assure that we don't find other insets like e.g. a newline
142 endInsetArg = lineERT
143 endLayoutArg = endInsetArg
144 while endInsetArg != endLayoutArg + 2 and endInsetArg != -1:
145 endInsetArg = endInsetArg - 1
146 endLayoutArg = endInsetArg
147 endInsetArg = find_token_backwards(document.body, "\\end_inset", endInsetArg)
148 endLayoutArg = find_token_backwards(document.body, "\\end_layout", endLayoutArg)
149 line = endInsetArg + 1
151 document.body[line + 1 : line + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
153 document.body[line + 4 : line + 4] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
155 document.body[endn : endn] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
159 # now check the case that we have "}" + "{" in two ERTs
161 endBrace = find_token(document.body, "}", lineERT)
162 if endBrace == lineERT + 5:
163 beginBrace = find_token(document.body, "{", endBrace)
164 # assure that the ERTs are consecutive (11 or 12 depending if there is a space between the ERTs or not)
165 if beginBrace == endBrace + 11 or beginBrace == endBrace + 12:
166 end = find_token(document.body, "\\end_inset", beginBrace)
167 document.body[lineERT : end + 1] = ["\\end_layout", "", "\\end_inset"]
169 # in the case that n > 1 we have optional arguments before
170 # therefore detect them if any
172 # first check if there is an argument
173 lineArg = find_token(document.body, "\\begin_inset Argument", line)
174 if lineArg < lineERT and lineArg != -1:
175 # we have an argument, so now search backwards for its end
176 # we must now assure that we don't find other insets like e.g. a newline
177 endInsetArg = lineERT
178 endLayoutArg = endInsetArg
179 while endInsetArg != endLayoutArg + 2 and endInsetArg != -1:
180 endInsetArg = endInsetArg - 1
181 endLayoutArg = endInsetArg
182 endInsetArg = find_token_backwards(document.body, "\\end_inset", endInsetArg)
183 endLayoutArg = find_token_backwards(document.body, "\\end_layout", endLayoutArg)
184 line = endInsetArg + 1
186 document.body[line + 1 : line + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
188 document.body[line + 4 : line + 4] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
190 document.body[endn : endn] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
193 # set the line where the next argument will be inserted
194 if beginBrace == endBrace + 11:
202 if environment == True and lineERT != -1:
203 opening = find_token(document.body, "{", lineERT)
204 if opening == lineERT + 5: # assure that the "{" is in this ERT
205 end = find_token(document.body, "\\end_inset", opening)
206 document.body[lineERT : end + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
208 lineERT2 = find_token(document.body, "\\begin_inset ERT", lineERT)
209 closing = find_token(document.body, "}", lineERT2)
210 if closing == lineERT2 + 5: # assure that the "}" is in this ERT
211 end2 = find_token(document.body, "\\end_inset", closing)
212 document.body[lineERT2 : end2 + 1] = ["\\end_layout", "", "\\end_inset"]
217 ###############################################################################
219 ### Conversion and reversion routines
221 ###############################################################################
223 def revert_visible_space(document):
224 "Revert InsetSpace visible into its ERT counterpart"
227 i = find_token(document.body, "\\begin_inset space \\textvisiblespace{}", i)
230 end = find_end_of_inset(document.body, i)
231 subst = put_cmd_in_ert("\\textvisiblespace{}")
232 document.body[i:end + 1] = subst
235 def convert_undertilde(document):
236 " Load undertilde automatically "
237 i = find_token(document.header, "\\use_mathdots" , 0)
239 i = find_token(document.header, "\\use_mhchem" , 0)
241 i = find_token(document.header, "\\use_esint" , 0)
243 document.warning("Malformed LyX document: Can't find \\use_mathdots.")
245 j = find_token(document.preamble, "\\usepackage{undertilde}", 0)
247 document.header.insert(i + 1, "\\use_undertilde 0")
249 document.header.insert(i + 1, "\\use_undertilde 2")
250 del document.preamble[j]
253 def revert_undertilde(document):
254 " Load undertilde if used in the document "
255 undertilde = find_token(document.header, "\\use_undertilde" , 0)
257 document.warning("No \\use_undertilde line. Assuming auto.")
259 val = get_value(document.header, "\\use_undertilde", undertilde)
260 del document.header[undertilde]
264 document.warning("Invalid \\use_undertilde value: " + val + ". Assuming auto.")
265 # probably usedots has not been changed, but be safe.
273 add_to_preamble(document, ["\\usepackage{undertilde}"])
276 # so we are in the auto case. we want to load undertilde if \utilde is used.
279 i = find_token(document.body, '\\begin_inset Formula', i)
282 j = find_end_of_inset(document.body, i)
284 document.warning("Malformed LyX document: Can't find end of Formula inset at line " + str(i))
287 code = "\n".join(document.body[i:j])
288 if code.find("\\utilde") != -1:
289 add_to_preamble(document, ["\\@ifundefined{utilde}{\\usepackage{undertilde}}"])
294 def revert_negative_space(document):
295 "Revert InsetSpace negmedspace and negthickspace into its TeX-code counterpart"
300 i = find_token(document.body, "\\begin_inset space \\negmedspace{}", i)
302 j = find_token(document.body, "\\begin_inset space \\negthickspace{}", j)
304 # load amsmath in the preamble if not already loaded if we are at the end of checking
306 i = find_token(document.header, "\\use_amsmath 2", 0)
308 add_to_preamble(document, ["\\@ifundefined{negthickspace}{\\usepackage{amsmath}}"])
312 end = find_end_of_inset(document.body, i)
313 subst = put_cmd_in_ert("\\negmedspace{}")
314 document.body[i:end + 1] = subst
315 j = find_token(document.body, "\\begin_inset space \\negthickspace{}", j)
318 end = find_end_of_inset(document.body, j)
319 subst = put_cmd_in_ert("\\negthickspace{}")
320 document.body[j:end + 1] = subst
324 def revert_math_spaces(document):
325 "Revert formulas with protected custom space and protected hfills to TeX-code"
328 i = find_token(document.body, "\\begin_inset Formula", i)
331 j = document.body[i].find("\\hspace*")
333 end = find_end_of_inset(document.body, i)
334 subst = put_cmd_in_ert(document.body[i][21:])
335 document.body[i:end + 1] = subst
339 def convert_japanese_encodings(document):
340 " Rename the japanese encodings to names understood by platex "
342 "EUC-JP-pLaTeX": "euc",
344 "SJIS-pLaTeX": "sjis"
346 i = find_token(document.header, "\\inputencoding" , 0)
349 val = get_value(document.header, "\\inputencoding", i)
350 if val in jap_enc_dict.keys():
351 document.header[i] = "\\inputencoding %s" % jap_enc_dict[val]
354 def revert_japanese_encodings(document):
355 " Revert the japanese encodings name changes "
357 "euc": "EUC-JP-pLaTeX",
359 "sjis": "SJIS-pLaTeX"
361 i = find_token(document.header, "\\inputencoding" , 0)
364 val = get_value(document.header, "\\inputencoding", i)
365 if val in jap_enc_dict.keys():
366 document.header[i] = "\\inputencoding %s" % jap_enc_dict[val]
369 def revert_justification(document):
370 " Revert the \\justification buffer param"
371 if not del_token(document.header, '\\justification', 0):
372 document.warning("Malformed LyX document: Missing \\justification.")
375 def revert_australian(document):
376 "Set English language variants Australian and Newzealand to English"
378 if document.language == "australian" or document.language == "newzealand":
379 document.language = "english"
380 i = find_token(document.header, "\\language", 0)
382 document.header[i] = "\\language english"
385 j = find_token(document.body, "\\lang australian", j)
387 j = find_token(document.body, "\\lang newzealand", 0)
391 document.body[j] = document.body[j].replace("\\lang newzealand", "\\lang english")
393 document.body[j] = document.body[j].replace("\\lang australian", "\\lang english")
397 def convert_biblio_style(document):
398 "Add a sensible default for \\biblio_style based on the citation engine."
399 i = find_token(document.header, "\\cite_engine", 0)
401 engine = get_value(document.header, "\\cite_engine", i).split("_")[0]
402 style = {"basic": "plain", "natbib": "plainnat", "jurabib": "jurabib"}
403 document.header.insert(i + 1, "\\biblio_style " + style[engine])
406 def revert_biblio_style(document):
407 "BibTeX insets with default option use the style defined by \\biblio_style."
408 i = find_token(document.header, "\\biblio_style" , 0)
410 document.warning("No \\biblio_style line. Nothing to do.")
413 default_style = get_value(document.header, "\\biblio_style", i)
414 del document.header[i]
416 # We are looking for bibtex insets having the default option
419 i = find_token(document.body, "\\begin_inset CommandInset bibtex", i)
422 j = find_end_of_inset(document.body, i)
424 document.warning("Malformed LyX document: Can't find end of bibtex inset at line " + str(i))
427 k = find_token(document.body, "options", i, j)
429 options = get_quoted_value(document.body, "options", k)
430 if "default" in options.split(","):
431 document.body[k] = 'options "%s"' \
432 % options.replace("default", default_style)
436 def handle_longtable_captions(document, forward):
439 begin_table = find_token(document.body, '<lyxtabular version=', begin_table)
440 if begin_table == -1:
442 end_table = find_end_of(document.body, begin_table, '<lyxtabular', '</lyxtabular>')
444 document.warning("Malformed LyX document: Could not find end of table.")
447 fline = find_token(document.body, "<features", begin_table, end_table)
449 document.warning("Can't find features for inset at line " + str(begin_table))
452 p = document.body[fline].find("islongtable")
457 numrows = get_option_value(document.body[begin_table], "rows")
459 numrows = int(numrows)
461 document.warning(document.body[begin_table])
462 document.warning("Unable to determine rows!")
463 begin_table = end_table
465 begin_row = begin_table
466 for row in range(numrows):
467 begin_row = find_token(document.body, '<row', begin_row, end_table)
469 document.warning("Can't find row " + str(row + 1))
471 end_row = find_end_of(document.body, begin_row, '<row', '</row>')
473 document.warning("Can't find end of row " + str(row + 1))
476 if (get_option_value(document.body[begin_row], 'caption') == 'true' and
477 get_option_value(document.body[begin_row], 'endfirsthead') != 'true' and
478 get_option_value(document.body[begin_row], 'endhead') != 'true' and
479 get_option_value(document.body[begin_row], 'endfoot') != 'true' and
480 get_option_value(document.body[begin_row], 'endlastfoot') != 'true'):
481 document.body[begin_row] = set_option_value(document.body[begin_row], 'caption', 'true", endfirsthead="true')
482 elif get_option_value(document.body[begin_row], 'caption') == 'true':
483 if get_option_value(document.body[begin_row], 'endfirsthead') == 'true':
484 document.body[begin_row] = set_option_value(document.body[begin_row], 'endfirsthead', 'false')
485 if get_option_value(document.body[begin_row], 'endhead') == 'true':
486 document.body[begin_row] = set_option_value(document.body[begin_row], 'endhead', 'false')
487 if get_option_value(document.body[begin_row], 'endfoot') == 'true':
488 document.body[begin_row] = set_option_value(document.body[begin_row], 'endfoot', 'false')
489 if get_option_value(document.body[begin_row], 'endlastfoot') == 'true':
490 document.body[begin_row] = set_option_value(document.body[begin_row], 'endlastfoot', 'false')
492 # since there could be a tabular inside this one, we
493 # cannot jump to end.
497 def convert_longtable_captions(document):
498 "Add a firsthead flag to caption rows"
499 handle_longtable_captions(document, True)
502 def revert_longtable_captions(document):
503 "remove head/foot flag from caption rows"
504 handle_longtable_captions(document, False)
507 def convert_use_packages(document):
508 "use_xxx yyy => use_package xxx yyy"
509 packages = ["amsmath", "esint", "mathdots", "mhchem", "undertilde"]
511 i = find_token(document.header, "\\use_%s" % p, 0)
513 value = get_value(document.header, "\\use_%s" % p, i)
514 document.header[i] = "\\use_package %s %s" % (p, value)
517 def revert_use_packages(document):
518 "use_package xxx yyy => use_xxx yyy"
519 packages = ["amsmath", "esint", "mathdots", "mhchem", "undertilde"]
520 # the order is arbitrary for the use_package version, and not all packages need to be given.
521 # Ensure a complete list and correct order (important for older LyX versions and especially lyx2lyx)
524 regexp = re.compile(r'(\\use_package\s+%s)' % p)
525 i = find_re(document.header, regexp, j)
527 value = get_value(document.header, "\\use_package %s" % p, i).split()[1]
528 del document.header[i]
530 document.header.insert(j, "\\use_%s %s" % (p, value))
534 def convert_use_package(document, pkg):
535 i = find_token(document.header, "\\use_package", 0)
537 document.warning("Malformed LyX document: Can't find \\use_package.")
539 j = find_token(document.preamble, "\\usepackage{" + pkg + "}", 0)
541 document.header.insert(i + 1, "\\use_package " + pkg + " 0")
543 document.header.insert(i + 1, "\\use_package " + pkg + " 2")
544 del document.preamble[j]
547 def revert_use_package(document, pkg, commands, oldauto):
548 # oldauto defines how the version we are reverting to behaves:
549 # if it is true, the old version uses the package automatically.
550 # if it is false, the old version never uses the package.
551 regexp = re.compile(r'(\\use_package\s+%s)' % pkg)
552 i = find_re(document.header, regexp, 0)
553 value = "1" # default is auto
555 value = get_value(document.header, "\\use_package" , i).split()[1]
556 del document.header[i]
557 if value == "2": # on
558 add_to_preamble(document, ["\\usepackage{" + pkg + "}"])
559 elif value == "1" and not oldauto: # auto
562 i = find_token(document.body, '\\begin_inset Formula', i)
565 j = find_end_of_inset(document.body, i)
567 document.warning("Malformed LyX document: Can't find end of Formula inset at line " + str(i))
570 code = "\n".join(document.body[i:j])
572 if code.find("\\%s" % c) != -1:
573 add_to_preamble(document, ["\\usepackage{" + pkg + "}"])
578 def convert_use_mathtools(document):
579 "insert use_package mathtools"
580 convert_use_package(document, "mathtools")
583 def revert_use_mathtools(document):
584 "remove use_package mathtools"
585 commands = ["mathclap", "mathllap", "mathrlap", \
586 "lgathered", "rgathered", "vcentcolon", "dblcolon", \
587 "coloneqq", "Coloneqq", "coloneq", "Coloneq", "eqqcolon", \
588 "Eqqcolon", "eqcolon", "Eqcolon", "colonapprox", \
589 "Colonapprox", "colonsim", "Colonsim"]
590 revert_use_package(document, "mathtools", commands, False)
593 def convert_use_stmaryrd(document):
594 "insert use_package stmaryrd"
595 convert_use_package(document, "stmaryrd")
598 def revert_use_stmaryrd(document):
599 "remove use_package stmaryrd"
600 # commands provided by stmaryrd.sty but LyX uses other packages:
601 # boxdot lightning, bigtriangledown, bigtriangleup
602 commands = ["shortleftarrow", "shortrightarrow", "shortuparrow", \
603 "shortdownarrow", "Yup", "Ydown", "Yleft", "Yright", \
604 "varcurlyvee", "varcurlywedge", "minuso", "baro", \
605 "sslash", "bbslash", "moo", "varotimes", "varoast", \
606 "varobar", "varodot", "varoslash", "varobslash", \
607 "varocircle", "varoplus", "varominus", "boxast", \
608 "boxbar", "boxslash", "boxbslash", "boxcircle", \
609 "boxbox", "boxempty", "merge", "vartimes", \
610 "fatsemi", "sswarrow", "ssearrow", "curlywedgeuparrow", \
611 "curlywedgedownarrow", "fatslash", "fatbslash", "lbag", \
612 "rbag", "varbigcirc", "leftrightarroweq", \
613 "curlyveedownarrow", "curlyveeuparrow", "nnwarrow", \
614 "nnearrow", "leftslice", "rightslice", "varolessthan", \
615 "varogreaterthan", "varovee", "varowedge", "talloblong", \
616 "interleave", "obar", "obslash", "olessthan", \
617 "ogreaterthan", "ovee", "owedge", "oblong", "inplus", \
618 "niplus", "nplus", "subsetplus", "supsetplus", \
619 "subsetpluseq", "supsetpluseq", "Lbag", "Rbag", \
620 "llbracket", "rrbracket", "llparenthesis", \
621 "rrparenthesis", "binampersand", "bindnasrepma", \
622 "trianglelefteqslant", "trianglerighteqslant", \
623 "ntrianglelefteqslant", "ntrianglerighteqslant", \
624 "llfloor", "rrfloor", "llceil", "rrceil", "arrownot", \
625 "Arrownot", "Mapstochar", "mapsfromchar", "Mapsfromchar", \
626 "leftrightarrowtriangle", "leftarrowtriangle", \
627 "rightarrowtriangle", \
628 "bigcurlyvee", "bigcurlywedge", "bigsqcap", "bigbox", \
629 "bigparallel", "biginterleave", "bignplus", \
630 "varcopyright", "longarrownot", "Longarrownot", \
631 "Mapsto", "mapsfrom", "Mapsfrom" "Longmapsto", \
632 "longmapsfrom", "Longmapsfrom"]
633 revert_use_package(document, "stmaryrd", commands, False)
637 def convert_use_stackrel(document):
638 "insert use_package stackrel"
639 convert_use_package(document, "stackrel")
642 def revert_use_stackrel(document):
643 "remove use_package stackrel"
644 commands = ["stackrel"]
645 revert_use_package(document, "stackrel", commands, False)
648 def convert_cite_engine_type(document):
649 "Determine the \\cite_engine_type from the citation engine."
650 i = find_token(document.header, "\\cite_engine", 0)
653 engine = get_value(document.header, "\\cite_engine", i)
655 engine, type = engine.split("_")
657 type = {"basic": "numerical", "jurabib": "authoryear"}[engine]
658 document.header[i] = "\\cite_engine " + engine
659 document.header.insert(i + 1, "\\cite_engine_type " + type)
662 def revert_cite_engine_type(document):
663 "Natbib had the type appended with an underscore."
664 engine_type = "numerical"
665 i = find_token(document.header, "\\cite_engine_type" , 0)
667 document.warning("No \\cite_engine_type line. Assuming numerical.")
669 engine_type = get_value(document.header, "\\cite_engine_type", i)
670 del document.header[i]
672 # We are looking for the natbib citation engine
673 i = find_token(document.header, "\\cite_engine natbib", 0)
676 document.header[i] = "\\cite_engine natbib_" + engine_type
679 def convert_cite_engine_type_default(document):
680 "Convert \\cite_engine_type to default for the basic citation engine."
681 i = find_token(document.header, "\\cite_engine basic", 0)
684 i = find_token(document.header, "\\cite_engine_type" , 0)
687 document.header[i] = "\\cite_engine_type default"
690 def revert_cite_engine_type_default(document):
691 """Revert \\cite_engine_type default.
693 Revert to numerical for the basic cite engine, otherwise to authoryear."""
694 engine_type = "authoryear"
695 i = find_token(document.header, "\\cite_engine_type default" , 0)
698 j = find_token(document.header, "\\cite_engine basic", 0)
700 engine_type = "numerical"
701 document.header[i] = "\\cite_engine_type " + engine_type
704 # this is the same, as revert_use_cancel() except for the default
705 def revert_cancel(document):
706 "add cancel to the preamble if necessary"
707 commands = ["cancelto", "cancel", "bcancel", "xcancel"]
708 revert_use_package(document, "cancel", commands, False)
711 def revert_verbatim(document):
712 " Revert verbatim einvironments completely to TeX-code. "
715 subst_end = ['\end_layout', '', '\\begin_layout Plain Layout',
717 '\\begin_layout Plain Layout', '', '',
720 '\\end_layout', '', '\\end_inset',
721 '', '', '\\end_layout']
722 subst_begin = ['\\begin_layout Standard', '\\noindent',
723 '\\begin_inset ERT', 'status collapsed', '',
724 '\\begin_layout Plain Layout', '', '', '\\backslash',
726 '\\end_layout', '', '\\begin_layout Plain Layout', '']
728 i = find_token(document.body, "\\begin_layout Verbatim", i)
731 j = find_end_of_layout(document.body, i)
733 document.warning("Malformed LyX document: Can't find end of Verbatim layout")
736 # delete all line breaks insets (there are no other insets)
739 n = find_token(document.body, "\\begin_inset Newline newline", l)
741 n = find_token(document.body, "\\begin_inset Newline linebreak", l)
744 m = find_end_of_inset(document.body, n)
745 del(document.body[m:m+1])
746 document.body[n:n+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
749 # consecutive verbatim environments need to be connected
750 k = find_token(document.body, "\\begin_layout Verbatim", j)
751 if k == j + 2 and consecutive == False:
753 document.body[j:j+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
754 document.body[i:i+1] = subst_begin
756 if k == j + 2 and consecutive == True:
757 document.body[j:j+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
758 del(document.body[i:i+1])
760 if k != j + 2 and consecutive == True:
761 document.body[j:j+1] = subst_end
762 # the next paragraph must not be indented
763 document.body[j+19:j+19] = ['\\noindent']
764 del(document.body[i:i+1])
768 document.body[j:j+1] = subst_end
769 # the next paragraph must not be indented
770 document.body[j+19:j+19] = ['\\noindent']
771 document.body[i:i+1] = subst_begin
774 def revert_tipa(document):
775 " Revert native TIPA insets to mathed or ERT. "
778 i = find_token(document.body, "\\begin_inset IPA", i)
781 j = find_end_of_inset(document.body, i)
783 document.warning("Malformed LyX document: Can't find end of IPA inset")
787 n = find_token(document.body, "\\begin_layout", i, j)
789 document.warning("Malformed LyX document: IPA inset has no embedded layout")
792 m = find_end_of_layout(document.body, n)
794 document.warning("Malformed LyX document: Can't find end of embedded layout")
797 content = document.body[n+1:m]
798 p = find_token(document.body, "\\begin_layout", m, j)
799 if p != -1 or len(content) > 1:
801 content = document.body[i+1:j]
803 # IPA insets with multiple pars need to be wrapped by \begin{IPA}...\end{IPA}
804 document.body[i:j+1] = ['\\end_layout', '', '\\begin_layout Standard'] + put_cmd_in_ert("\\begin{IPA}") + ['\\end_layout'] + content + ['\\begin_layout Standard'] + put_cmd_in_ert("\\end{IPA}")
805 add_to_preamble(document, ["\\usepackage{tipa,tipx}"])
807 # single-par IPA insets can be reverted to mathed
808 document.body[i:j+1] = ["\\begin_inset Formula $\\text{\\textipa{" + content[0] + "}}$", "\\end_inset"]
812 def revert_cell_rotation(document):
813 "Revert cell rotations to TeX-code"
815 load_rotating = False
819 # first, let's find out if we need to do anything
820 i = find_token(document.body, '<cell ', i)
823 j = document.body[i].find('rotate="')
825 k = document.body[i].find('"', j + 8)
826 value = document.body[i][j + 8 : k]
828 rgx = re.compile(r' rotate="[^"]+?"')
829 # remove rotate option
830 document.body[i] = rgx.sub('', document.body[i])
832 rgx = re.compile(r' rotate="[^"]+?"')
833 document.body[i] = rgx.sub('rotate="true"', document.body[i])
835 rgx = re.compile(r' rotate="[^"]+?"')
837 # remove rotate option
838 document.body[i] = rgx.sub('', document.body[i])
840 document.body[i + 5 : i + 5] = \
841 put_cmd_in_ert("\\end{turn}")
842 document.body[i + 4 : i + 4] = \
843 put_cmd_in_ert("\\begin{turn}{" + value + "}")
849 add_to_preamble(document, ["\\@ifundefined{turnbox}{\usepackage{rotating}}{}"])
852 def convert_cell_rotation(document):
853 'Convert cell rotation statements from "true" to "90"'
857 # first, let's find out if we need to do anything
858 i = find_token(document.body, '<cell ', i)
861 j = document.body[i].find('rotate="true"')
863 rgx = re.compile(r'rotate="[^"]+?"')
864 # convert "true" to "90"
865 document.body[i] = rgx.sub('rotate="90"', document.body[i])
870 def revert_table_rotation(document):
871 "Revert table rotations to TeX-code"
873 load_rotating = False
877 # first, let's find out if we need to do anything
878 i = find_token(document.body, '<features ', i)
881 j = document.body[i].find('rotate="')
883 end_table = find_token(document.body, '</lyxtabular>', j)
884 k = document.body[i].find('"', j + 8)
885 value = document.body[i][j + 8 : k]
887 rgx = re.compile(r' rotate="[^"]+?"')
888 # remove rotate option
889 document.body[i] = rgx.sub('', document.body[i])
891 rgx = re.compile(r'rotate="[^"]+?"')
892 document.body[i] = rgx.sub('rotate="true"', document.body[i])
894 rgx = re.compile(r' rotate="[^"]+?"')
896 # remove rotate option
897 document.body[i] = rgx.sub('', document.body[i])
899 document.body[end_table + 3 : end_table + 3] = \
900 put_cmd_in_ert("\\end{turn}")
901 document.body[i - 2 : i - 2] = \
902 put_cmd_in_ert("\\begin{turn}{" + value + "}")
908 add_to_preamble(document, ["\\@ifundefined{turnbox}{\usepackage{rotating}}{}"])
911 def convert_table_rotation(document):
912 'Convert table rotation statements from "true" to "90"'
916 # first, let's find out if we need to do anything
917 i = find_token(document.body, '<features ', i)
920 j = document.body[i].find('rotate="true"')
922 rgx = re.compile(r'rotate="[^"]+?"')
923 # convert "true" to "90"
924 document.body[i] = rgx.sub('rotate="90"', document.body[i])
929 def convert_listoflistings(document):
930 'Convert ERT \lstlistoflistings to TOC lstlistoflistings inset'
931 # We can support roundtrip because the command is so simple
934 i = find_token(document.body, "\\begin_inset ERT", i)
937 j = find_end_of_inset(document.body, i)
939 document.warning("Malformed LyX document: Can't find end of ERT inset")
942 ert = get_ert(document.body, i)
943 if ert == "\\lstlistoflistings{}":
944 document.body[i:j] = ["\\begin_inset CommandInset toc", "LatexCommand lstlistoflistings", ""]
950 def revert_listoflistings(document):
951 'Convert TOC lstlistoflistings inset to ERT lstlistoflistings'
954 i = find_token(document.body, "\\begin_inset CommandInset toc", i)
957 if document.body[i+1] == "LatexCommand lstlistoflistings":
958 j = find_end_of_inset(document.body, i)
960 document.warning("Malformed LyX document: Can't find end of TOC inset")
963 subst = put_cmd_in_ert("\\lstlistoflistings{}")
964 document.body[i:j+1] = subst
965 add_to_preamble(document, ["\\usepackage{listings}"])
969 def convert_use_amssymb(document):
970 "insert use_package amssymb"
971 regexp = re.compile(r'(\\use_package\s+amsmath)')
972 i = find_re(document.header, regexp, 0)
974 document.warning("Malformed LyX document: Can't find \\use_package amsmath.")
976 value = get_value(document.header, "\\use_package" , i).split()[1]
979 useamsmath = int(value)
981 document.warning("Invalid \\use_package amsmath: " + value + ". Assuming auto.")
983 j = find_token(document.preamble, "\\usepackage{amssymb}", 0)
985 document.header.insert(i + 1, "\\use_package amssymb %d" % useamsmath)
987 document.header.insert(i + 1, "\\use_package amssymb 2")
988 del document.preamble[j]
991 def revert_use_amssymb(document):
992 "remove use_package amssymb"
993 regexp1 = re.compile(r'(\\use_package\s+amsmath)')
994 regexp2 = re.compile(r'(\\use_package\s+amssymb)')
995 i = find_re(document.header, regexp1, 0)
996 j = find_re(document.header, regexp2, 0)
997 value1 = "1" # default is auto
998 value2 = "1" # default is auto
1000 value1 = get_value(document.header, "\\use_package" , i).split()[1]
1002 value2 = get_value(document.header, "\\use_package" , j).split()[1]
1003 del document.header[j]
1004 if value1 != value2 and value2 == "2": # on
1005 add_to_preamble(document, ["\\usepackage{amssymb}"])
1008 def convert_use_cancel(document):
1009 "insert use_package cancel"
1010 convert_use_package(document, "cancel")
1013 def revert_use_cancel(document):
1014 "remove use_package cancel"
1015 commands = ["cancel", "bcancel", "xcancel", "cancelto"]
1016 revert_use_package(document, "cancel", commands, True)
1019 def revert_ancientgreek(document):
1020 "Set the document language for ancientgreek to greek"
1022 if document.language == "ancientgreek":
1023 document.language = "greek"
1024 i = find_token(document.header, "\\language", 0)
1026 document.header[i] = "\\language greek"
1029 j = find_token(document.body, "\\lang ancientgreek", j)
1033 document.body[j] = document.body[j].replace("\\lang ancientgreek", "\\lang greek")
1037 def revert_languages(document):
1038 "Set the document language for new supported languages to English"
1041 "coptic", "divehi", "hindi", "kurmanji", "lao", "marathi", "occitan", "sanskrit",
1042 "syriac", "tamil", "telugu", "urdu"
1044 for n in range(len(languages)):
1045 if document.language == languages[n]:
1046 document.language = "english"
1047 i = find_token(document.header, "\\language", 0)
1049 document.header[i] = "\\language english"
1051 while j < len(document.body):
1052 j = find_token(document.body, "\\lang " + languages[n], j)
1054 document.body[j] = document.body[j].replace("\\lang " + languages[n], "\\lang english")
1057 j = len(document.body)
1060 def convert_armenian(document):
1061 "Use polyglossia and thus non-TeX fonts for Armenian"
1063 if document.language == "armenian":
1064 i = find_token(document.header, "\\use_non_tex_fonts", 0)
1066 document.header[i] = "\\use_non_tex_fonts true"
1069 def revert_armenian(document):
1070 "Use ArmTeX and thus TeX fonts for Armenian"
1072 if document.language == "armenian":
1073 i = find_token(document.header, "\\use_non_tex_fonts", 0)
1075 document.header[i] = "\\use_non_tex_fonts false"
1078 def revert_libertine(document):
1079 " Revert native libertine font definition to LaTeX "
1081 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1082 i = find_token(document.header, "\\font_roman libertine", 0)
1085 j = find_token(document.header, "\\font_osf true", 0)
1088 preamble = "\\usepackage"
1090 document.header[j] = "\\font_osf false"
1093 preamble += "[lining]"
1094 preamble += "{libertine-type1}"
1095 add_to_preamble(document, [preamble])
1096 document.header[i] = "\\font_roman default"
1099 def revert_txtt(document):
1100 " Revert native txtt font definition to LaTeX "
1102 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1103 i = find_token(document.header, "\\font_typewriter txtt", 0)
1105 preamble = "\\renewcommand{\\ttdefault}{txtt}"
1106 add_to_preamble(document, [preamble])
1107 document.header[i] = "\\font_typewriter default"
1110 def revert_mathdesign(document):
1111 " Revert native mathdesign font definition to LaTeX "
1113 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1119 i = find_token(document.header, "\\font_roman", 0)
1122 val = get_value(document.header, "\\font_roman", i)
1123 if val in mathdesign_dict.keys():
1124 preamble = "\\usepackage[%s" % mathdesign_dict[val]
1126 j = find_token(document.header, "\\font_osf true", 0)
1129 document.header[j] = "\\font_osf false"
1130 l = find_token(document.header, "\\font_sc true", 0)
1133 document.header[l] = "\\font_sc false"
1135 preamble += ",expert"
1136 preamble += "]{mathdesign}"
1137 add_to_preamble(document, [preamble])
1138 document.header[i] = "\\font_roman default"
1141 def revert_texgyre(document):
1142 " Revert native TeXGyre font definition to LaTeX "
1144 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1145 texgyre_fonts = ["tgadventor", "tgbonum", "tgchorus", "tgcursor", \
1146 "tgheros", "tgpagella", "tgschola", "tgtermes"]
1147 i = find_token(document.header, "\\font_roman", 0)
1149 val = get_value(document.header, "\\font_roman", i)
1150 if val in texgyre_fonts:
1151 preamble = "\\usepackage{%s}" % val
1152 add_to_preamble(document, [preamble])
1153 document.header[i] = "\\font_roman default"
1154 i = find_token(document.header, "\\font_sans", 0)
1156 val = get_value(document.header, "\\font_sans", i)
1157 if val in texgyre_fonts:
1158 preamble = "\\usepackage{%s}" % val
1159 add_to_preamble(document, [preamble])
1160 document.header[i] = "\\font_sans default"
1161 i = find_token(document.header, "\\font_typewriter", 0)
1163 val = get_value(document.header, "\\font_typewriter", i)
1164 if val in texgyre_fonts:
1165 preamble = "\\usepackage{%s}" % val
1166 add_to_preamble(document, [preamble])
1167 document.header[i] = "\\font_typewriter default"
1170 def revert_ipadeco(document):
1171 " Revert IPA decorations to ERT "
1174 i = find_token(document.body, "\\begin_inset IPADeco", i)
1177 end = find_end_of_inset(document.body, i)
1179 document.warning("Can't find end of inset at line " + str(i))
1182 line = document.body[i]
1183 rx = re.compile(r'\\begin_inset IPADeco (.*)$')
1185 decotype = m.group(1)
1186 if decotype != "toptiebar" and decotype != "bottomtiebar":
1187 document.warning("Invalid IPADeco type: " + decotype)
1190 blay = find_token(document.body, "\\begin_layout Plain Layout", i, end)
1192 document.warning("Can't find layout for inset at line " + str(i))
1195 bend = find_end_of_layout(document.body, blay)
1197 document.warning("Malformed LyX document: Could not find end of IPADeco inset's layout.")
1200 substi = ["\\begin_inset ERT", "status collapsed", "",
1201 "\\begin_layout Plain Layout", "", "", "\\backslash",
1202 decotype + "{", "\\end_layout", "", "\\end_inset"]
1203 substj = ["\\size default", "", "\\begin_inset ERT", "status collapsed", "",
1204 "\\begin_layout Plain Layout", "", "}", "\\end_layout", "", "\\end_inset"]
1205 # do the later one first so as not to mess up the numbering
1206 document.body[bend:end + 1] = substj
1207 document.body[i:blay + 1] = substi
1208 i = end + len(substi) + len(substj) - (end - bend) - (blay - i) - 2
1209 add_to_preamble(document, "\\usepackage{tipa}")
1212 def revert_ipachar(document):
1213 ' Revert \\IPAChar to ERT '
1216 while i < len(document.body):
1217 m = re.match(r'(.*)\\IPAChar \\(\w+\{\w+\})(.*)', document.body[i])
1221 ipachar = m.group(2)
1224 '\\begin_inset ERT',
1225 'status collapsed', '',
1226 '\\begin_layout Standard',
1227 '', '', '\\backslash',
1232 document.body[i: i+1] = subst
1237 add_to_preamble(document, "\\usepackage{tone}")
1240 def revert_minionpro(document):
1241 " Revert native MinionPro font definition to LaTeX "
1243 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1244 i = find_token(document.header, "\\font_roman minionpro", 0)
1247 j = find_token(document.header, "\\font_osf true", 0)
1250 preamble = "\\usepackage"
1252 document.header[j] = "\\font_osf false"
1255 preamble += "{MinionPro}"
1256 add_to_preamble(document, [preamble])
1257 document.header[i] = "\\font_roman default"
1260 def revert_mathfonts(document):
1261 " Revert native math font definitions to LaTeX "
1263 i = find_token(document.header, "\\font_math", 0)
1266 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1267 val = get_value(document.header, "\\font_math", i)
1268 if val == "eulervm":
1269 add_to_preamble(document, "\\usepackage{eulervm}")
1270 elif val == "default":
1272 "lmodern": "\\renewcommand{\\rmdefault}{lmr}",
1273 "minionpro": "\\usepackage[onlytext,lf]{MinionPro}",
1274 "minionpro-osf": "\\usepackage[onlytext]{MinionPro}",
1275 "palatino": "\\renewcommand{\\rmdefault}{ppl}",
1276 "palatino-osf": "\\renewcommand{\\rmdefault}{pplj}",
1277 "times": "\\renewcommand{\\rmdefault}{ptm}",
1278 "utopia": "\\renewcommand{\\rmdefault}{futs}",
1279 "utopia-osf": "\\renewcommand{\\rmdefault}{futj}",
1281 j = find_token(document.header, "\\font_roman", 0)
1283 rm = get_value(document.header, "\\font_roman", j)
1284 k = find_token(document.header, "\\font_osf true", 0)
1287 if rm in mathfont_dict.keys():
1288 add_to_preamble(document, mathfont_dict[rm])
1289 document.header[j] = "\\font_roman default"
1291 document.header[k] = "\\font_osf false"
1292 del document.header[i]
1295 def revert_mdnomath(document):
1296 " Revert mathdesign and fourier without math "
1298 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1300 "md-charter": "mdbch",
1301 "md-utopia": "mdput",
1302 "md-garamond": "mdugm"
1304 i = find_token(document.header, "\\font_roman", 0)
1307 val = get_value(document.header, "\\font_roman", i)
1308 if val in mathdesign_dict.keys():
1309 j = find_token(document.header, "\\font_math", 0)
1311 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1312 mval = get_value(document.header, "\\font_math", j)
1313 if mval == "default":
1314 document.header[i] = "\\font_roman default"
1315 add_to_preamble(document, "\\renewcommand{\\rmdefault}{%s}" % mathdesign_dict[val])
1317 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1320 def convert_mdnomath(document):
1321 " Change mathdesign font name "
1323 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1325 "mdbch": "md-charter",
1326 "mdput": "md-utopia",
1327 "mdugm": "md-garamond"
1329 i = find_token(document.header, "\\font_roman", 0)
1332 val = get_value(document.header, "\\font_roman", i)
1333 if val in mathdesign_dict.keys():
1334 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1337 def revert_newtxmath(document):
1338 " Revert native newtxmath definitions to LaTeX "
1340 i = find_token(document.header, "\\font_math", 0)
1343 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1344 val = get_value(document.header, "\\font_math", i)
1346 "libertine-ntxm": "\\usepackage[libertine]{newtxmath}",
1347 "minion-ntxm": "\\usepackage[minion]{newtxmath}",
1348 "newtxmath": "\\usepackage{newtxmath}",
1350 if val in mathfont_dict.keys():
1351 add_to_preamble(document, mathfont_dict[val])
1352 document.header[i] = "\\font_math auto"
1355 def revert_biolinum(document):
1356 " Revert native biolinum font definition to LaTeX "
1358 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1359 i = find_token(document.header, "\\font_sans biolinum", 0)
1362 j = find_token(document.header, "\\font_osf true", 0)
1365 preamble = "\\usepackage"
1368 preamble += "{biolinum-type1}"
1369 add_to_preamble(document, [preamble])
1370 document.header[i] = "\\font_sans default"
1373 def revert_uop(document):
1374 " Revert native URW Classico (Optima) font definition to LaTeX "
1376 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1377 i = find_token(document.header, "\\font_sans uop", 0)
1379 preamble = "\\renewcommand{\\sfdefault}{uop}"
1380 add_to_preamble(document, [preamble])
1381 document.header[i] = "\\font_sans default"
1384 def convert_latexargs(document):
1385 " Convert InsetArgument to new syntax "
1387 if find_token(document.body, "\\begin_inset Argument", 0) == -1:
1391 # A list of layouts (document classes) with only optional or no arguments.
1392 # These can be safely converted to the new syntax
1393 # (I took the liberty to add some of my personal layouts/modules here; JSP)
1394 safe_layouts = ["aa", "aapaper", "aastex", "achemso", "acmsiggraph", "AEA",
1395 "agu-dtd", "agums", "agutex", "amsart", "amsbook", "apa",
1396 "arab-article", "armenian-article", "article-beamer", "article",
1397 "beamer", "book", "broadway", "chess", "cl2emult", "ctex-article",
1398 "ctex-book", "ctex-report", "dinbrief", "docbook-book", "docbook-chapter",
1399 "docbook", "docbook-section", "doublecol-new", "dtk", "ectaart", "egs",
1400 "elsarticle", "elsart", "entcs", "europecv", "extarticle", "extbook",
1401 "extletter", "extreport", "foils", "frletter", "g-brief2", "g-brief",
1402 "heb-article", "heb-letter", "hollywood", "IEEEtran", "ijmpc", "ijmpd",
1403 "iopart", "isprs", "jarticle", "jasatex", "jbook", "jgrga", "jreport",
1404 "jsarticle", "jsbeamer", "jsbook", "jss", "kluwer", "latex8", "letter", "lettre",
1405 "literate-article", "literate-book", "literate-report", "llncs", "ltugboat",
1406 "memoir", "moderncv", "mwart", "mwbk", "mwrep", "paper", "powerdot",
1407 "recipebook", "report", "revtex4", "revtex", "scrartcl", "scrarticle-beamer",
1408 "scrbook", "scrlettr", "scrlttr2", "scrreprt", "seminar", "siamltex",
1409 "sigplanconf", "simplecv", "singlecol", "singlecol-new", "slides", "spie",
1410 "svglobal3", "svglobal", "svjog", "svmono", "svmult", "svprobth", "tarticle",
1411 "tbook", "treport", "tufte-book", "tufte-handout"]
1412 # A list of "safe" modules, same as above
1413 safe_modules = ["biblatex", "beameraddons", "beamersession", "braille", "customHeadersFooters",
1414 "endnotes", "enumitem", "eqs-within-sections", "figs-within-sections", "fix-cm",
1415 "fixltx2e", "foottoend", "hanging", "jscharstyles", "knitr", "lilypond",
1416 "linguistics", "linguisticx", "logicalmkup", "minimalistic", "nomindex", "noweb",
1417 "pdfcomment", "sweave", "tabs-within-sections", "theorems-ams-bytype",
1418 "theorems-ams-extended-bytype", "theorems-ams-extended", "theorems-ams", "theorems-bytype",
1419 "theorems-chap-bytype", "theorems-chap", "theorems-named", "theorems-sec-bytype",
1420 "theorems-sec", "theorems-starred", "theorems-std", "todonotes"]
1421 # Modules we need to take care of
1422 caveat_modules = ["initials"]
1423 # information about the relevant styles in caveat_modules (number of opt and req args)
1424 # use this if we get more caveat_modules. For now, use hard coding (see below).
1425 # initials = [{'Layout' : 'Initial', 'opt' : 1, 'req' : 1}]
1427 # Is this a known safe layout?
1428 safe_layout = document.textclass in safe_layouts
1430 document.warning("Lyx2lyx knows nothing about textclass '%s'. "
1431 "Please check if short title insets have been converted correctly."
1432 % document.textclass)
1433 # Do we use unsafe or unknown modules
1434 mods = document.get_module_list()
1435 unknown_modules = False
1436 used_caveat_modules = list()
1438 if mod in safe_modules:
1440 if mod in caveat_modules:
1441 used_caveat_modules.append(mod)
1443 unknown_modules = True
1444 document.warning("Lyx2lyx knows nothing about module '%s'. "
1445 "Please check if short title insets have been converted correctly."
1450 i = find_token(document.body, "\\begin_inset Argument", i)
1454 if not safe_layout or unknown_modules:
1455 # We cannot do more here since we have no access to this layout.
1456 # InsetArgument itself will do the real work
1457 # (see InsetArgument::updateBuffer())
1458 document.body[i] = "\\begin_inset Argument 999"
1462 # Find containing paragraph layout
1463 parent = get_containing_layout(document.body, i)
1465 document.warning("Malformed LyX document: Can't find parent paragraph layout")
1472 if len(used_caveat_modules) > 0:
1473 # We know for now that this must be the initials module with the Initial layout
1474 # If we get more such modules, we need some automating.
1475 if parent[0] == "Initial":
1476 # Layout has 1 opt and 1 req arg.
1477 # Count the actual arguments
1479 for p in range(parbeg, parend):
1480 if document.body[p] == "\\begin_inset Argument":
1485 # Collect all arguments in this paragraph
1487 for p in range(parbeg, parend):
1488 if document.body[p] == "\\begin_inset Argument":
1490 if allowed_opts != -1:
1491 # We have less arguments than opt + required.
1492 # required must take precedence.
1493 if argnr > allowed_opts and argnr < first_req:
1495 document.body[p] = "\\begin_inset Argument %d" % argnr
1499 def revert_latexargs(document):
1500 " Revert InsetArgument to old syntax "
1503 rx = re.compile(r'^\\begin_inset Argument (\d+)$')
1506 # Search for Argument insets
1507 i = find_token(document.body, "\\begin_inset Argument", i)
1510 m = rx.match(document.body[i])
1512 # No ID: inset already reverted
1515 # Find containing paragraph layout
1516 parent = get_containing_layout(document.body, i)
1518 document.warning("Malformed LyX document: Can't find parent paragraph layout")
1523 realparbeg = parent[3]
1524 # Collect all arguments in this paragraph
1526 for p in range(parbeg, parend):
1527 m = rx.match(document.body[p])
1529 val = int(m.group(1))
1530 j = find_end_of_inset(document.body, p)
1531 # Revert to old syntax
1532 document.body[p] = "\\begin_inset Argument"
1534 document.warning("Malformed LyX document: Can't find end of Argument inset")
1537 args[val] = document.body[p : j + 1]
1539 realparend = realparend - len(document.body[p : j + 1])
1540 # Remove arg inset at this position
1541 del document.body[p : j + 1]
1544 # Now sort the arg insets
1546 for f in sorted(args):
1549 # Insert the sorted arg insets at paragraph begin
1550 document.body[realparbeg : realparbeg] = subst
1552 i = realparbeg + 1 + len(subst)
1555 def revert_IEEEtran(document):
1557 Reverts InsetArgument of
1560 Biography without photo
1563 if document.textclass == "IEEEtran":
1570 i = find_token(document.body, "\\begin_layout Page headings", i)
1572 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1575 i2 = find_token(document.body, "\\begin_inset Flex Paragraph Start", i2)
1577 revert_Argument_to_TeX_brace(document, i2, 0, 1, 1, False, False)
1580 j = find_token(document.body, "\\begin_layout Biography without photo", j)
1582 revert_Argument_to_TeX_brace(document, j, 0, 1, 1, True, False)
1585 k = find_token(document.body, "\\begin_layout Biography", k)
1586 kA = find_token(document.body, "\\begin_layout Biography without photo", k)
1587 if k == kA and k != -1:
1591 # start with the second argument, therefore 2
1592 revert_Argument_to_TeX_brace(document, k, 0, 2, 2, True, False)
1594 if i == -1 and i2 == -1 and j == -1 and k == -1:
1598 def revert_IEEEtran_2(document):
1600 Reverts Flex Paragraph Start to TeX-code
1602 if document.textclass == "IEEEtran":
1606 begin = find_token(document.body, "\\begin_inset Flex Paragraph Start", begin)
1608 end1 = find_end_of_inset(document.body, begin)
1609 document.body[end1 - 2 : end1 + 1] = put_cmd_in_ert("}")
1610 document.body[begin : begin + 4] = put_cmd_in_ert("\\IEEEPARstart{")
1616 def convert_IEEEtran(document):
1621 Biography without photo
1624 if document.textclass == "IEEEtran":
1630 i = find_token(document.body, "\\begin_layout Page headings", i)
1632 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1635 j = find_token(document.body, "\\begin_layout Biography without photo", j)
1637 convert_TeX_brace_to_Argument(document, j, 1, 1, False, True)
1640 # assure that we don't handle Biography Biography without photo
1641 k = find_token(document.body, "\\begin_layout Biography", k)
1642 kA = find_token(document.body, "\\begin_layout Biography without photo", k - 1)
1643 if k == kA and k != -1:
1647 # the argument we want to convert is the second one
1648 convert_TeX_brace_to_Argument(document, k, 2, 2, False, True)
1650 if i == -1 and j == -1 and k == -1:
1654 def revert_AASTeX(document):
1655 " Reverts InsetArgument of Altaffilation to TeX-code "
1656 if document.textclass == "aastex":
1660 i = find_token(document.body, "\\begin_layout Altaffilation", i)
1662 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1668 def convert_AASTeX(document):
1669 " Converts ERT of Altaffilation to InsetArgument "
1670 if document.textclass == "aastex":
1674 i = find_token(document.body, "\\begin_layout Altaffilation", i)
1676 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1682 def revert_AGUTeX(document):
1683 " Reverts InsetArgument of Author affiliation to TeX-code "
1684 if document.textclass == "agutex":
1688 i = find_token(document.body, "\\begin_layout Author affiliation", i)
1690 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1696 def convert_AGUTeX(document):
1697 " Converts ERT of Author affiliation to InsetArgument "
1698 if document.textclass == "agutex":
1702 i = find_token(document.body, "\\begin_layout Author affiliation", i)
1704 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1710 def revert_IJMP(document):
1711 " Reverts InsetArgument of MarkBoth to TeX-code "
1712 if document.textclass == "ijmpc" or document.textclass == "ijmpd":
1716 i = find_token(document.body, "\\begin_layout MarkBoth", i)
1718 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1724 def convert_IJMP(document):
1725 " Converts ERT of MarkBoth to InsetArgument "
1726 if document.textclass == "ijmpc" or document.textclass == "ijmpd":
1730 i = find_token(document.body, "\\begin_layout MarkBoth", i)
1732 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1738 def revert_SIGPLAN(document):
1739 " Reverts InsetArguments of SIGPLAN to TeX-code "
1740 if document.textclass == "sigplanconf":
1745 i = find_token(document.body, "\\begin_layout Conference", i)
1747 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1750 j = find_token(document.body, "\\begin_layout Author", j)
1752 revert_Argument_to_TeX_brace(document, j, 0, 1, 2, False, False)
1754 if i == -1 and j == -1:
1758 def convert_SIGPLAN(document):
1759 " Converts ERT of SIGPLAN to InsetArgument "
1760 if document.textclass == "sigplanconf":
1765 i = find_token(document.body, "\\begin_layout Conference", i)
1767 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1770 j = find_token(document.body, "\\begin_layout Author", j)
1772 convert_TeX_brace_to_Argument(document, j, 1, 2, False, False)
1774 if i == -1 and j == -1:
1778 def revert_SIGGRAPH(document):
1779 " Reverts InsetArgument of Flex CRcat to TeX-code "
1780 if document.textclass == "acmsiggraph":
1784 i = find_token(document.body, "\\begin_inset Flex CRcat", i)
1786 revert_Argument_to_TeX_brace(document, i, 0, 1, 3, False, False)
1792 def convert_SIGGRAPH(document):
1793 " Converts ERT of Flex CRcat to InsetArgument "
1794 if document.textclass == "acmsiggraph":
1798 i = find_token(document.body, "\\begin_inset Flex CRcat", i)
1800 convert_TeX_brace_to_Argument(document, i, 1, 3, True, False)
1806 def revert_EuropeCV(document):
1807 " Reverts InsetArguments of europeCV to TeX-code "
1808 if document.textclass == "europecv":
1815 i = find_token(document.body, "\\begin_layout Item", i)
1817 revert_Argument_to_TeX_brace(document, i, 0, 2, 2, False, False)
1820 j = find_token(document.body, "\\begin_layout BulletedItem", j)
1822 revert_Argument_to_TeX_brace(document, j, 0, 2, 2, False, False)
1825 k = find_token(document.body, "\\begin_layout Language", k)
1827 revert_Argument_to_TeX_brace(document, k, 0, 2, 6, False, False)
1830 m = find_token(document.body, "\\begin_layout LastLanguage", m)
1832 revert_Argument_to_TeX_brace(document, m, 0, 2, 6, False, False)
1834 if i == -1 and j == -1 and k == -1 and m == -1:
1838 def convert_EuropeCV(document):
1839 " Converts ERT of europeCV to InsetArgument "
1840 if document.textclass == "europecv":
1847 i = find_token(document.body, "\\begin_layout Item", i)
1849 convert_TeX_brace_to_Argument(document, i, 2, 2, False, False)
1852 j = find_token(document.body, "\\begin_layout BulletedItem", j)
1854 convert_TeX_brace_to_Argument(document, j, 2, 2, False, False)
1857 k = find_token(document.body, "\\begin_layout Language", k)
1859 convert_TeX_brace_to_Argument(document, k, 2, 6, False, False)
1862 m = find_token(document.body, "\\begin_layout LastLanguage", m)
1864 convert_TeX_brace_to_Argument(document, m, 2, 6, False, False)
1866 if i == -1 and j == -1 and k == -1 and m == -1:
1870 def revert_ModernCV(document):
1871 " Reverts InsetArguments of modernCV to TeX-code "
1872 if document.textclass == "moderncv":
1880 j = find_token(document.body, "\\begin_layout Entry", j)
1882 revert_Argument_to_TeX_brace(document, j, 0, 1, 5, False, False)
1885 k = find_token(document.body, "\\begin_layout Item", k)
1887 revert_Argument_to_TeX_brace(document, k, 0, 1, 1, False, False)
1890 m = find_token(document.body, "\\begin_layout ItemWithComment", m)
1892 revert_Argument_to_TeX_brace(document, m, 0, 1, 2, False, False)
1893 document.body[m] = document.body[m].replace("\\begin_layout ItemWithComment", "\\begin_layout Language")
1896 o = find_token(document.body, "\\begin_layout DoubleItem", o)
1898 revert_Argument_to_TeX_brace(document, o, 0, 1, 3, False, False)
1899 document.body[o] = document.body[o].replace("\\begin_layout DoubleItem", "\\begin_layout Computer")
1902 p = find_token(document.body, "\\begin_layout Social", p)
1904 revert_Argument_to_TeX_brace(document, p, 0, 1, 1, False, True)
1906 if j == -1 and k == -1 and m == -1 and o == -1 and p == -1:
1910 def revert_ModernCV_2(document):
1911 " Reverts the Flex:Column inset of modernCV to TeX-code "
1912 if document.textclass == "moderncv":
1917 flex = find_token(document.body, "\\begin_inset Flex Column", flex)
1919 flexEnd = find_end_of_inset(document.body, flex)
1920 wasOpt = revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, False, True)
1921 revert_Argument_to_TeX_brace(document, flex, 0, 2, 2, False, False)
1922 flexEnd = find_end_of_inset(document.body, flex)
1924 document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\cvcolumn")
1926 document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\cvcolumn{")
1927 document.body[flexEnd + 4 : flexEnd + 7] = put_cmd_in_ert("}")
1933 def revert_ModernCV_3(document):
1934 " Reverts the Column style of modernCV to TeX-code "
1935 if document.textclass == "moderncv":
1936 # revert the layouts
1937 revert_ModernCV(document)
1939 # get the position of the end of the last column inset
1940 LastFlexEnd = revert_ModernCV_2(document)
1943 p = find_token(document.body, "\\begin_layout Columns", p)
1945 pEnd = find_end_of_layout(document.body, p)
1946 document.body[p] = document.body[p].replace("\\begin_layout Columns", "\\begin_layout Standard")
1947 if LastFlexEnd != -1:
1948 document.body[p + 1 : p + 1] = put_cmd_in_ert("\\begin{cvcolumns}")
1949 document.body[LastFlexEnd + 24 : LastFlexEnd + 24] = put_cmd_in_ert("\\end{cvcolumns}")
1955 def revert_ModernCV_4(document):
1956 " Reverts the style Social to TeX-code "
1957 if document.textclass == "moderncv":
1958 # revert the layouts
1959 revert_ModernCV(document)
1963 p = find_token(document.body, "\\begin_layout Social", p)
1965 pEnd = find_end_of_layout(document.body, p)
1966 document.body[p] = document.body[p].replace("\\begin_layout Social", "\\begin_layout Standard")
1967 document.body[p + 1 : p + 1] = put_cmd_in_ert("\\social")
1968 hasOpt = find_token(document.body, "[", p + 9)
1970 document.body[p + 30 : p + 30] = put_cmd_in_ert("{")
1971 document.body[p + 41 : p + 41] = put_cmd_in_ert("}")
1973 document.body[p + 11 : p + 11] = put_cmd_in_ert("{")
1974 document.body[p + 21 : p + 21] = put_cmd_in_ert("}")
1980 def convert_ModernCV(document):
1981 " Converts ERT of modernCV to InsetArgument "
1982 if document.textclass == "moderncv":
1990 i = find_token(document.body, "\\begin_layout DoubleItem", i)
1992 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1993 document.body[o] = document.body[o].replace("\\begin_layout DoubleItem", "\\begin_layout DoubleListItem")
1996 j = find_token(document.body, "\\begin_layout Entry", j)
1998 convert_TeX_brace_to_Argument(document, j, 1, 5, False, False)
2001 k = find_token(document.body, "\\begin_layout Item", k)
2003 convert_TeX_brace_to_Argument(document, k, 1, 1, False, False)
2006 m = find_token(document.body, "\\begin_layout Language", m)
2008 convert_TeX_brace_to_Argument(document, m, 1, 2, False, False)
2010 if i == -1 and j == -1 and k == -1 and m == -1:
2014 def revert_Initials(document):
2015 " Reverts InsetArgument of Initial to TeX-code "
2018 i = find_token(document.body, "\\begin_layout Initial", i)
2021 # first arg (optional) and second arg (first mandatory) are supported in LyX 2.0.x
2022 revert_Argument_to_TeX_brace(document, i, 0, 3, 3, False, False)
2026 def convert_Initials(document):
2027 " Converts ERT of Initial to InsetArgument "
2030 i = find_token(document.body, "\\begin_layout Initial", i)
2033 document.warning(str(i))
2034 convert_TeX_brace_to_Argument(document, i, 3, 3, False, False)
2038 def revert_literate(document):
2039 " Revert Literate document to old format "
2040 if del_token(document.header, "noweb", 0):
2041 document.textclass = "literate-" + document.textclass
2044 i = find_token(document.body, "\\begin_layout Chunk", i)
2047 document.body[i] = "\\begin_layout Scrap"
2051 def convert_literate(document):
2052 " Convert Literate document to new format"
2053 i = find_token(document.header, "\\textclass", 0)
2054 if (i != -1) and "literate-" in document.header[i]:
2055 document.textclass = document.header[i].replace("\\textclass literate-", "")
2056 j = find_token(document.header, "\\begin_modules", 0)
2058 document.header.insert(j + 1, "noweb")
2060 document.header.insert(i + 1, "\\end_modules")
2061 document.header.insert(i + 1, "noweb")
2062 document.header.insert(i + 1, "\\begin_modules")
2065 i = find_token(document.body, "\\begin_layout Scrap", i)
2068 document.body[i] = "\\begin_layout Chunk"
2072 def revert_itemargs(document):
2073 " Reverts \\item arguments to TeX-code "
2076 i = find_token(document.body, "\\begin_inset Argument item:", i)
2079 j = find_end_of_inset(document.body, i)
2080 # Find containing paragraph layout
2081 parent = get_containing_layout(document.body, i)
2083 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2087 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2088 endPlain = find_end_of_layout(document.body, beginPlain)
2089 content = document.body[beginPlain + 1 : endPlain]
2090 del document.body[i:j+1]
2091 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2092 document.body[parbeg : parbeg] = subst
2096 def revert_garamondx_newtxmath(document):
2097 " Revert native garamond newtxmath definition to LaTeX "
2099 i = find_token(document.header, "\\font_math", 0)
2102 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
2103 val = get_value(document.header, "\\font_math", i)
2104 if val == "garamondx-ntxm":
2105 add_to_preamble(document, "\\usepackage[garamondx]{newtxmath}")
2106 document.header[i] = "\\font_math auto"
2109 def revert_garamondx(document):
2110 " Revert native garamond font definition to LaTeX "
2112 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
2113 i = find_token(document.header, "\\font_roman garamondx", 0)
2116 j = find_token(document.header, "\\font_osf true", 0)
2119 preamble = "\\usepackage"
2121 preamble += "[osfI]"
2122 preamble += "{garamondx}"
2123 add_to_preamble(document, [preamble])
2124 document.header[i] = "\\font_roman default"
2127 def convert_beamerargs(document):
2128 " Converts beamer arguments to new layout "
2130 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2131 if document.textclass not in beamer_classes:
2134 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
2135 list_layouts = ["Itemize", "Enumerate", "Description"]
2136 rx = re.compile(r'^\\begin_inset Argument (\d+)$')
2140 i = find_token(document.body, "\\begin_inset Argument", i)
2143 # Find containing paragraph layout
2144 parent = get_containing_layout(document.body, i)
2146 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2151 layoutname = parent[0]
2152 for p in range(parbeg, parend):
2153 if layoutname in shifted_layouts:
2154 m = rx.match(document.body[p])
2156 argnr = int(m.group(1))
2158 document.body[p] = "\\begin_inset Argument %d" % argnr
2159 if layoutname == "AgainFrame":
2160 m = rx.match(document.body[p])
2162 document.body[p] = "\\begin_inset Argument 3"
2163 if document.body[p + 4] == "\\begin_inset ERT":
2164 if document.body[p + 9].startswith("<"):
2165 # This is an overlay specification
2167 document.body[p + 9] = document.body[p + 9][1:]
2168 if document.body[p + 9].endswith(">"):
2170 document.body[p + 9] = document.body[p + 9][:-1]
2172 document.body[p] = "\\begin_inset Argument 2"
2173 if layoutname in list_layouts:
2174 m = rx.match(document.body[p])
2176 if m.group(1) == "1":
2177 if document.body[p + 4] == "\\begin_inset ERT":
2178 if document.body[p + 9].startswith("<"):
2179 # This is an overlay specification
2181 document.body[p + 9] = document.body[p + 9][1:]
2182 if document.body[p + 9].endswith(">"):
2184 document.body[p + 9] = document.body[p + 9][:-1]
2185 elif layoutname != "Itemize":
2187 document.body[p] = "\\begin_inset Argument 2"
2191 def convert_againframe_args(document):
2192 " Converts beamer AgainFrame to new layout "
2194 # FIXME: This currently only works if the arguments are in one single ERT
2196 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2197 if document.textclass not in beamer_classes:
2202 i = find_token(document.body, "\\begin_layout AgainFrame", i)
2205 parent = get_containing_layout(document.body, i)
2207 document.warning("Wrong parent layout!")
2211 if document.body[parbeg] == "\\begin_inset ERT":
2212 ertcont = parbeg + 5
2213 if document.body[ertcont].startswith("[<"):
2214 # This is a default overlay specification
2216 document.body[ertcont] = document.body[ertcont][2:]
2217 if document.body[ertcont].endswith(">]"):
2219 document.body[ertcont] = document.body[ertcont][:-2]
2220 elif document.body[ertcont].endswith("]"):
2222 tok = document.body[ertcont].find('>][')
2224 subst = [document.body[ertcont][:tok],
2225 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2226 'status collapsed', '', '\\begin_layout Plain Layout',
2227 document.body[ertcont][tok + 3:-1]]
2228 document.body[ertcont : ertcont + 1] = subst
2229 # Convert to ArgInset
2230 document.body[parbeg] = "\\begin_inset Argument 2"
2233 elif document.body[ertcont].startswith("<"):
2234 # This is an overlay specification
2236 document.body[ertcont] = document.body[ertcont][1:]
2237 if document.body[ertcont].endswith(">"):
2239 document.body[ertcont] = document.body[ertcont][:-1]
2240 # Convert to ArgInset
2241 document.body[parbeg] = "\\begin_inset Argument 1"
2242 elif document.body[ertcont].endswith(">]"):
2244 tok = document.body[ertcont].find('>[<')
2246 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2247 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2248 'status collapsed', '', '\\begin_layout Plain Layout',
2249 document.body[ertcont][tok + 3:-2]]
2250 # Convert to ArgInset
2251 document.body[parbeg] = "\\begin_inset Argument 1"
2252 elif document.body[ertcont].endswith("]"):
2254 tok = document.body[ertcont].find('>[<')
2257 tokk = document.body[ertcont].find('>][')
2259 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2260 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2261 'status collapsed', '', '\\begin_layout Plain Layout',
2262 document.body[ertcont][tok + 3:tokk],
2263 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2264 'status collapsed', '', '\\begin_layout Plain Layout',
2265 document.body[ertcont][tokk + 3:-1]]
2267 tokk = document.body[ertcont].find('>[')
2269 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tokk],
2270 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2271 'status collapsed', '', '\\begin_layout Plain Layout',
2272 document.body[ertcont][tokk + 2:-1]]
2273 # Convert to ArgInset
2274 document.body[parbeg] = "\\begin_inset Argument 1"
2277 elif document.body[ertcont].startswith("["):
2278 # This is an ERT option
2280 document.body[ertcont] = document.body[ertcont][1:]
2281 if document.body[ertcont].endswith("]"):
2283 document.body[ertcont] = document.body[ertcont][:-1]
2284 # Convert to ArgInset
2285 document.body[parbeg] = "\\begin_inset Argument 3"
2291 def convert_corollary_args(document):
2292 " Converts beamer corrolary-style ERT arguments native InsetArgs "
2294 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2295 if document.textclass not in beamer_classes:
2298 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2299 for lay in corollary_layouts:
2302 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2305 parent = get_containing_layout(document.body, i)
2307 document.warning("Wrong parent layout!")
2311 if document.body[parbeg] == "\\begin_inset ERT":
2312 ertcont = parbeg + 5
2313 if document.body[ertcont].startswith("<"):
2314 # This is an overlay specification
2316 document.body[ertcont] = document.body[ertcont][1:]
2317 if document.body[ertcont].endswith(">"):
2319 document.body[ertcont] = document.body[ertcont][:-1]
2320 elif document.body[ertcont].endswith("]"):
2322 tok = document.body[ertcont].find('>[')
2324 subst = [document.body[ertcont][:tok],
2325 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2326 'status collapsed', '', '\\begin_layout Plain Layout',
2327 document.body[ertcont][tok + 2:-1]]
2328 document.body[ertcont : ertcont + 1] = subst
2329 # Convert to ArgInset
2330 document.body[parbeg] = "\\begin_inset Argument 1"
2333 elif document.body[ertcont].startswith("["):
2334 # This is an ERT option
2336 document.body[ertcont] = document.body[ertcont][1:]
2337 if document.body[ertcont].endswith("]"):
2339 document.body[ertcont] = document.body[ertcont][:-1]
2340 # Convert to ArgInset
2341 document.body[parbeg] = "\\begin_inset Argument 2"
2348 def convert_quote_args(document):
2349 " Converts beamer quote style ERT args to native InsetArgs "
2351 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2352 if document.textclass not in beamer_classes:
2355 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2356 for lay in quote_layouts:
2359 i = find_token(document.body, "\\begin_layout " + lay, i)
2362 parent = get_containing_layout(document.body, i)
2364 document.warning("Wrong parent layout!")
2368 if document.body[parbeg] == "\\begin_inset ERT":
2369 if document.body[i + 6].startswith("<"):
2370 # This is an overlay specification
2372 document.body[i + 6] = document.body[i + 6][1:]
2373 if document.body[i + 6].endswith(">"):
2375 document.body[i + 6] = document.body[i + 6][:-1]
2376 # Convert to ArgInset
2377 document.body[i + 1] = "\\begin_inset Argument 1"
2381 def revert_beamerargs(document):
2382 " Reverts beamer arguments to old layout "
2384 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2385 if document.textclass not in beamer_classes:
2389 list_layouts = ["Itemize", "Enumerate", "Description"]
2390 headings = ["Part", "Section", "Section*", "Subsection", "Subsection*",
2391 "Subsubsection", "Subsubsection*", "FrameSubtitle", "NoteItem"]
2392 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2393 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2394 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2397 i = find_token(document.body, "\\begin_inset Argument", i)
2400 # Find containing paragraph layout
2401 parent = get_containing_layout(document.body, i)
2403 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2408 realparbeg = parent[3]
2409 layoutname = parent[0]
2411 for p in range(parbeg, parend):
2415 if layoutname in headings:
2416 m = rx.match(document.body[p])
2420 # Find containing paragraph layout
2421 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2422 endPlain = find_end_of_layout(document.body, beginPlain)
2423 endInset = find_end_of_inset(document.body, p)
2424 argcontent = document.body[beginPlain + 1 : endPlain]
2426 realparend = realparend - len(document.body[p : endInset + 1])
2428 del document.body[p : endInset + 1]
2429 if layoutname == "FrameSubtitle":
2430 pre = put_cmd_in_ert("\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2431 elif layoutname == "NoteItem":
2432 pre = put_cmd_in_ert("\\note<") + argcontent + put_cmd_in_ert(">[item]")
2433 elif layoutname.endswith('*'):
2434 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower()[:-1] + "<") + argcontent + put_cmd_in_ert(">*")
2436 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2437 secarg = find_token(document.body, "\\begin_inset Argument 2", parbeg, parend)
2439 # Find containing paragraph layout
2440 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", secarg)
2441 endPlain = find_end_of_layout(document.body, beginPlain)
2442 endInset = find_end_of_inset(document.body, secarg)
2443 argcontent = document.body[beginPlain + 1 : endPlain]
2445 realparend = realparend - len(document.body[secarg : endInset + 1])
2446 del document.body[secarg : endInset + 1]
2447 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2448 pre += put_cmd_in_ert("{")
2449 document.body[parbeg] = "\\begin_layout Standard"
2450 document.body[realparbeg : realparbeg] = pre
2451 pe = find_end_of_layout(document.body, parbeg)
2452 post = put_cmd_in_ert("}")
2453 document.body[pe : pe] = post
2454 realparend += len(pre) + len(post)
2455 if layoutname == "AgainFrame":
2456 m = rx.match(document.body[p])
2460 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2461 endPlain = find_end_of_layout(document.body, beginPlain)
2462 endInset = find_end_of_inset(document.body, p)
2463 content = document.body[beginPlain + 1 : endPlain]
2465 realparend = realparend - len(document.body[p : endInset + 1])
2467 del document.body[p : endInset + 1]
2468 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2469 document.body[realparbeg : realparbeg] = subst
2470 if layoutname == "Overprint":
2471 m = rx.match(document.body[p])
2475 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2476 endPlain = find_end_of_layout(document.body, beginPlain)
2477 endInset = find_end_of_inset(document.body, p)
2478 content = document.body[beginPlain + 1 : endPlain]
2480 realparend = realparend - len(document.body[p : endInset + 1])
2482 del document.body[p : endInset + 1]
2483 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2484 document.body[realparbeg : realparbeg] = subst
2485 if layoutname == "OverlayArea":
2486 m = rx.match(document.body[p])
2490 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2491 endPlain = find_end_of_layout(document.body, beginPlain)
2492 endInset = find_end_of_inset(document.body, p)
2493 content = document.body[beginPlain + 1 : endPlain]
2495 realparend = realparend - len(document.body[p : endInset + 1])
2497 del document.body[p : endInset + 1]
2498 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2499 document.body[realparbeg : realparbeg] = subst
2500 if layoutname in list_layouts:
2501 m = rx.match(document.body[p])
2505 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2506 endPlain = find_end_of_layout(document.body, beginPlain)
2507 endInset = find_end_of_inset(document.body, p)
2508 content = document.body[beginPlain + 1 : endPlain]
2509 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2510 realparend = realparend + len(subst) - len(content)
2511 document.body[beginPlain + 1 : endPlain] = subst
2512 elif argnr == "item:1":
2513 j = find_end_of_inset(document.body, i)
2514 # Find containing paragraph layout
2515 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2516 endPlain = find_end_of_layout(document.body, beginPlain)
2517 content = document.body[beginPlain + 1 : endPlain]
2518 del document.body[i:j+1]
2519 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2520 document.body[realparbeg : realparbeg] = subst
2521 elif argnr == "item:2":
2522 j = find_end_of_inset(document.body, i)
2523 # Find containing paragraph layout
2524 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2525 endPlain = find_end_of_layout(document.body, beginPlain)
2526 content = document.body[beginPlain + 1 : endPlain]
2527 del document.body[i:j+1]
2528 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2529 document.body[realparbeg : realparbeg] = subst
2530 if layoutname in quote_layouts:
2531 m = rx.match(document.body[p])
2535 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2536 endPlain = find_end_of_layout(document.body, beginPlain)
2537 endInset = find_end_of_inset(document.body, p)
2538 content = document.body[beginPlain + 1 : endPlain]
2540 realparend = realparend - len(document.body[p : endInset + 1])
2542 del document.body[p : endInset + 1]
2543 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2544 document.body[realparbeg : realparbeg] = subst
2545 if layoutname in corollary_layouts:
2546 m = rx.match(document.body[p])
2550 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2551 endPlain = find_end_of_layout(document.body, beginPlain)
2552 endInset = find_end_of_inset(document.body, p)
2553 content = document.body[beginPlain + 1 : endPlain]
2555 realparend = realparend - len(document.body[p : endInset + 1])
2557 del document.body[p : endInset + 1]
2558 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2559 document.body[realparbeg : realparbeg] = subst
2564 def revert_beamerargs2(document):
2565 " Reverts beamer arguments to old layout, step 2 "
2567 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2568 if document.textclass not in beamer_classes:
2572 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
2573 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2574 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2577 i = find_token(document.body, "\\begin_inset Argument", i)
2580 # Find containing paragraph layout
2581 parent = get_containing_layout(document.body, i)
2583 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2588 realparbeg = parent[3]
2589 layoutname = parent[0]
2591 for p in range(parbeg, parend):
2595 if layoutname in shifted_layouts:
2596 m = rx.match(document.body[p])
2600 document.body[p] = "\\begin_inset Argument 1"
2601 if layoutname in corollary_layouts:
2602 m = rx.match(document.body[p])
2606 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2607 endPlain = find_end_of_layout(document.body, beginPlain)
2608 endInset = find_end_of_inset(document.body, p)
2609 content = document.body[beginPlain + 1 : endPlain]
2611 realparend = realparend - len(document.body[p : endInset + 1])
2613 del document.body[p : endInset + 1]
2614 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2615 document.body[realparbeg : realparbeg] = subst
2616 if layoutname == "OverlayArea":
2617 m = rx.match(document.body[p])
2621 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2622 endPlain = find_end_of_layout(document.body, beginPlain)
2623 endInset = find_end_of_inset(document.body, p)
2624 content = document.body[beginPlain + 1 : endPlain]
2626 realparend = realparend - len(document.body[p : endInset + 1])
2628 del document.body[p : endInset + 1]
2629 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2630 document.body[realparbeg : realparbeg] = subst
2631 if layoutname == "AgainFrame":
2632 m = rx.match(document.body[p])
2636 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2637 endPlain = find_end_of_layout(document.body, beginPlain)
2638 endInset = find_end_of_inset(document.body, p)
2639 content = document.body[beginPlain + 1 : endPlain]
2641 realparend = realparend - len(document.body[p : endInset + 1])
2643 del document.body[p : endInset + 1]
2644 subst = put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
2645 document.body[realparbeg : realparbeg] = subst
2649 def revert_beamerargs3(document):
2650 " Reverts beamer arguments to old layout, step 3 "
2652 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2653 if document.textclass not in beamer_classes:
2656 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2659 i = find_token(document.body, "\\begin_inset Argument", i)
2662 # Find containing paragraph layout
2663 parent = get_containing_layout(document.body, i)
2665 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2670 realparbeg = parent[3]
2671 layoutname = parent[0]
2673 for p in range(parbeg, parend):
2677 if layoutname == "AgainFrame":
2678 m = rx.match(document.body[p])
2682 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2683 endPlain = find_end_of_layout(document.body, beginPlain)
2684 endInset = find_end_of_inset(document.body, p)
2685 content = document.body[beginPlain + 1 : endPlain]
2687 realparend = realparend - len(document.body[p : endInset + 1])
2689 del document.body[p : endInset + 1]
2690 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2691 document.body[realparbeg : realparbeg] = subst
2695 def revert_beamerflex(document):
2696 " Reverts beamer Flex insets "
2698 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2699 if document.textclass not in beamer_classes:
2702 new_flexes = {"Bold" : "\\textbf", "Emphasize" : "\\emph", "Only" : "\\only",
2703 "Uncover" : "\\uncover", "Visible" : "\\visible",
2704 "Invisible" : "\\invisible", "Alternative" : "\\alt",
2705 "Beamer_Note" : "\\note"}
2706 old_flexes = {"Alert" : "\\alert", "Structure" : "\\structure"}
2707 rx = re.compile(r'^\\begin_inset Flex (.+)$')
2711 i = find_token(document.body, "\\begin_inset Flex", i)
2714 m = rx.match(document.body[i])
2716 flextype = m.group(1)
2717 z = find_end_of_inset(document.body, i)
2719 document.warning("Can't find end of Flex " + flextype + " inset.")
2722 if flextype in new_flexes:
2723 pre = put_cmd_in_ert(new_flexes[flextype])
2724 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2726 argend = find_end_of_inset(document.body, arg)
2728 document.warning("Can't find end of Argument!")
2731 # Find containing paragraph layout
2732 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2733 endPlain = find_end_of_layout(document.body, beginPlain)
2734 argcontent = document.body[beginPlain + 1 : endPlain]
2736 z = z - len(document.body[arg : argend + 1])
2738 del document.body[arg : argend + 1]
2739 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2740 arg = find_token(document.body, "\\begin_inset Argument 2", i, z)
2742 argend = find_end_of_inset(document.body, arg)
2744 document.warning("Can't find end of Argument!")
2747 # Find containing paragraph layout
2748 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2749 endPlain = find_end_of_layout(document.body, beginPlain)
2750 argcontent = document.body[beginPlain + 1 : endPlain]
2752 z = z - len(document.body[arg : argend + 1])
2754 del document.body[arg : argend + 1]
2755 if flextype == "Alternative":
2756 pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
2758 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2759 pre += put_cmd_in_ert("{")
2760 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2761 endPlain = find_end_of_layout(document.body, beginPlain)
2763 z = z - len(document.body[i : beginPlain + 1])
2765 document.body[i : beginPlain + 1] = pre
2766 post = put_cmd_in_ert("}")
2767 document.body[z - 2 : z + 1] = post
2768 elif flextype in old_flexes:
2769 pre = put_cmd_in_ert(old_flexes[flextype])
2770 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2774 argend = find_end_of_inset(document.body, arg)
2776 document.warning("Can't find end of Argument!")
2779 # Find containing paragraph layout
2780 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2781 endPlain = find_end_of_layout(document.body, beginPlain)
2782 argcontent = document.body[beginPlain + 1 : endPlain]
2784 z = z - len(document.body[arg : argend + 1])
2786 del document.body[arg : argend + 1]
2787 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2788 pre += put_cmd_in_ert("{")
2789 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2790 endPlain = find_end_of_layout(document.body, beginPlain)
2792 z = z - len(document.body[i : beginPlain + 1])
2794 document.body[i : beginPlain + 1] = pre
2795 post = put_cmd_in_ert("}")
2796 document.body[z - 2 : z + 1] = post
2801 def revert_beamerblocks(document):
2802 " Reverts beamer block arguments to ERT "
2804 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2805 if document.textclass not in beamer_classes:
2808 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2810 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2813 i = find_token(document.body, "\\begin_inset Argument", i)
2816 # Find containing paragraph layout
2817 parent = get_containing_layout(document.body, i)
2819 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2824 realparbeg = parent[3]
2825 layoutname = parent[0]
2827 for p in range(parbeg, parend):
2831 if layoutname in blocks:
2832 m = rx.match(document.body[p])
2836 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2837 endPlain = find_end_of_layout(document.body, beginPlain)
2838 endInset = find_end_of_inset(document.body, p)
2839 content = document.body[beginPlain + 1 : endPlain]
2841 realparend = realparend - len(document.body[p : endInset + 1])
2843 del document.body[p : endInset + 1]
2844 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2845 document.body[realparbeg : realparbeg] = subst
2847 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2848 endPlain = find_end_of_layout(document.body, beginPlain)
2849 endInset = find_end_of_inset(document.body, p)
2850 content = document.body[beginPlain + 1 : endPlain]
2852 realparend = realparend - len(document.body[p : endInset + 1])
2854 del document.body[p : endInset + 1]
2855 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2856 document.body[realparbeg : realparbeg] = subst
2861 def convert_beamerblocks(document):
2862 " Converts beamer block ERT args to native InsetArgs "
2864 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2865 if document.textclass not in beamer_classes:
2868 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2872 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2875 parent = get_containing_layout(document.body, i)
2876 if parent == False or parent[1] != i:
2877 document.warning("Wrong parent layout!")
2883 if document.body[parbeg] == "\\begin_inset ERT":
2884 ertcont = parbeg + 5
2886 if document.body[ertcont].startswith("<"):
2887 # This is an overlay specification
2889 document.body[ertcont] = document.body[ertcont][1:]
2890 if document.body[ertcont].endswith(">"):
2892 document.body[ertcont] = document.body[ertcont][:-1]
2893 # Convert to ArgInset
2894 document.body[parbeg] = "\\begin_inset Argument 1"
2895 elif document.body[ertcont].endswith("}"):
2897 tok = document.body[ertcont].find('>{')
2899 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2900 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2901 'status collapsed', '', '\\begin_layout Plain Layout',
2902 document.body[ertcont][tok + 2:-1]]
2903 # Convert to ArgInset
2904 document.body[parbeg] = "\\begin_inset Argument 1"
2905 elif document.body[ertcont].startswith("{"):
2906 # This is the block title
2907 if document.body[ertcont].endswith("}"):
2908 # strip off the braces
2909 document.body[ertcont] = document.body[ertcont][1:-1]
2910 # Convert to ArgInset
2911 document.body[parbeg] = "\\begin_inset Argument 2"
2912 elif count_pars_in_inset(document.body, ertcont) > 1:
2913 # Multipar ERT. Skip this.
2916 convert_TeX_brace_to_Argument(document, i, 2, 2, False, True)
2919 j = find_end_of_layout(document.body, i)
2921 document.warning("end of layout not found!")
2922 k = find_token(document.body, "\\begin_inset Argument", i, j)
2924 document.warning("InsetArgument not found!")
2926 l = find_end_of_inset(document.body, k)
2927 m = find_token(document.body, "\\begin_inset ERT", l, j)
2935 def convert_overprint(document):
2936 " Convert old beamer overprint layouts to ERT "
2938 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2939 if document.textclass not in beamer_classes:
2944 i = find_token(document.body, "\\begin_layout Overprint", i)
2947 # Find end of sequence
2948 j = find_end_of_sequence(document.body, i)
2950 document.warning("Malformed LyX document. Cannot find end of Overprint sequence!")
2954 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
2956 if document.body[j] == "\\end_deeper":
2957 esubst = ["", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
2959 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
2960 endseq = endseq + len(esubst) - len(document.body[j : j])
2961 document.body[j : j] = esubst
2962 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
2964 argend = find_end_of_layout(document.body, argbeg)
2966 document.warning("Malformed LyX document. Cannot find end of Overprint argument!")
2969 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
2970 endPlain = find_end_of_layout(document.body, beginPlain)
2971 content = document.body[beginPlain + 1 : endPlain]
2973 endseq = endseq - len(document.body[argbeg : argend + 1])
2975 del document.body[argbeg : argend + 1]
2976 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2978 endseq = endseq - len(document.body[i : i])
2979 document.body[i : i] = subst + ["\\end_layout"]
2980 endseq += len(subst)
2982 for p in range(i, endseq):
2983 if document.body[p] == "\\begin_layout Overprint":
2984 document.body[p] = "\\begin_layout Standard"
2989 def revert_overprint(document):
2990 " Revert old beamer overprint layouts to ERT "
2992 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2993 if document.textclass not in beamer_classes:
2998 i = find_token(document.body, "\\begin_layout Overprint", i)
3001 # Find end of sequence
3002 j = find_end_of_sequence(document.body, i)
3004 document.warning("Malformed LyX document. Cannot find end of Overprint sequence!")
3008 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
3009 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}")
3010 endseq = endseq + len(esubst) - len(document.body[j : j])
3011 if document.body[j] == "\\end_deeper":
3012 document.body[j : j] = ["\\end_deeper", ""] + esubst
3014 document.body[j : j] = esubst
3017 if document.body[r] == "\\begin_deeper":
3018 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3020 document.body[r] = ""
3021 document.body[s] = ""
3025 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
3027 argend = find_end_of_inset(document.body, argbeg)
3029 document.warning("Malformed LyX document. Cannot find end of Overprint argument!")
3032 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3033 endPlain = find_end_of_layout(document.body, beginPlain)
3034 content = document.body[beginPlain + 1 : endPlain]
3036 endseq = endseq - len(document.body[argbeg : argend])
3038 del document.body[argbeg : argend + 1]
3039 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3041 endseq = endseq - len(document.body[i : i])
3042 document.body[i : i] = subst + ["\\end_layout"]
3043 endseq += len(subst)
3049 if document.body[p] == "\\begin_layout Overprint":
3050 q = find_end_of_layout(document.body, p)
3052 document.warning("Malformed LyX document. Cannot find end of Overprint layout!")
3055 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\onslide")
3056 argbeg = find_token(document.body, "\\begin_inset Argument item:1", p, q)
3058 argend = find_end_of_inset(document.body, argbeg)
3060 document.warning("Malformed LyX document. Cannot find end of Overprint item argument!")
3063 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3064 endPlain = find_end_of_layout(document.body, beginPlain)
3065 content = document.body[beginPlain + 1 : endPlain]
3067 endseq = endseq - len(document.body[argbeg : argend + 1])
3069 del document.body[argbeg : argend + 1]
3070 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3071 endseq = endseq - len(document.body[p : p + 1]) + len(subst)
3072 document.body[p : p + 1] = subst
3078 def revert_frametitle(document):
3079 " Reverts beamer frametitle layout to ERT "
3081 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3082 if document.textclass not in beamer_classes:
3085 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
3088 i = find_token(document.body, "\\begin_layout FrameTitle", i)
3091 j = find_end_of_layout(document.body, i)
3093 document.warning("Malformed LyX document: Can't find end of FrameTitle layout")
3097 document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
3098 endlay += len(put_cmd_in_ert("}"))
3099 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\frametitle")
3100 for p in range(i, j):
3103 m = rx.match(document.body[p])
3107 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3108 endPlain = find_end_of_layout(document.body, beginPlain)
3109 endInset = find_end_of_inset(document.body, p)
3110 content = document.body[beginPlain + 1 : endPlain]
3112 endlay = endlay - len(document.body[p : endInset + 1])
3114 del document.body[p : endInset + 1]
3115 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3117 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3118 endPlain = find_end_of_layout(document.body, beginPlain)
3119 endInset = find_end_of_inset(document.body, p)
3120 content = document.body[beginPlain + 1 : endPlain]
3122 endlay = endlay - len(document.body[p : endInset + 1])
3124 del document.body[p : endInset + 1]
3125 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3127 subst += put_cmd_in_ert("{")
3128 document.body[i : i + 1] = subst
3132 def convert_epigraph(document):
3133 " Converts memoir epigraph to new syntax "
3135 if document.textclass != "memoir":
3140 i = find_token(document.body, "\\begin_layout Epigraph", i)
3143 j = find_end_of_layout(document.body, i)
3145 document.warning("Malformed LyX document: Can't find end of Epigraph layout")
3150 ert = find_token(document.body, "\\begin_inset ERT", i, j)
3152 endInset = find_end_of_inset(document.body, ert)
3153 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", ert)
3154 endPlain = find_end_of_layout(document.body, beginPlain)
3155 ertcont = beginPlain + 2
3156 if document.body[ertcont] == "}{":
3158 # Convert to ArgInset
3159 endlay = endlay - 2 * len(document.body[j])
3160 begsubst = ['\\begin_inset Argument post:1', 'status collapsed', '',
3161 '\\begin_layout Plain Layout']
3162 endsubst = ['\\end_layout', '', '\\end_inset', '', document.body[j]]
3163 document.body[j : j + 1] = endsubst
3164 document.body[endInset + 1 : endInset + 1] = begsubst
3166 endlay += len(begsubst) + len(endsubst)
3167 endlay = endlay - len(document.body[ert : endInset + 1])
3168 del document.body[ert : endInset + 1]
3173 def revert_epigraph(document):
3174 " Reverts memoir epigraph argument to ERT "
3176 if document.textclass != "memoir":
3181 i = find_token(document.body, "\\begin_layout Epigraph", i)
3184 j = find_end_of_layout(document.body, i)
3186 document.warning("Malformed LyX document: Can't find end of Epigraph layout")
3191 p = find_token(document.body, "\\begin_layout Argument post:1", i, j)
3193 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3194 endPlain = find_end_of_layout(document.body, beginPlain)
3195 endInset = find_end_of_inset(document.body, p)
3196 content = document.body[beginPlain + 1 : endPlain]
3198 endlay = endlay - len(document.body[p : endInset + 1])
3200 del document.body[p : endInset + 1]
3201 subst += put_cmd_in_ert("}{") + content
3203 subst += put_cmd_in_ert("}{")
3205 document.body[j : j] = subst + document.body[j : j]
3209 def convert_captioninsets(document):
3210 " Converts caption insets to new syntax "
3214 i = find_token(document.body, "\\begin_inset Caption", i)
3217 document.body[i] = "\\begin_inset Caption Standard"
3221 def revert_captioninsets(document):
3222 " Reverts caption insets to old syntax "
3226 i = find_token(document.body, "\\begin_inset Caption Standard", i)
3229 document.body[i] = "\\begin_inset Caption"
3233 def convert_captionlayouts(document):
3234 " Convert caption layouts to caption insets. "
3237 "Captionabove": "Above",
3238 "Captionbelow": "Below",
3239 "FigCaption" : "FigCaption",
3240 "Table_Caption" : "Table",
3241 "CenteredCaption" : "Centered",
3242 "Bicaption" : "Bicaption",
3247 i = find_token(document.body, "\\begin_layout", i)
3250 val = get_value(document.body, "\\begin_layout", i)
3251 if val in caption_dict.keys():
3252 j = find_end_of_layout(document.body, i)
3254 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3257 document.body[j:j] = ["\\end_layout", "", "\\end_inset", "", ""]
3258 document.body[i:i+1] = ["\\begin_layout %s" % document.default_layout,
3259 "\\begin_inset Caption %s" % caption_dict[val], "",
3260 "\\begin_layout %s" % document.default_layout]
3264 def revert_captionlayouts(document):
3265 " Revert caption insets to caption layouts. "
3268 "Above" : "Captionabove",
3269 "Below" : "Captionbelow",
3270 "FigCaption" : "FigCaption",
3271 "Table" : "Table_Caption",
3272 "Centered" : "CenteredCaption",
3273 "Bicaption" : "Bicaption",
3277 rx = re.compile(r'^\\begin_inset Caption (\S+)$')
3279 i = find_token(document.body, "\\begin_inset Caption", i)
3283 m = rx.match(document.body[i])
3287 if val not in caption_dict.keys():
3291 # We either need to delete the previous \begin_layout line, or we
3292 # need to end the previous layout if this inset is not in the first
3293 # position of the paragraph.
3294 layout_before = find_token_backwards(document.body, "\\begin_layout", i)
3295 if layout_before == -1:
3296 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3298 layout_line = document.body[layout_before]
3299 del_layout_before = True
3300 l = layout_before + 1
3302 if document.body[l] != "":
3303 del_layout_before = False
3306 if del_layout_before:
3307 del document.body[layout_before:i]
3310 document.body[i:i] = ["\\end_layout", ""]
3313 # Find start of layout in the inset and end of inset
3314 j = find_token(document.body, "\\begin_layout", i)
3316 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3318 k = find_end_of_inset(document.body, i)
3320 document.warning("Malformed LyX document: Missing `\\end_inset'.")
3323 # We either need to delete the following \end_layout line, or we need
3324 # to restart the old layout if this inset is not at the paragraph end.
3325 layout_after = find_token(document.body, "\\end_layout", k)
3326 if layout_after == -1:
3327 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3329 del_layout_after = True
3331 while l < layout_after:
3332 if document.body[l] != "":
3333 del_layout_after = False
3336 if del_layout_after:
3337 del document.body[k+1:layout_after+1]
3339 document.body[k+1:k+1] = [layout_line, ""]
3341 # delete \begin_layout and \end_inset and replace \begin_inset with
3342 # "\begin_layout XXX". This works because we can only have one
3343 # paragraph in the caption inset: The old \end_layout will be recycled.
3344 del document.body[k]
3345 if document.body[k] == "":
3346 del document.body[k]
3347 del document.body[j]
3348 if document.body[j] == "":
3349 del document.body[j]
3350 document.body[i] = "\\begin_layout %s" % caption_dict[val]
3351 if document.body[i+1] == "":
3352 del document.body[i+1]
3356 def revert_fragileframe(document):
3357 " Reverts beamer FragileFrame layout to ERT "
3359 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3360 if document.textclass not in beamer_classes:
3365 i = find_token(document.body, "\\begin_layout FragileFrame", i)
3368 # Find end of sequence
3369 j = find_end_of_sequence(document.body, i)
3371 document.warning("Malformed LyX document. Cannot find end of FragileFrame sequence!")
3375 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{frame}")
3376 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{frame}")
3377 endseq = endseq + len(esubst) - len(document.body[j : j])
3378 if document.body[j] == "\\end_deeper":
3379 document.body[j : j] = ["\\end_deeper", ""] + esubst
3381 document.body[j : j] = esubst
3382 for q in range(i, j):
3383 if document.body[q] == "\\begin_layout FragileFrame":
3384 document.body[q] = "\\begin_layout %s" % document.default_layout
3387 if document.body[r] == "\\begin_deeper":
3388 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3390 document.body[r] = ""
3391 document.body[s] = ""
3395 for p in range(1, 5):
3396 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, j)
3399 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3400 endPlain = find_end_of_layout(document.body, beginPlain)
3401 endInset = find_end_of_inset(document.body, arg)
3402 content = document.body[beginPlain + 1 : endPlain]
3404 j = j - len(document.body[arg : endInset + 1])
3406 del document.body[arg : endInset + 1]
3407 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3409 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3410 endPlain = find_end_of_layout(document.body, beginPlain)
3411 endInset = find_end_of_inset(document.body, arg)
3412 content = document.body[beginPlain + 1 : endPlain]
3414 j = j - len(document.body[arg : endInset + 1])
3416 del document.body[arg : endInset + 1]
3417 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3419 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3420 endPlain = find_end_of_layout(document.body, beginPlain)
3421 endInset = find_end_of_inset(document.body, arg)
3422 content = document.body[beginPlain + 1 : endPlain]
3424 j = j - len(document.body[arg : endInset + 1])
3426 del document.body[arg : endInset + 1]
3427 subst += put_cmd_in_ert("[fragile,") + content + put_cmd_in_ert("]")
3429 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3430 endPlain = find_end_of_layout(document.body, beginPlain)
3431 endInset = find_end_of_inset(document.body, arg)
3432 content = document.body[beginPlain + 1 : endPlain]
3434 j = j - len(document.body[arg : endInset + 1])
3436 del document.body[arg : endInset + 1]
3437 subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
3439 subst += put_cmd_in_ert("[fragile]")
3441 document.body[i : i + 1] = subst
3445 def revert_newframes(document):
3446 " Reverts beamer Frame and PlainFrame layouts to old forms "
3448 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3449 if document.textclass not in beamer_classes:
3453 "Frame" : "BeginFrame",
3454 "PlainFrame" : "BeginPlainFrame",
3457 rx = re.compile(r'^\\begin_layout (\S+)$')
3460 i = find_token(document.body, "\\begin_layout", i)
3464 m = rx.match(document.body[i])
3468 if val not in frame_dict.keys():
3471 # Find end of sequence
3472 j = find_end_of_sequence(document.body, i)
3474 document.warning("Malformed LyX document. Cannot find end of Frame sequence!")
3478 subst = ["\\begin_layout %s" % frame_dict[val]]
3479 esubst = ["\\end_layout", "", "\\begin_layout EndFrame", "", "\\end_layout"]
3480 endseq = endseq + len(esubst) - len(document.body[j : j])
3481 if document.body[j] == "\\end_deeper":
3482 document.body[j : j] = ["\\end_deeper", ""] + esubst
3484 document.body[j : j] = esubst
3485 for q in range(i, j):
3486 if document.body[q] == "\\begin_layout %s" % val:
3487 document.body[q] = "\\begin_layout %s" % document.default_layout
3490 if document.body[r] == "\\begin_deeper":
3491 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3493 document.body[r] = ""
3494 document.body[s] = ""
3498 l = find_end_of_layout(document.body, i)
3499 for p in range(1, 5):
3500 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, l)
3503 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3504 endPlain = find_end_of_layout(document.body, beginPlain)
3505 endInset = find_end_of_inset(document.body, arg)
3506 content = document.body[beginPlain + 1 : endPlain]
3508 l = l - len(document.body[arg : endInset + 1])
3510 del document.body[arg : endInset + 1]
3511 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3513 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3514 endPlain = find_end_of_layout(document.body, beginPlain)
3515 endInset = find_end_of_inset(document.body, arg)
3516 content = document.body[beginPlain + 1 : endPlain]
3518 l = l - len(document.body[arg : endInset + 1])
3520 del document.body[arg : endInset + 1]
3521 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3523 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3524 endPlain = find_end_of_layout(document.body, beginPlain)
3525 endInset = find_end_of_inset(document.body, arg)
3526 content = document.body[beginPlain + 1 : endPlain]
3528 l = l - len(document.body[arg : endInset + 1])
3530 del document.body[arg : endInset + 1]
3531 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3533 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3534 endPlain = find_end_of_layout(document.body, beginPlain)
3535 endInset = find_end_of_inset(document.body, arg)
3536 content = document.body[beginPlain + 1 : endPlain]
3538 l = l - len(document.body[arg : endInset + 1])
3540 del document.body[arg : endInset + 1]
3543 document.body[i : i + 1] = subst
3546 # known encodings that do not change their names (same LyX and LaTeX names)
3547 known_enc_tuple = ("auto", "default", "ansinew", "applemac", "armscii8", "ascii",
3548 "cp437", "cp437de", "cp850", "cp852", "cp855", "cp858", "cp862", "cp865", "cp866",
3549 "cp1250", "cp1251", "cp1252", "cp1255", "cp1256", "cp1257", "koi8-r", "koi8-u",
3550 "pt154", "pt254", "tis620-0", "utf8", "utf8x", "utf8-plain")
3552 def convert_encodings(document):
3553 "Use the LyX names of the encodings instead of the LaTeX names."
3554 LaTeX2LyX_enc_dict = {
3555 "8859-6": "iso8859-6",
3556 "8859-8": "iso8859-8",
3558 "euc": "euc-jp-platex",
3563 "iso88595": "iso8859-5",
3564 "iso-8859-7": "iso8859-7",
3566 "jis": "jis-platex",
3568 "l7xenc": "iso8859-13",
3569 "latin1": "iso8859-1",
3570 "latin2": "iso8859-2",
3571 "latin3": "iso8859-3",
3572 "latin4": "iso8859-4",
3573 "latin5": "iso8859-9",
3574 "latin9": "iso8859-15",
3575 "latin10": "iso8859-16",
3576 "SJIS": "shift-jis",
3577 "sjis": "shift-jis-platex",
3580 i = find_token(document.header, "\\inputencoding" , 0)
3583 val = get_value(document.header, "\\inputencoding", i)
3584 if val in LaTeX2LyX_enc_dict.keys():
3585 document.header[i] = "\\inputencoding %s" % LaTeX2LyX_enc_dict[val]
3586 elif val not in known_enc_tuple:
3587 document.warning("Ignoring unknown input encoding: `%s'" % val)
3590 def revert_encodings(document):
3591 """Revert to using the LaTeX names of the encodings instead of the LyX names.
3592 Also revert utf8-platex to sjis, the language default when using Japanese.
3594 LyX2LaTeX_enc_dict = {
3599 "euc-jp-platex": "euc",
3602 "iso8859-1": "latin1",
3603 "iso8859-2": "latin2",
3604 "iso8859-3": "latin3",
3605 "iso8859-4": "latin4",
3606 "iso8859-5": "iso88595",
3607 "iso8859-6": "8859-6",
3608 "iso8859-7": "iso-8859-7",
3609 "iso8859-8": "8859-8",
3610 "iso8859-9": "latin5",
3611 "iso8859-13": "l7xenc",
3612 "iso8859-15": "latin9",
3613 "iso8859-16": "latin10",
3615 "jis-platex": "jis",
3616 "shift-jis": "SJIS",
3617 "shift-jis-platex": "sjis",
3619 "utf8-platex": "sjis"
3621 i = find_token(document.header, "\\inputencoding" , 0)
3624 val = get_value(document.header, "\\inputencoding", i)
3625 if val in LyX2LaTeX_enc_dict.keys():
3626 document.header[i] = "\\inputencoding %s" % LyX2LaTeX_enc_dict[val]
3627 elif val not in known_enc_tuple:
3628 document.warning("Ignoring unknown input encoding: `%s'" % val)
3631 def revert_IEEEtran_3(document):
3633 Reverts Flex Insets to TeX-code
3635 if document.textclass == "IEEEtran":
3641 h = find_token(document.body, "\\begin_inset Flex Author Mark", h)
3643 endh = find_end_of_inset(document.body, h)
3644 document.body[endh - 2 : endh + 1] = put_cmd_in_ert("}")
3645 document.body[h : h + 4] = put_cmd_in_ert("\\IEEEauthorrefmark{")
3648 i = find_token(document.body, "\\begin_inset Flex Author Name", i)
3650 endi = find_end_of_inset(document.body, i)
3651 document.body[endi - 2 : endi + 1] = put_cmd_in_ert("}")
3652 document.body[i : i + 4] = put_cmd_in_ert("\\IEEEauthorblockN{")
3655 j = find_token(document.body, "\\begin_inset Flex Author Affiliation", j)
3657 endj = find_end_of_inset(document.body, j)
3658 document.body[endj - 2 : endj + 1] = put_cmd_in_ert("}")
3659 document.body[j : j + 4] = put_cmd_in_ert("\\IEEEauthorblockA{")
3661 if i == -1 and j == -1 and h == -1:
3665 def revert_kurier_fonts(document):
3666 " Revert kurier font definition to LaTeX "
3668 i = find_token(document.header, "\\font_math", 0)
3670 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3671 val = get_value(document.header, "\\font_math", i)
3672 if val == "kurier-math":
3673 add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
3674 "\\usepackage[math]{kurier}\n" \
3675 "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
3676 document.header[i] = "\\font_math auto"
3678 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3679 kurier_fonts = ["kurier", "kurierc", "kurierl", "kurierlc"]
3680 k = find_token(document.header, "\\font_sans kurier", 0)
3682 sf = get_value(document.header, "\\font_sans", k)
3683 if sf in kurier_fonts:
3684 add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
3685 document.header[k] = "\\font_sans default"
3687 def revert_iwona_fonts(document):
3688 " Revert iwona font definition to LaTeX "
3690 i = find_token(document.header, "\\font_math", 0)
3692 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3693 val = get_value(document.header, "\\font_math", i)
3694 if val == "iwona-math":
3695 add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
3696 "\\usepackage[math]{iwona}\n" \
3697 "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
3698 document.header[i] = "\\font_math auto"
3700 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3701 iwona_fonts = ["iwona", "iwonac", "iwonal", "iwonalc"]
3702 k = find_token(document.header, "\\font_sans iwona", 0)
3704 sf = get_value(document.header, "\\font_sans", k)
3705 if sf in iwona_fonts:
3706 add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
3707 document.header[k] = "\\font_sans default"
3710 def revert_new_libertines(document):
3711 " Revert new libertine font definition to LaTeX "
3713 if find_token(document.header, "\\use_non_tex_fonts true", 0) != -1:
3716 i = find_token(document.header, "\\font_typewriter libertine-mono", 0)
3718 preamble = "\\usepackage"
3719 sc = find_token(document.header, "\\font_tt_scale", 0)
3721 scval = get_value(document.header, "\\font_tt_scale", sc)
3723 preamble += "[scale=%f]" % (float(scval) / 100)
3724 document.header[sc] = "\\font_tt_scale 100"
3725 preamble += "{libertineMono-type1}"
3726 add_to_preamble(document, [preamble])
3727 document.header[i] = "\\font_typewriter default"
3729 k = find_token(document.header, "\\font_sans biolinum", 0)
3731 preamble = "\\usepackage"
3733 j = find_token(document.header, "\\font_osf true", 0)
3738 sc = find_token(document.header, "\\font_sf_scale", 0)
3740 scval = get_value(document.header, "\\font_sf_scale", sc)
3742 options += ",scale=%f" % (float(scval) / 100)
3743 document.header[sc] = "\\font_sf_scale 100"
3745 preamble += "[" + options +"]"
3746 preamble += "{biolinum-type1}"
3747 add_to_preamble(document, [preamble])
3748 document.header[k] = "\\font_sans default"
3751 def convert_lyxframes(document):
3752 " Converts old beamer frames to new style "
3754 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3755 if document.textclass not in beamer_classes:
3758 framebeg = ["BeginFrame", "BeginPlainFrame"]
3759 frameend = ["Frame", "PlainFrame", "EndFrame", "BeginFrame", "BeginPlainFrame", "AgainFrame",
3760 "Section", "Section*", "Subsection", "Subsection*", "Subsubsection", "Subsubsection*"]
3761 for lay in framebeg:
3764 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
3767 parent = get_containing_layout(document.body, i)
3768 if parent == False or parent[1] != i:
3769 document.warning("Wrong parent layout!")
3772 frametype = parent[0]
3776 # Step I: Convert ERT arguments
3777 # FIXME: This currently only works if the arguments are in one single ERT
3779 if document.body[parbeg] == "\\begin_inset ERT":
3780 ertend = find_end_of_inset(document.body, parbeg)
3782 document.warning("Malformed LyX document: missing ERT \\end_inset")
3784 ertcont = parbeg + 5
3785 if document.body[ertcont].startswith("[<"):
3786 # This is a default overlay specification
3788 document.body[ertcont] = document.body[ertcont][2:]
3789 if document.body[ertcont].endswith(">]"):
3791 document.body[ertcont] = document.body[ertcont][:-2]
3792 elif document.body[ertcont].endswith("]"):
3794 tok = document.body[ertcont].find('>][')
3796 subst = [document.body[ertcont][:tok],
3797 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
3798 'status collapsed', '', '\\begin_layout Plain Layout',
3799 document.body[ertcont][tok + 3:-1]]
3800 document.body[ertcont : ertcont + 1] = subst
3802 # Convert to ArgInset
3803 document.body[parbeg] = "\\begin_inset Argument 2"
3804 elif document.body[ertcont].startswith("<"):
3805 # This is an overlay specification
3807 document.body[ertcont] = document.body[ertcont][1:]
3808 if document.body[ertcont].endswith(">"):
3810 document.body[ertcont] = document.body[ertcont][:-1]
3811 # Convert to ArgInset
3812 document.body[parbeg] = "\\begin_inset Argument 1"
3813 elif document.body[ertcont].endswith(">]"):
3815 tok = document.body[ertcont].find('>[<')
3817 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
3818 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
3819 'status collapsed', '', '\\begin_layout Plain Layout',
3820 document.body[ertcont][tok + 3:-2]]
3821 # Convert to ArgInset
3822 document.body[parbeg] = "\\begin_inset Argument 1"
3824 elif document.body[ertcont].endswith("]"):
3826 tok = document.body[ertcont].find('>[<')
3829 tokk = document.body[ertcont].find('>][')
3831 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
3832 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
3833 'status collapsed', '', '\\begin_layout Plain Layout',
3834 document.body[ertcont][tok + 3:tokk],
3835 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
3836 'status collapsed', '', '\\begin_layout Plain Layout',
3837 document.body[ertcont][tokk + 3:-1]]
3840 tokk = document.body[ertcont].find('>[')
3842 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tokk],
3843 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
3844 'status collapsed', '', '\\begin_layout Plain Layout',
3845 document.body[ertcont][tokk + 2:-1]]
3847 # Convert to ArgInset
3848 document.body[parbeg] = "\\begin_inset Argument 1"
3849 elif document.body[ertcont].startswith("["):
3850 # This is an ERT option
3852 document.body[ertcont] = document.body[ertcont][1:]
3853 if document.body[ertcont].endswith("]"):
3855 document.body[ertcont] = document.body[ertcont][:-1]
3856 # Convert to ArgInset
3857 document.body[parbeg] = "\\begin_inset Argument 3"
3858 # End of argument conversion
3859 # Step II: Now rename the layout and convert the title to an argument
3860 j = find_end_of_layout(document.body, i)
3861 document.body[j : j + 1] = ['\\end_layout', '', '\\end_inset', '', '\\end_layout']
3862 if lay == "BeginFrame":
3863 document.body[i] = "\\begin_layout Frame"
3865 document.body[i] = "\\begin_layout PlainFrame"
3866 document.body[ertend + 1 : ertend + 1] = ['\\begin_inset Argument 4',
3867 'status open', '', '\\begin_layout Plain Layout']
3868 # Step III: find real frame end
3872 fend = find_token(document.body, "\\begin_layout", jj)
3874 document.warning("Malformed LyX document: No real frame end!")
3876 val = get_value(document.body, "\\begin_layout", fend)
3877 if val not in frameend:
3880 old = document.body[fend]
3881 if val == frametype:
3882 document.body[fend : fend] = ['\\end_deeper', '', '\\begin_layout Separator', '', '\\end_layout']
3884 document.body[fend : fend] = ['\\end_deeper']
3885 document.body[j + 1 : j + 1] = ['', '\\begin_deeper']
3890 def remove_endframes(document):
3891 " Remove deprecated beamer endframes "
3893 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3894 if document.textclass not in beamer_classes:
3899 i = find_token_exact(document.body, "\\begin_layout EndFrame", i)
3902 j = find_end_of_layout(document.body, i)
3904 document.warning("Malformed LyX document: Missing \\end_layout to EndFrame")
3907 del document.body[i : j + 1]
3910 def revert_powerdot_flexes(document):
3911 " Reverts powerdot flex insets "
3913 if document.textclass != "powerdot":
3916 flexes = {"Onslide" : "\\onslide",
3917 "Onslide*" : "\\onslide*",
3918 "Onslide+" : "\\onslide+"}
3919 rx = re.compile(r'^\\begin_inset Flex (.+)$')
3923 i = find_token(document.body, "\\begin_inset Flex", i)
3926 m = rx.match(document.body[i])
3928 flextype = m.group(1)
3929 z = find_end_of_inset(document.body, i)
3931 document.warning("Can't find end of Flex " + flextype + " inset.")
3934 if flextype in flexes:
3935 pre = put_cmd_in_ert(flexes[flextype])
3936 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
3938 argend = find_end_of_inset(document.body, arg)
3940 document.warning("Can't find end of Argument!")
3943 # Find containing paragraph layout
3944 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3945 endPlain = find_end_of_layout(document.body, beginPlain)
3946 argcontent = document.body[beginPlain + 1 : endPlain]
3948 z = z - len(document.body[arg : argend + 1])
3950 del document.body[arg : argend + 1]
3951 pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
3952 pre += put_cmd_in_ert("{")
3953 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
3954 endPlain = find_end_of_layout(document.body, beginPlain)
3956 z = z - len(document.body[i : beginPlain + 1])
3958 document.body[i : beginPlain + 1] = pre
3959 post = put_cmd_in_ert("}")
3960 document.body[z - 2 : z + 1] = post
3964 def revert_powerdot_pause(document):
3965 " Reverts powerdot pause layout to ERT "
3967 if document.textclass != "powerdot":
3972 i = find_token(document.body, "\\begin_layout Pause", i)
3975 j = find_end_of_layout(document.body, i)
3977 document.warning("Malformed LyX document: Can't find end of Pause layout")
3981 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\pause")
3982 for p in range(i, j):
3985 arg = find_token(document.body, "\\begin_inset Argument 1", i, j)
3987 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3988 endPlain = find_end_of_layout(document.body, beginPlain)
3989 endInset = find_end_of_inset(document.body, p)
3990 content = document.body[beginPlain + 1 : endPlain]
3992 endlay = endlay - len(document.body[p : endInset + 1])
3994 del document.body[p : endInset + 1]
3995 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3997 document.body[i : i + 1] = subst
4001 def revert_powerdot_itemargs(document):
4002 " Reverts powerdot item arguments to ERT "
4004 if document.textclass != "powerdot":
4008 list_layouts = ["Itemize", "ItemizeType1", "Enumerate", "EnumerateType1"]
4009 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
4012 i = find_token(document.body, "\\begin_inset Argument", i)
4015 # Find containing paragraph layout
4016 parent = get_containing_layout(document.body, i)
4018 document.warning("Malformed LyX document: Can't find parent paragraph layout")
4023 realparbeg = parent[3]
4024 layoutname = parent[0]
4026 for p in range(parbeg, parend):
4030 if layoutname in list_layouts:
4031 m = rx.match(document.body[p])
4034 if argnr == "item:1":
4035 j = find_end_of_inset(document.body, i)
4036 # Find containing paragraph layout
4037 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
4038 endPlain = find_end_of_layout(document.body, beginPlain)
4039 content = document.body[beginPlain + 1 : endPlain]
4040 del document.body[i:j+1]
4041 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
4042 document.body[realparbeg : realparbeg] = subst
4043 elif argnr == "item:2":
4044 j = find_end_of_inset(document.body, i)
4045 # Find containing paragraph layout
4046 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
4047 endPlain = find_end_of_layout(document.body, beginPlain)
4048 content = document.body[beginPlain + 1 : endPlain]
4049 del document.body[i:j+1]
4050 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
4051 document.body[realparbeg : realparbeg] = subst
4056 def revert_powerdot_columns(document):
4057 " Reverts powerdot twocolumn to TeX-code "
4058 if document.textclass != "powerdot":
4061 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
4064 i = find_token(document.body, "\\begin_layout Twocolumn", i)
4067 j = find_end_of_layout(document.body, i)
4069 document.warning("Malformed LyX document: Can't find end of Twocolumn layout")
4073 document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
4074 endlay += len(put_cmd_in_ert("}"))
4075 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\twocolumn")
4076 for p in range(i, j):
4079 m = rx.match(document.body[p])
4083 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
4084 endPlain = find_end_of_layout(document.body, beginPlain)
4085 endInset = find_end_of_inset(document.body, p)
4086 content = document.body[beginPlain + 1 : endPlain]
4088 endlay = endlay - len(document.body[p : endInset + 1])
4090 del document.body[p : endInset + 1]
4091 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
4093 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
4094 endPlain = find_end_of_layout(document.body, beginPlain)
4095 endInset = find_end_of_inset(document.body, p)
4096 content = document.body[beginPlain + 1 : endPlain]
4098 endlay = endlay - len(document.body[p : endInset + 1])
4100 del document.body[p : endInset + 1]
4101 subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
4103 subst += put_cmd_in_ert("{")
4104 document.body[i : i + 1] = subst
4108 def revert_mbox_fbox(document):
4109 'Convert revert mbox/fbox boxes to TeX-code'
4112 i = find_token(document.body, "\\begin_inset Box", i)
4115 j = find_token(document.body, "width", i)
4117 document.warning("Malformed LyX document: Can't find box width")
4119 width = get_value(document.body, "width", j)
4120 k = find_end_of_inset(document.body, j)
4122 document.warning("Malformed LyX document: Can't find end of box inset")
4125 BeginLayout = find_token(document.body, "\\begin_layout Plain Layout", j)
4126 EndLayout = find_token(document.body, "\\end_layout", BeginLayout)
4127 # replace if width is ""
4129 document.body[EndLayout:k + 1] = put_cmd_in_ert("}")
4130 if document.body[i] == "\\begin_inset Box Frameless":
4131 document.body[i:BeginLayout + 1] = put_cmd_in_ert("\\mbox{")
4132 if document.body[i] == "\\begin_inset Box Boxed":
4133 document.body[i:BeginLayout + 1] = put_cmd_in_ert("\\fbox{")
4137 def revert_starred_caption(document):
4138 " Reverts unnumbered longtable caption insets "
4142 i = find_token(document.body, "\\begin_inset Caption LongTableNoNumber", i)
4145 # This is not equivalent, but since the caption inset is a full blown
4146 # text inset a true conversion to ERT is too difficult.
4147 document.body[i] = "\\begin_inset Caption Standard"
4151 def revert_forced_local_layout(document):
4154 i = find_token(document.header, "\\begin_forced_local_layout", i)
4157 j = find_end_of(document.header, i, "\\begin_forced_local_layout", "\\end_forced_local_layout")
4159 # this should not happen
4161 regexp = re.compile(r'\s*forcelocal', re.IGNORECASE)
4162 k = find_re(document.header, regexp, i, j)
4164 del document.header[k]
4166 k = find_re(document.header, regexp, i, j)
4167 k = find_token(document.header, "\\begin_local_layout", 0)
4169 document.header[i] = "\\begin_local_layout"
4170 document.header[j] = "\\end_local_layout"
4172 l = find_end_of(document.header, k, "\\begin_local_layout", "\\end_local_layout")
4174 # this should not happen
4176 lines = document.header[i+1 : j]
4178 document.header[k+1 : k+1] = lines
4179 document.header[i : j ] = []
4181 document.header[i : j ] = []
4182 document.header[k+1 : k+1] = lines
4185 def revert_aa1(document):
4186 " Reverts InsetArguments of aa to TeX-code "
4187 if document.textclass == "aa":
4191 i = find_token(document.body, "\\begin_layout Abstract (structured)", i)
4193 revert_Argument_to_TeX_brace(document, i, 0, 1, 4, False, False)
4199 def revert_aa2(document):
4200 " Reverts InsetArguments of aa to TeX-code "
4201 if document.textclass == "aa":
4205 i = find_token(document.body, "\\begin_layout Abstract (structured)", i)
4207 document.body[i] = "\\begin_layout Abstract"
4213 def revert_tibetan(document):
4214 "Set the document language for Tibetan to English"
4216 if document.language == "tibetan":
4217 document.language = "english"
4218 i = find_token(document.header, "\\language", 0)
4220 document.header[i] = "\\language english"
4222 while j < len(document.body):
4223 j = find_token(document.body, "\\lang tibetan", j)
4225 document.body[j] = document.body[j].replace("\\lang tibetan", "\\lang english")
4228 j = len(document.body)
4237 # the idea here is that we will have a sequence of chunk paragraphs
4238 # we want to convert them to paragraphs in a chunk inset
4239 # the last will be discarded
4240 # the first should look like: <<FROGS>>=
4241 # will will discard the delimiters, and put the contents into the
4242 # optional argument of the inset
4243 def convert_chunks(document):
4244 first_re = re.compile(r'<<(.*)>>=')
4247 # the beginning of this sequence
4249 # find start of a block of chunks
4250 i = find_token(document.body, "\\begin_layout Chunk", i)
4258 # process the one we just found
4259 j = find_end_of_layout(document.body, i)
4261 document.warning("Malformed LyX documents. Can't find end of Chunk layout!")
4263 thischunk = "".join(document.body[i + 1:j])
4264 contents.append(document.body[i + 1:j])
4266 if thischunk == "@":
4269 # look for the next one
4271 i = find_token(document.body, "\\begin_layout", i)
4275 layout = get_value(document.body, "\\begin_layout", i)
4276 #sys.stderr.write(layout+ '\n')
4277 if layout != "Chunk":
4281 # error, but we can try to continue
4288 # the last chunk should simply have an "@" in it
4290 if ''.join(contents[-1]) != "@":
4291 document.warning("Unexpected chunk contents.")
4296 # the first item should look like: <<FROGS>>=
4297 # we want the inside
4298 optarg = ' '.join(contents[0])
4300 match = first_re.search(optarg)
4302 optarg = match.groups()[0]
4305 newstuff = ['\\begin_layout Standard',
4306 '\\begin_inset Flex Chunk',
4308 '\\begin_layout Plain Layout', '']
4312 ['\\begin_inset Argument 1',
4314 '\\begin_layout Plain Layout',
4322 newstuff.extend(['', '\\begin_layout Plain Layout', ''])
4326 newstuff.append('\\end_layout')
4328 newstuff.extend(['', '\\end_inset', '', '\\end_layout', ''])
4330 document.body[start:end] = newstuff
4332 k += len(newstuff) - (end - start)
4335 def revert_chunks(document):
4338 i = find_token(document.body, "\\begin_inset Flex Chunk", i)
4342 iend = find_end_of_inset(document.body, i)
4344 document.warning("Can't find end of Chunk!")
4348 # Look for optional argument
4350 ostart = find_token(document.body, "\\begin_inset Argument 1", i, iend)
4352 oend = find_end_of_inset(document.body, ostart)
4353 k = find_token(document.body, "\\begin_layout Plain Layout", ostart, oend)
4355 document.warning("Malformed LyX document: Can't find argument contents!")
4357 m = find_end_of_layout(document.body, k)
4358 optarg = "".join(document.body[k+1:m])
4361 # We now remove the optional argument, so we have something
4362 # uniform on which to work
4363 document.body[ostart : oend + 1] = []
4364 # iend is now invalid
4365 iend = find_end_of_inset(document.body, i)
4367 retval = get_containing_layout(document.body, i)
4369 document.warning("Can't find containing layout for Chunk!")
4372 (lname, lstart, lend, pstart) = retval
4373 # we now want to work through the various paragraphs, and collect their contents
4377 k = find_token(document.body, "\\begin_layout Plain Layout", k, lend)
4380 j = find_end_of_layout(document.body, k)
4382 document.warning("Can't find end of layout inside chunk!")
4384 parlist.append(document.body[k+1:j])
4386 # we now need to wrap all of these paragraphs in chunks
4389 newlines.extend(["\\begin_layout Chunk", "", "<<" + optarg + ">>=", "\\end_layout", ""])
4390 for stuff in parlist:
4391 newlines.extend(["\\begin_layout Chunk"] + stuff + ["\\end_layout", ""])
4392 newlines.extend(["\\begin_layout Chunk", "", "@", "\\end_layout", ""])
4393 # replace old content with new content
4394 document.body[lstart : lend + 1] = newlines
4395 i = lstart + len(newlines)
4402 supported_versions = ["2.1.0","2.1"]
4405 [415, [convert_undertilde]],
4407 [417, [convert_japanese_encodings]],
4410 [420, [convert_biblio_style]],
4411 [421, [convert_longtable_captions]],
4412 [422, [convert_use_packages]],
4413 [423, [convert_use_mathtools]],
4414 [424, [convert_cite_engine_type]],
4418 [428, [convert_cell_rotation]],
4419 [429, [convert_table_rotation]],
4420 [430, [convert_listoflistings]],
4421 [431, [convert_use_amssymb]],
4423 [433, [convert_armenian]],
4431 [441, [convert_mdnomath]],
4436 [446, [convert_latexargs]],
4437 [447, [convert_IEEEtran, convert_AASTeX, convert_AGUTeX, convert_IJMP, convert_SIGPLAN, convert_SIGGRAPH, convert_EuropeCV, convert_Initials, convert_ModernCV]],
4438 [448, [convert_literate]],
4441 [451, [convert_beamerargs, convert_againframe_args, convert_corollary_args, convert_quote_args]],
4442 [452, [convert_beamerblocks]],
4443 [453, [convert_use_stmaryrd]],
4444 [454, [convert_overprint]],
4446 [456, [convert_epigraph]],
4447 [457, [convert_use_stackrel]],
4448 [458, [convert_captioninsets, convert_captionlayouts]],
4453 [463, [convert_encodings]],
4454 [464, [convert_use_cancel]],
4455 [465, [convert_lyxframes, remove_endframes]],
4461 [471, [convert_cite_engine_type_default]],
4464 [474, [convert_chunks]],
4468 [473, [revert_chunks]],
4469 [472, [revert_tibetan]],
4470 [471, [revert_aa1,revert_aa2]],
4471 [470, [revert_cite_engine_type_default]],
4472 [469, [revert_forced_local_layout]],
4473 [468, [revert_starred_caption]],
4474 [467, [revert_mbox_fbox]],
4475 [466, [revert_iwona_fonts]],
4476 [465, [revert_powerdot_flexes, revert_powerdot_pause, revert_powerdot_itemargs, revert_powerdot_columns]],
4478 [463, [revert_use_cancel]],
4479 [462, [revert_encodings]],
4480 [461, [revert_new_libertines]],
4481 [460, [revert_kurier_fonts]],
4482 [459, [revert_IEEEtran_3]],
4483 [458, [revert_fragileframe, revert_newframes]],
4484 [457, [revert_captioninsets, revert_captionlayouts]],
4485 [456, [revert_use_stackrel]],
4486 [455, [revert_epigraph]],
4487 [454, [revert_frametitle]],
4488 [453, [revert_overprint]],
4489 [452, [revert_use_stmaryrd]],
4490 [451, [revert_beamerblocks]],
4491 [450, [revert_beamerargs, revert_beamerargs2, revert_beamerargs3, revert_beamerflex]],
4492 [449, [revert_garamondx, revert_garamondx_newtxmath]],
4493 [448, [revert_itemargs]],
4494 [447, [revert_literate]],
4495 [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]],
4496 [445, [revert_latexargs]],
4497 [444, [revert_uop]],
4498 [443, [revert_biolinum]],
4500 [441, [revert_newtxmath]],
4501 [440, [revert_mdnomath]],
4502 [439, [revert_mathfonts]],
4503 [438, [revert_minionpro]],
4504 [437, [revert_ipadeco, revert_ipachar]],
4505 [436, [revert_texgyre]],
4506 [435, [revert_mathdesign]],
4507 [434, [revert_txtt]],
4508 [433, [revert_libertine]],
4509 [432, [revert_armenian]],
4510 [431, [revert_languages, revert_ancientgreek]],
4511 [430, [revert_use_amssymb]],
4512 [429, [revert_listoflistings]],
4513 [428, [revert_table_rotation]],
4514 [427, [revert_cell_rotation]],
4515 [426, [revert_tipa]],
4516 [425, [revert_verbatim]],
4517 [424, [revert_cancel]],
4518 [423, [revert_cite_engine_type]],
4519 [422, [revert_use_mathtools]],
4520 [421, [revert_use_packages]],
4521 [420, [revert_longtable_captions]],
4522 [419, [revert_biblio_style]],
4523 [418, [revert_australian]],
4524 [417, [revert_justification]],
4525 [416, [revert_japanese_encodings]],
4526 [415, [revert_negative_space, revert_math_spaces]],
4527 [414, [revert_undertilde]],
4528 [413, [revert_visible_space]]
4532 if __name__ == "__main__":