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 ###############################################################################
58 ### Conversion and reversion routines
60 ###############################################################################
62 def revert_visible_space(document):
63 "Revert InsetSpace visible into its ERT counterpart"
66 i = find_token(document.body, "\\begin_inset space \\textvisiblespace{}", i)
69 end = find_end_of_inset(document.body, i)
70 subst = put_cmd_in_ert("\\textvisiblespace{}")
71 document.body[i:end + 1] = subst
74 def convert_undertilde(document):
75 " Load undertilde automatically "
76 i = find_token(document.header, "\\use_mathdots" , 0)
78 i = find_token(document.header, "\\use_mhchem" , 0)
80 i = find_token(document.header, "\\use_esint" , 0)
82 document.warning("Malformed LyX document: Can't find \\use_mathdots.")
84 j = find_token(document.preamble, "\\usepackage{undertilde}", 0)
86 document.header.insert(i + 1, "\\use_undertilde 0")
88 document.header.insert(i + 1, "\\use_undertilde 2")
89 del document.preamble[j]
92 def revert_undertilde(document):
93 " Load undertilde if used in the document "
94 undertilde = find_token(document.header, "\\use_undertilde" , 0)
96 document.warning("No \\use_undertilde line. Assuming auto.")
98 val = get_value(document.header, "\\use_undertilde", undertilde)
99 del document.header[undertilde]
103 document.warning("Invalid \\use_undertilde value: " + val + ". Assuming auto.")
104 # probably usedots has not been changed, but be safe.
112 add_to_preamble(document, ["\\usepackage{undertilde}"])
115 # so we are in the auto case. we want to load undertilde if \utilde is used.
118 i = find_token(document.body, '\\begin_inset Formula', i)
121 j = find_end_of_inset(document.body, i)
123 document.warning("Malformed LyX document: Can't find end of Formula inset at line " + str(i))
126 code = "\n".join(document.body[i:j])
127 if code.find("\\utilde") != -1:
128 add_to_preamble(document, ["\\@ifundefined{utilde}{\\usepackage{undertilde}}"])
133 def revert_negative_space(document):
134 "Revert InsetSpace negmedspace and negthickspace into its TeX-code counterpart"
139 i = find_token(document.body, "\\begin_inset space \\negmedspace{}", i)
141 j = find_token(document.body, "\\begin_inset space \\negthickspace{}", j)
143 # load amsmath in the preamble if not already loaded if we are at the end of checking
145 i = find_token(document.header, "\\use_amsmath 2", 0)
147 add_to_preamble(document, ["\\@ifundefined{negthickspace}{\\usepackage{amsmath}}"])
151 end = find_end_of_inset(document.body, i)
152 subst = put_cmd_in_ert("\\negmedspace{}")
153 document.body[i:end + 1] = subst
154 j = find_token(document.body, "\\begin_inset space \\negthickspace{}", j)
157 end = find_end_of_inset(document.body, j)
158 subst = put_cmd_in_ert("\\negthickspace{}")
159 document.body[j:end + 1] = subst
163 def revert_math_spaces(document):
164 "Revert formulas with protected custom space and protected hfills to TeX-code"
167 i = find_token(document.body, "\\begin_inset Formula", i)
170 j = document.body[i].find("\\hspace*")
172 end = find_end_of_inset(document.body, i)
173 subst = put_cmd_in_ert(document.body[i][21:])
174 document.body[i:end + 1] = subst
178 def convert_japanese_encodings(document):
179 " Rename the japanese encodings to names understood by platex "
181 "EUC-JP-pLaTeX": "euc",
183 "SJIS-pLaTeX": "sjis"
185 i = find_token(document.header, "\\inputencoding" , 0)
188 val = get_value(document.header, "\\inputencoding", i)
189 if val in jap_enc_dict.keys():
190 document.header[i] = "\\inputencoding %s" % jap_enc_dict[val]
193 def revert_japanese_encodings(document):
194 " Revert the japanese encodings name changes "
196 "euc": "EUC-JP-pLaTeX",
198 "sjis": "SJIS-pLaTeX"
200 i = find_token(document.header, "\\inputencoding" , 0)
203 val = get_value(document.header, "\\inputencoding", i)
204 if val in jap_enc_dict.keys():
205 document.header[i] = "\\inputencoding %s" % jap_enc_dict[val]
208 def revert_justification(document):
209 " Revert the \\justification buffer param"
210 if not del_token(document.header, '\\justification', 0):
211 document.warning("Malformed LyX document: Missing \\justification.")
214 def revert_australian(document):
215 "Set English language variants Australian and Newzealand to English"
217 if document.language == "australian" or document.language == "newzealand":
218 document.language = "english"
219 i = find_token(document.header, "\\language", 0)
221 document.header[i] = "\\language english"
224 j = find_token(document.body, "\\lang australian", j)
226 j = find_token(document.body, "\\lang newzealand", 0)
230 document.body[j] = document.body[j].replace("\\lang newzealand", "\\lang english")
232 document.body[j] = document.body[j].replace("\\lang australian", "\\lang english")
236 def convert_biblio_style(document):
237 "Add a sensible default for \\biblio_style based on the citation engine."
238 i = find_token(document.header, "\\cite_engine", 0)
240 engine = get_value(document.header, "\\cite_engine", i).split("_")[0]
241 style = {"basic": "plain", "natbib": "plainnat", "jurabib": "jurabib"}
242 document.header.insert(i + 1, "\\biblio_style " + style[engine])
245 def revert_biblio_style(document):
246 "BibTeX insets with default option use the style defined by \\biblio_style."
247 i = find_token(document.header, "\\biblio_style" , 0)
249 document.warning("No \\biblio_style line. Nothing to do.")
252 default_style = get_value(document.header, "\\biblio_style", i)
253 del document.header[i]
255 # We are looking for bibtex insets having the default option
258 i = find_token(document.body, "\\begin_inset CommandInset bibtex", i)
261 j = find_end_of_inset(document.body, i)
263 document.warning("Malformed LyX document: Can't find end of bibtex inset at line " + str(i))
266 k = find_token(document.body, "options", i, j)
268 options = get_quoted_value(document.body, "options", k)
269 if "default" in options.split(","):
270 document.body[k] = 'options "%s"' \
271 % options.replace("default", default_style)
275 def handle_longtable_captions(document, forward):
278 begin_table = find_token(document.body, '<lyxtabular version=', begin_table)
279 if begin_table == -1:
281 end_table = find_end_of(document.body, begin_table, '<lyxtabular', '</lyxtabular>')
283 document.warning("Malformed LyX document: Could not find end of table.")
286 fline = find_token(document.body, "<features", begin_table, end_table)
288 document.warning("Can't find features for inset at line " + str(begin_table))
291 p = document.body[fline].find("islongtable")
296 numrows = get_option_value(document.body[begin_table], "rows")
298 numrows = int(numrows)
300 document.warning(document.body[begin_table])
301 document.warning("Unable to determine rows!")
302 begin_table = end_table
304 begin_row = begin_table
305 for row in range(numrows):
306 begin_row = find_token(document.body, '<row', begin_row, end_table)
308 document.warning("Can't find row " + str(row + 1))
310 end_row = find_end_of(document.body, begin_row, '<row', '</row>')
312 document.warning("Can't find end of row " + str(row + 1))
315 if (get_option_value(document.body[begin_row], 'caption') == 'true' and
316 get_option_value(document.body[begin_row], 'endfirsthead') != 'true' and
317 get_option_value(document.body[begin_row], 'endhead') != 'true' and
318 get_option_value(document.body[begin_row], 'endfoot') != 'true' and
319 get_option_value(document.body[begin_row], 'endlastfoot') != 'true'):
320 document.body[begin_row] = set_option_value(document.body[begin_row], 'caption', 'true", endfirsthead="true')
321 elif get_option_value(document.body[begin_row], 'caption') == 'true':
322 if get_option_value(document.body[begin_row], 'endfirsthead') == 'true':
323 document.body[begin_row] = set_option_value(document.body[begin_row], 'endfirsthead', 'false')
324 if get_option_value(document.body[begin_row], 'endhead') == 'true':
325 document.body[begin_row] = set_option_value(document.body[begin_row], 'endhead', 'false')
326 if get_option_value(document.body[begin_row], 'endfoot') == 'true':
327 document.body[begin_row] = set_option_value(document.body[begin_row], 'endfoot', 'false')
328 if get_option_value(document.body[begin_row], 'endlastfoot') == 'true':
329 document.body[begin_row] = set_option_value(document.body[begin_row], 'endlastfoot', 'false')
331 # since there could be a tabular inside this one, we
332 # cannot jump to end.
336 def convert_longtable_captions(document):
337 "Add a firsthead flag to caption rows"
338 handle_longtable_captions(document, True)
341 def revert_longtable_captions(document):
342 "remove head/foot flag from caption rows"
343 handle_longtable_captions(document, False)
346 def convert_use_packages(document):
347 "use_xxx yyy => use_package xxx yyy"
348 packages = ["amsmath", "esint", "mathdots", "mhchem", "undertilde"]
350 i = find_token(document.header, "\\use_%s" % p, 0)
352 value = get_value(document.header, "\\use_%s" % p, i)
353 document.header[i] = "\\use_package %s %s" % (p, value)
356 def revert_use_packages(document):
357 "use_package xxx yyy => use_xxx yyy"
358 packages = ["amsmath", "esint", "mathdots", "mhchem", "undertilde"]
359 # the order is arbitrary for the use_package version, and not all packages need to be given.
360 # Ensure a complete list and correct order (important for older LyX versions and especially lyx2lyx)
363 regexp = re.compile(r'(\\use_package\s+%s)' % p)
364 i = find_re(document.header, regexp, j)
366 value = get_value(document.header, "\\use_package %s" % p, i).split()[1]
367 del document.header[i]
369 document.header.insert(j, "\\use_%s %s" % (p, value))
373 def convert_use_package(document, pkg):
374 i = find_token(document.header, "\\use_package", 0)
376 document.warning("Malformed LyX document: Can't find \\use_package.")
378 j = find_token(document.preamble, "\\usepackage{" + pkg + "}", 0)
380 document.header.insert(i + 1, "\\use_package " + pkg + " 0")
382 document.header.insert(i + 1, "\\use_package " + pkg + " 2")
383 del document.preamble[j]
386 def revert_use_package(document, pkg, commands, oldauto):
387 # oldauto defines how the version we are reverting to behaves:
388 # if it is true, the old version uses the package automatically.
389 # if it is false, the old version never uses the package.
390 regexp = re.compile(r'(\\use_package\s+%s)' % pkg)
391 i = find_re(document.header, regexp, 0)
392 value = "1" # default is auto
394 value = get_value(document.header, "\\use_package" , i).split()[1]
395 del document.header[i]
396 if value == "2": # on
397 add_to_preamble(document, ["\\usepackage{" + pkg + "}"])
398 elif value == "1" and not oldauto: # auto
401 i = find_token(document.body, '\\begin_inset Formula', i)
404 j = find_end_of_inset(document.body, i)
406 document.warning("Malformed LyX document: Can't find end of Formula inset at line " + str(i))
409 code = "\n".join(document.body[i:j])
411 if code.find("\\%s" % c) != -1:
412 add_to_preamble(document, ["\\usepackage{" + pkg + "}"])
417 def convert_use_mathtools(document):
418 "insert use_package mathtools"
419 convert_use_package(document, "mathtools")
422 def revert_use_mathtools(document):
423 "remove use_package mathtools"
424 commands = ["mathclap", "mathllap", "mathrlap", \
425 "lgathered", "rgathered", "vcentcolon", "dblcolon", \
426 "coloneqq", "Coloneqq", "coloneq", "Coloneq", "eqqcolon", \
427 "Eqqcolon", "eqcolon", "Eqcolon", "colonapprox", \
428 "Colonapprox", "colonsim", "Colonsim"]
429 revert_use_package(document, "mathtools", commands, False)
432 def convert_use_stmaryrd(document):
433 "insert use_package stmaryrd"
434 convert_use_package(document, "stmaryrd")
437 def revert_use_stmaryrd(document):
438 "remove use_package stmaryrd"
439 # commands provided by stmaryrd.sty but LyX uses other packages:
440 # boxdot lightning, bigtriangledown, bigtriangleup
441 commands = ["shortleftarrow", "shortrightarrow", "shortuparrow", \
442 "shortdownarrow", "Yup", "Ydown", "Yleft", "Yright", \
443 "varcurlyvee", "varcurlywedge", "minuso", "baro", \
444 "sslash", "bbslash", "moo", "varotimes", "varoast", \
445 "varobar", "varodot", "varoslash", "varobslash", \
446 "varocircle", "varoplus", "varominus", "boxast", \
447 "boxbar", "boxslash", "boxbslash", "boxcircle", \
448 "boxbox", "boxempty", "merge", "vartimes", \
449 "fatsemi", "sswarrow", "ssearrow", "curlywedgeuparrow", \
450 "curlywedgedownarrow", "fatslash", "fatbslash", "lbag", \
451 "rbag", "varbigcirc", "leftrightarroweq", \
452 "curlyveedownarrow", "curlyveeuparrow", "nnwarrow", \
453 "nnearrow", "leftslice", "rightslice", "varolessthan", \
454 "varogreaterthan", "varovee", "varowedge", "talloblong", \
455 "interleave", "obar", "obslash", "olessthan", \
456 "ogreaterthan", "ovee", "owedge", "oblong", "inplus", \
457 "niplus", "nplus", "subsetplus", "supsetplus", \
458 "subsetpluseq", "supsetpluseq", "Lbag", "Rbag", \
459 "llbracket", "rrbracket", "llparenthesis", \
460 "rrparenthesis", "binampersand", "bindnasrepma", \
461 "trianglelefteqslant", "trianglerighteqslant", \
462 "ntrianglelefteqslant", "ntrianglerighteqslant", \
463 "llfloor", "rrfloor", "llceil", "rrceil", "arrownot", \
464 "Arrownot", "Mapstochar", "mapsfromchar", "Mapsfromchar", \
465 "leftrightarrowtriangle", "leftarrowtriangle", \
466 "rightarrowtriangle", \
467 "bigcurlyvee", "bigcurlywedge", "bigsqcap", "bigbox", \
468 "bigparallel", "biginterleave", "bignplus", \
469 "varcopyright", "longarrownot", "Longarrownot", \
470 "Mapsto", "mapsfrom", "Mapsfrom" "Longmapsto", \
471 "longmapsfrom", "Longmapsfrom"]
472 revert_use_package(document, "stmaryrd", commands, False)
476 def convert_use_stackrel(document):
477 "insert use_package stackrel"
478 convert_use_package(document, "stackrel")
481 def revert_use_stackrel(document):
482 "remove use_package stackrel"
483 commands = ["stackrel"]
484 revert_use_package(document, "stackrel", commands, False)
487 def convert_cite_engine_type(document):
488 "Determine the \\cite_engine_type from the citation engine."
489 i = find_token(document.header, "\\cite_engine", 0)
492 engine = get_value(document.header, "\\cite_engine", i)
494 engine, type = engine.split("_")
496 type = {"basic": "numerical", "jurabib": "authoryear"}[engine]
497 document.header[i] = "\\cite_engine " + engine
498 document.header.insert(i + 1, "\\cite_engine_type " + type)
501 def revert_cite_engine_type(document):
502 "Natbib had the type appended with an underscore."
503 engine_type = "numerical"
504 i = find_token(document.header, "\\cite_engine_type" , 0)
506 document.warning("No \\cite_engine_type line. Assuming numerical.")
508 engine_type = get_value(document.header, "\\cite_engine_type", i)
509 del document.header[i]
511 # We are looking for the natbib citation engine
512 i = find_token(document.header, "\\cite_engine natbib", 0)
515 document.header[i] = "\\cite_engine natbib_" + engine_type
518 def convert_cite_engine_type_default(document):
519 "Convert \\cite_engine_type to default for the basic citation engine."
520 i = find_token(document.header, "\\cite_engine basic", 0)
523 i = find_token(document.header, "\\cite_engine_type" , 0)
526 document.header[i] = "\\cite_engine_type default"
529 def revert_cite_engine_type_default(document):
530 """Revert \\cite_engine_type default.
532 Revert to numerical for the basic cite engine, otherwise to authoryear."""
533 engine_type = "authoryear"
534 i = find_token(document.header, "\\cite_engine_type default" , 0)
537 j = find_token(document.header, "\\cite_engine basic", 0)
539 engine_type = "numerical"
540 document.header[i] = "\\cite_engine_type " + engine_type
543 # this is the same, as revert_use_cancel() except for the default
544 def revert_cancel(document):
545 "add cancel to the preamble if necessary"
546 commands = ["cancelto", "cancel", "bcancel", "xcancel"]
547 revert_use_package(document, "cancel", commands, False)
550 def revert_verbatim(document):
551 " Revert verbatim einvironments completely to TeX-code. "
554 subst_end = ['\end_layout', '', '\\begin_layout Plain Layout',
556 '\\begin_layout Plain Layout', '', '',
559 '\\end_layout', '', '\\end_inset',
560 '', '', '\\end_layout']
561 subst_begin = ['\\begin_layout Standard', '\\noindent',
562 '\\begin_inset ERT', 'status collapsed', '',
563 '\\begin_layout Plain Layout', '', '', '\\backslash',
565 '\\end_layout', '', '\\begin_layout Plain Layout', '']
567 i = find_token(document.body, "\\begin_layout Verbatim", i)
570 j = find_end_of_layout(document.body, i)
572 document.warning("Malformed LyX document: Can't find end of Verbatim layout")
575 # delete all line breaks insets (there are no other insets)
578 n = find_token(document.body, "\\begin_inset Newline newline", l)
580 n = find_token(document.body, "\\begin_inset Newline linebreak", l)
583 m = find_end_of_inset(document.body, n)
584 del(document.body[m:m+1])
585 document.body[n:n+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
588 # consecutive verbatim environments need to be connected
589 k = find_token(document.body, "\\begin_layout Verbatim", j)
590 if k == j + 2 and consecutive == False:
592 document.body[j:j+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
593 document.body[i:i+1] = subst_begin
595 if k == j + 2 and consecutive == True:
596 document.body[j:j+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
597 del(document.body[i:i+1])
599 if k != j + 2 and consecutive == True:
600 document.body[j:j+1] = subst_end
601 # the next paragraph must not be indented
602 document.body[j+19:j+19] = ['\\noindent']
603 del(document.body[i:i+1])
607 document.body[j:j+1] = subst_end
608 # the next paragraph must not be indented
609 document.body[j+19:j+19] = ['\\noindent']
610 document.body[i:i+1] = subst_begin
613 def revert_tipa(document):
614 " Revert native TIPA insets to mathed or ERT. "
617 i = find_token(document.body, "\\begin_inset IPA", i)
620 j = find_end_of_inset(document.body, i)
622 document.warning("Malformed LyX document: Can't find end of IPA inset")
626 n = find_token(document.body, "\\begin_layout", i, j)
628 document.warning("Malformed LyX document: IPA inset has no embedded layout")
631 m = find_end_of_layout(document.body, n)
633 document.warning("Malformed LyX document: Can't find end of embedded layout")
636 content = document.body[n+1:m]
637 p = find_token(document.body, "\\begin_layout", m, j)
638 if p != -1 or len(content) > 1:
640 content = document.body[i+1:j]
642 # IPA insets with multiple pars need to be wrapped by \begin{IPA}...\end{IPA}
643 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}")
644 add_to_preamble(document, ["\\usepackage{tipa,tipx}"])
646 # single-par IPA insets can be reverted to mathed
647 document.body[i:j+1] = ["\\begin_inset Formula $\\text{\\textipa{" + content[0] + "}}$", "\\end_inset"]
651 def revert_cell_rotation(document):
652 "Revert cell rotations to TeX-code"
654 load_rotating = False
658 # first, let's find out if we need to do anything
659 i = find_token(document.body, '<cell ', i)
662 j = document.body[i].find('rotate="')
664 k = document.body[i].find('"', j + 8)
665 value = document.body[i][j + 8 : k]
667 rgx = re.compile(r' rotate="[^"]+?"')
668 # remove rotate option
669 document.body[i] = rgx.sub('', document.body[i])
671 rgx = re.compile(r' rotate="[^"]+?"')
672 document.body[i] = rgx.sub('rotate="true"', document.body[i])
674 rgx = re.compile(r' rotate="[^"]+?"')
676 # remove rotate option
677 document.body[i] = rgx.sub('', document.body[i])
679 document.body[i + 5 : i + 5] = \
680 put_cmd_in_ert("\\end{turn}")
681 document.body[i + 4 : i + 4] = \
682 put_cmd_in_ert("\\begin{turn}{" + value + "}")
688 add_to_preamble(document, ["\\@ifundefined{turnbox}{\usepackage{rotating}}{}"])
691 def convert_cell_rotation(document):
692 'Convert cell rotation statements from "true" to "90"'
696 # first, let's find out if we need to do anything
697 i = find_token(document.body, '<cell ', i)
700 j = document.body[i].find('rotate="true"')
702 rgx = re.compile(r'rotate="[^"]+?"')
703 # convert "true" to "90"
704 document.body[i] = rgx.sub('rotate="90"', document.body[i])
709 def revert_table_rotation(document):
710 "Revert table rotations to TeX-code"
712 load_rotating = False
716 # first, let's find out if we need to do anything
717 i = find_token(document.body, '<features ', i)
720 j = document.body[i].find('rotate="')
722 end_table = find_token(document.body, '</lyxtabular>', j)
723 k = document.body[i].find('"', j + 8)
724 value = document.body[i][j + 8 : k]
726 rgx = re.compile(r' rotate="[^"]+?"')
727 # remove rotate option
728 document.body[i] = rgx.sub('', document.body[i])
730 rgx = re.compile(r'rotate="[^"]+?"')
731 document.body[i] = rgx.sub('rotate="true"', document.body[i])
733 rgx = re.compile(r' rotate="[^"]+?"')
735 # remove rotate option
736 document.body[i] = rgx.sub('', document.body[i])
738 document.body[end_table + 3 : end_table + 3] = \
739 put_cmd_in_ert("\\end{turn}")
740 document.body[i - 2 : i - 2] = \
741 put_cmd_in_ert("\\begin{turn}{" + value + "}")
747 add_to_preamble(document, ["\\@ifundefined{turnbox}{\usepackage{rotating}}{}"])
750 def convert_table_rotation(document):
751 'Convert table rotation statements from "true" to "90"'
755 # first, let's find out if we need to do anything
756 i = find_token(document.body, '<features ', i)
759 j = document.body[i].find('rotate="true"')
761 rgx = re.compile(r'rotate="[^"]+?"')
762 # convert "true" to "90"
763 document.body[i] = rgx.sub('rotate="90"', document.body[i])
768 def convert_listoflistings(document):
769 'Convert ERT \lstlistoflistings to TOC lstlistoflistings inset'
770 # We can support roundtrip because the command is so simple
773 i = find_token(document.body, "\\begin_inset ERT", i)
776 j = find_end_of_inset(document.body, i)
778 document.warning("Malformed LyX document: Can't find end of ERT inset")
781 ert = get_ert(document.body, i)
782 if ert == "\\lstlistoflistings{}":
783 document.body[i:j] = ["\\begin_inset CommandInset toc", "LatexCommand lstlistoflistings", ""]
789 def revert_listoflistings(document):
790 'Convert TOC lstlistoflistings inset to ERT lstlistoflistings'
793 i = find_token(document.body, "\\begin_inset CommandInset toc", i)
796 if document.body[i+1] == "LatexCommand lstlistoflistings":
797 j = find_end_of_inset(document.body, i)
799 document.warning("Malformed LyX document: Can't find end of TOC inset")
802 subst = put_cmd_in_ert("\\lstlistoflistings{}")
803 document.body[i:j+1] = subst
804 add_to_preamble(document, ["\\usepackage{listings}"])
808 def convert_use_amssymb(document):
809 "insert use_package amssymb"
810 regexp = re.compile(r'(\\use_package\s+amsmath)')
811 i = find_re(document.header, regexp, 0)
813 document.warning("Malformed LyX document: Can't find \\use_package amsmath.")
815 value = get_value(document.header, "\\use_package" , i).split()[1]
818 useamsmath = int(value)
820 document.warning("Invalid \\use_package amsmath: " + value + ". Assuming auto.")
822 j = find_token(document.preamble, "\\usepackage{amssymb}", 0)
824 document.header.insert(i + 1, "\\use_package amssymb %d" % useamsmath)
826 document.header.insert(i + 1, "\\use_package amssymb 2")
827 del document.preamble[j]
830 def revert_use_amssymb(document):
831 "remove use_package amssymb"
832 regexp1 = re.compile(r'(\\use_package\s+amsmath)')
833 regexp2 = re.compile(r'(\\use_package\s+amssymb)')
834 i = find_re(document.header, regexp1, 0)
835 j = find_re(document.header, regexp2, 0)
836 value1 = "1" # default is auto
837 value2 = "1" # default is auto
839 value1 = get_value(document.header, "\\use_package" , i).split()[1]
841 value2 = get_value(document.header, "\\use_package" , j).split()[1]
842 del document.header[j]
843 if value1 != value2 and value2 == "2": # on
844 add_to_preamble(document, ["\\usepackage{amssymb}"])
847 def convert_use_cancel(document):
848 "insert use_package cancel"
849 convert_use_package(document, "cancel")
852 def revert_use_cancel(document):
853 "remove use_package cancel"
854 commands = ["cancel", "bcancel", "xcancel", "cancelto"]
855 revert_use_package(document, "cancel", commands, True)
858 def revert_ancientgreek(document):
859 "Set the document language for ancientgreek to greek"
861 if document.language == "ancientgreek":
862 document.language = "greek"
863 i = find_token(document.header, "\\language", 0)
865 document.header[i] = "\\language greek"
868 j = find_token(document.body, "\\lang ancientgreek", j)
872 document.body[j] = document.body[j].replace("\\lang ancientgreek", "\\lang greek")
876 def revert_languages(document):
877 "Set the document language for new supported languages to English"
880 "coptic", "divehi", "hindi", "kurmanji", "lao", "marathi", "occitan", "sanskrit",
881 "syriac", "tamil", "telugu", "urdu"
883 for n in range(len(languages)):
884 if document.language == languages[n]:
885 document.language = "english"
886 i = find_token(document.header, "\\language", 0)
888 document.header[i] = "\\language english"
890 while j < len(document.body):
891 j = find_token(document.body, "\\lang " + languages[n], j)
893 document.body[j] = document.body[j].replace("\\lang " + languages[n], "\\lang english")
896 j = len(document.body)
899 def convert_armenian(document):
900 "Use polyglossia and thus non-TeX fonts for Armenian"
902 if document.language == "armenian":
903 i = find_token(document.header, "\\use_non_tex_fonts", 0)
905 document.header[i] = "\\use_non_tex_fonts true"
908 def revert_armenian(document):
909 "Use ArmTeX and thus TeX fonts for Armenian"
911 if document.language == "armenian":
912 i = find_token(document.header, "\\use_non_tex_fonts", 0)
914 document.header[i] = "\\use_non_tex_fonts false"
917 def revert_libertine(document):
918 " Revert native libertine font definition to LaTeX "
920 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
921 i = find_token(document.header, "\\font_roman libertine", 0)
924 j = find_token(document.header, "\\font_osf true", 0)
927 preamble = "\\usepackage"
929 document.header[j] = "\\font_osf false"
932 preamble += "[lining]"
933 preamble += "{libertine-type1}"
934 add_to_preamble(document, [preamble])
935 document.header[i] = "\\font_roman default"
938 def revert_txtt(document):
939 " Revert native txtt font definition to LaTeX "
941 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
942 i = find_token(document.header, "\\font_typewriter txtt", 0)
944 preamble = "\\renewcommand{\\ttdefault}{txtt}"
945 add_to_preamble(document, [preamble])
946 document.header[i] = "\\font_typewriter default"
949 def revert_mathdesign(document):
950 " Revert native mathdesign font definition to LaTeX "
952 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
958 i = find_token(document.header, "\\font_roman", 0)
961 val = get_value(document.header, "\\font_roman", i)
962 if val in mathdesign_dict.keys():
963 preamble = "\\usepackage[%s" % mathdesign_dict[val]
965 j = find_token(document.header, "\\font_osf true", 0)
968 document.header[j] = "\\font_osf false"
969 l = find_token(document.header, "\\font_sc true", 0)
972 document.header[l] = "\\font_sc false"
974 preamble += ",expert"
975 preamble += "]{mathdesign}"
976 add_to_preamble(document, [preamble])
977 document.header[i] = "\\font_roman default"
980 def revert_texgyre(document):
981 " Revert native TeXGyre font definition to LaTeX "
983 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
984 texgyre_fonts = ["tgadventor", "tgbonum", "tgchorus", "tgcursor", \
985 "tgheros", "tgpagella", "tgschola", "tgtermes"]
986 i = find_token(document.header, "\\font_roman", 0)
988 val = get_value(document.header, "\\font_roman", i)
989 if val in texgyre_fonts:
990 preamble = "\\usepackage{%s}" % val
991 add_to_preamble(document, [preamble])
992 document.header[i] = "\\font_roman default"
993 i = find_token(document.header, "\\font_sans", 0)
995 val = get_value(document.header, "\\font_sans", i)
996 if val in texgyre_fonts:
997 preamble = "\\usepackage{%s}" % val
998 add_to_preamble(document, [preamble])
999 document.header[i] = "\\font_sans default"
1000 i = find_token(document.header, "\\font_typewriter", 0)
1002 val = get_value(document.header, "\\font_typewriter", i)
1003 if val in texgyre_fonts:
1004 preamble = "\\usepackage{%s}" % val
1005 add_to_preamble(document, [preamble])
1006 document.header[i] = "\\font_typewriter default"
1009 def revert_ipadeco(document):
1010 " Revert IPA decorations to ERT "
1013 i = find_token(document.body, "\\begin_inset IPADeco", i)
1016 end = find_end_of_inset(document.body, i)
1018 document.warning("Can't find end of inset at line " + str(i))
1021 line = document.body[i]
1022 rx = re.compile(r'\\begin_inset IPADeco (.*)$')
1024 decotype = m.group(1)
1025 if decotype != "toptiebar" and decotype != "bottomtiebar":
1026 document.warning("Invalid IPADeco type: " + decotype)
1029 blay = find_token(document.body, "\\begin_layout Plain Layout", i, end)
1031 document.warning("Can't find layout for inset at line " + str(i))
1034 bend = find_end_of_layout(document.body, blay)
1036 document.warning("Malformed LyX document: Could not find end of IPADeco inset's layout.")
1039 substi = ["\\begin_inset ERT", "status collapsed", "",
1040 "\\begin_layout Plain Layout", "", "", "\\backslash",
1041 decotype + "{", "\\end_layout", "", "\\end_inset"]
1042 substj = ["\\size default", "", "\\begin_inset ERT", "status collapsed", "",
1043 "\\begin_layout Plain Layout", "", "}", "\\end_layout", "", "\\end_inset"]
1044 # do the later one first so as not to mess up the numbering
1045 document.body[bend:end + 1] = substj
1046 document.body[i:blay + 1] = substi
1047 i = end + len(substi) + len(substj) - (end - bend) - (blay - i) - 2
1048 add_to_preamble(document, "\\usepackage{tipa}")
1051 def revert_ipachar(document):
1052 ' Revert \\IPAChar to ERT '
1055 while i < len(document.body):
1056 m = re.match(r'(.*)\\IPAChar \\(\w+\{\w+\})(.*)', document.body[i])
1060 ipachar = m.group(2)
1063 '\\begin_inset ERT',
1064 'status collapsed', '',
1065 '\\begin_layout Standard',
1066 '', '', '\\backslash',
1071 document.body[i: i+1] = subst
1076 add_to_preamble(document, "\\usepackage{tone}")
1079 def revert_minionpro(document):
1080 " Revert native MinionPro font definition to LaTeX "
1082 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1083 i = find_token(document.header, "\\font_roman minionpro", 0)
1086 j = find_token(document.header, "\\font_osf true", 0)
1089 preamble = "\\usepackage"
1091 document.header[j] = "\\font_osf false"
1094 preamble += "{MinionPro}"
1095 add_to_preamble(document, [preamble])
1096 document.header[i] = "\\font_roman default"
1099 def revert_mathfonts(document):
1100 " Revert native math font definitions to LaTeX "
1102 i = find_token(document.header, "\\font_math", 0)
1105 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1106 val = get_value(document.header, "\\font_math", i)
1107 if val == "eulervm":
1108 add_to_preamble(document, "\\usepackage{eulervm}")
1109 elif val == "default":
1111 "lmodern": "\\renewcommand{\\rmdefault}{lmr}",
1112 "minionpro": "\\usepackage[onlytext,lf]{MinionPro}",
1113 "minionpro-osf": "\\usepackage[onlytext]{MinionPro}",
1114 "palatino": "\\renewcommand{\\rmdefault}{ppl}",
1115 "palatino-osf": "\\renewcommand{\\rmdefault}{pplj}",
1116 "times": "\\renewcommand{\\rmdefault}{ptm}",
1117 "utopia": "\\renewcommand{\\rmdefault}{futs}",
1118 "utopia-osf": "\\renewcommand{\\rmdefault}{futj}",
1120 j = find_token(document.header, "\\font_roman", 0)
1122 rm = get_value(document.header, "\\font_roman", j)
1123 k = find_token(document.header, "\\font_osf true", 0)
1126 if rm in mathfont_dict.keys():
1127 add_to_preamble(document, mathfont_dict[rm])
1128 document.header[j] = "\\font_roman default"
1130 document.header[k] = "\\font_osf false"
1131 del document.header[i]
1134 def revert_mdnomath(document):
1135 " Revert mathdesign and fourier without math "
1137 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1139 "md-charter": "mdbch",
1140 "md-utopia": "mdput",
1141 "md-garamond": "mdugm"
1143 i = find_token(document.header, "\\font_roman", 0)
1146 val = get_value(document.header, "\\font_roman", i)
1147 if val in mathdesign_dict.keys():
1148 j = find_token(document.header, "\\font_math", 0)
1150 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1151 mval = get_value(document.header, "\\font_math", j)
1152 if mval == "default":
1153 document.header[i] = "\\font_roman default"
1154 add_to_preamble(document, "\\renewcommand{\\rmdefault}{%s}" % mathdesign_dict[val])
1156 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1159 def convert_mdnomath(document):
1160 " Change mathdesign font name "
1162 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1164 "mdbch": "md-charter",
1165 "mdput": "md-utopia",
1166 "mdugm": "md-garamond"
1168 i = find_token(document.header, "\\font_roman", 0)
1171 val = get_value(document.header, "\\font_roman", i)
1172 if val in mathdesign_dict.keys():
1173 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1176 def revert_newtxmath(document):
1177 " Revert native newtxmath definitions to LaTeX "
1179 i = find_token(document.header, "\\font_math", 0)
1182 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1183 val = get_value(document.header, "\\font_math", i)
1185 "libertine-ntxm": "\\usepackage[libertine]{newtxmath}",
1186 "minion-ntxm": "\\usepackage[minion]{newtxmath}",
1187 "newtxmath": "\\usepackage{newtxmath}",
1189 if val in mathfont_dict.keys():
1190 add_to_preamble(document, mathfont_dict[val])
1191 document.header[i] = "\\font_math auto"
1194 def revert_biolinum(document):
1195 " Revert native biolinum font definition to LaTeX "
1197 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1198 i = find_token(document.header, "\\font_sans biolinum", 0)
1201 j = find_token(document.header, "\\font_osf true", 0)
1204 preamble = "\\usepackage"
1207 preamble += "{biolinum-type1}"
1208 add_to_preamble(document, [preamble])
1209 document.header[i] = "\\font_sans default"
1212 def revert_uop(document):
1213 " Revert native URW Classico (Optima) font definition to LaTeX "
1215 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1216 i = find_token(document.header, "\\font_sans uop", 0)
1218 preamble = "\\renewcommand{\\sfdefault}{uop}"
1219 add_to_preamble(document, [preamble])
1220 document.header[i] = "\\font_sans default"
1223 def convert_latexargs(document):
1224 " Convert InsetArgument to new syntax "
1226 if find_token(document.body, "\\begin_inset Argument", 0) == -1:
1230 # A list of layouts (document classes) with only optional or no arguments.
1231 # These can be safely converted to the new syntax
1232 # (I took the liberty to add some of my personal layouts/modules here; JSP)
1233 safe_layouts = ["aa", "aapaper", "aastex", "achemso", "acmsiggraph", "AEA",
1234 "agu-dtd", "agums", "agutex", "amsart", "amsbook", "apa",
1235 "arab-article", "armenian-article", "article-beamer", "article",
1236 "beamer", "book", "broadway", "chess", "cl2emult", "ctex-article",
1237 "ctex-book", "ctex-report", "dinbrief", "docbook-book", "docbook-chapter",
1238 "docbook", "docbook-section", "doublecol-new", "dtk", "ectaart", "egs",
1239 "elsarticle", "elsart", "entcs", "europecv", "extarticle", "extbook",
1240 "extletter", "extreport", "foils", "frletter", "g-brief2", "g-brief",
1241 "heb-article", "heb-letter", "hollywood", "IEEEtran", "ijmpc", "ijmpd",
1242 "iopart", "isprs", "jarticle", "jasatex", "jbook", "jgrga", "jreport",
1243 "jsarticle", "jsbeamer", "jsbook", "jss", "kluwer", "latex8", "letter", "lettre",
1244 "literate-article", "literate-book", "literate-report", "llncs", "ltugboat",
1245 "memoir", "moderncv", "mwart", "mwbk", "mwrep", "paper", "powerdot",
1246 "recipebook", "report", "revtex4", "revtex", "scrartcl", "scrarticle-beamer",
1247 "scrbook", "scrlettr", "scrlttr2", "scrreprt", "seminar", "siamltex",
1248 "sigplanconf", "simplecv", "singlecol", "singlecol-new", "slides", "spie",
1249 "svglobal3", "svglobal", "svjog", "svmono", "svmult", "svprobth", "tarticle",
1250 "tbook", "treport", "tufte-book", "tufte-handout"]
1251 # A list of "safe" modules, same as above
1252 safe_modules = ["biblatex", "beameraddons", "beamersession", "braille", "customHeadersFooters",
1253 "endnotes", "enumitem", "eqs-within-sections", "figs-within-sections", "fix-cm",
1254 "fixltx2e", "foottoend", "hanging", "jscharstyles", "knitr", "lilypond",
1255 "linguistics", "linguisticx", "logicalmkup", "minimalistic", "nomindex", "noweb",
1256 "pdfcomment", "sweave", "tabs-within-sections", "theorems-ams-bytype",
1257 "theorems-ams-extended-bytype", "theorems-ams-extended", "theorems-ams", "theorems-bytype",
1258 "theorems-chap-bytype", "theorems-chap", "theorems-named", "theorems-sec-bytype",
1259 "theorems-sec", "theorems-starred", "theorems-std", "todonotes"]
1260 # Modules we need to take care of
1261 caveat_modules = ["initials"]
1262 # information about the relevant styles in caveat_modules (number of opt and req args)
1263 # use this if we get more caveat_modules. For now, use hard coding (see below).
1264 # initials = [{'Layout' : 'Initial', 'opt' : 1, 'req' : 1}]
1266 # Is this a known safe layout?
1267 safe_layout = document.textclass in safe_layouts
1269 document.warning("Lyx2lyx knows nothing about textclass '%s'. "
1270 "Please check if short title insets have been converted correctly."
1271 % document.textclass)
1272 # Do we use unsafe or unknown modules
1273 mods = document.get_module_list()
1274 unknown_modules = False
1275 used_caveat_modules = list()
1277 if mod in safe_modules:
1279 if mod in caveat_modules:
1280 used_caveat_modules.append(mod)
1282 unknown_modules = True
1283 document.warning("Lyx2lyx knows nothing about module '%s'. "
1284 "Please check if short title insets have been converted correctly."
1289 i = find_token(document.body, "\\begin_inset Argument", i)
1293 if not safe_layout or unknown_modules:
1294 # We cannot do more here since we have no access to this layout.
1295 # InsetArgument itself will do the real work
1296 # (see InsetArgument::updateBuffer())
1297 document.body[i] = "\\begin_inset Argument 999"
1301 # Find containing paragraph layout
1302 parent = get_containing_layout(document.body, i)
1304 document.warning("Malformed LyX document: Can't find parent paragraph layout")
1311 if len(used_caveat_modules) > 0:
1312 # We know for now that this must be the initials module with the Initial layout
1313 # If we get more such modules, we need some automating.
1314 if parent[0] == "Initial":
1315 # Layout has 1 opt and 1 req arg.
1316 # Count the actual arguments
1318 for p in range(parbeg, parend):
1319 if document.body[p] == "\\begin_inset Argument":
1324 # Collect all arguments in this paragraph
1326 for p in range(parbeg, parend):
1327 if document.body[p] == "\\begin_inset Argument":
1329 if allowed_opts != -1:
1330 # We have less arguments than opt + required.
1331 # required must take precedence.
1332 if argnr > allowed_opts and argnr < first_req:
1334 document.body[p] = "\\begin_inset Argument %d" % argnr
1338 def revert_latexargs(document):
1339 " Revert InsetArgument to old syntax "
1342 rx = re.compile(r'^\\begin_inset Argument (\d+)$')
1345 # Search for Argument insets
1346 i = find_token(document.body, "\\begin_inset Argument", i)
1349 m = rx.match(document.body[i])
1351 # No ID: inset already reverted
1354 # Find containing paragraph layout
1355 parent = get_containing_layout(document.body, i)
1357 document.warning("Malformed LyX document: Can't find parent paragraph layout")
1362 realparbeg = parent[3]
1363 # Collect all arguments in this paragraph
1365 for p in range(parbeg, parend):
1366 m = rx.match(document.body[p])
1368 val = int(m.group(1))
1369 j = find_end_of_inset(document.body, p)
1370 # Revert to old syntax
1371 document.body[p] = "\\begin_inset Argument"
1373 document.warning("Malformed LyX document: Can't find end of Argument inset")
1376 args[val] = document.body[p : j + 1]
1378 realparend = realparend - len(document.body[p : j + 1])
1379 # Remove arg inset at this position
1380 del document.body[p : j + 1]
1383 # Now sort the arg insets
1385 for f in sorted(args):
1388 # Insert the sorted arg insets at paragraph begin
1389 document.body[realparbeg : realparbeg] = subst
1391 i = realparbeg + 1 + len(subst)
1394 def revert_Argument_to_TeX_brace(document, line, endline, n, nmax, environment, opt):
1396 Reverts an InsetArgument to TeX-code
1398 revert_Argument_to_TeX_brace(document, LineOfBegin, LineOfEnd, StartArgument, EndArgument, isEnvironment, isOpt)
1399 LineOfBegin is the line of the \begin_layout or \begin_inset statement
1400 LineOfEnd is the line of the \end_layout or \end_inset statement, if "0" is given, the end of the file is used instead
1401 StartArgument is the number of the first argument that needs to be converted
1402 EndArgument is the number of the last argument that needs to be converted or the last defined one
1403 isEnvironment must be true, if the layout is for a LaTeX environment
1404 isOpt must be true, if the argument is an optional one
1408 while lineArg != -1 and n < nmax + 1:
1409 lineArg = find_token(document.body, "\\begin_inset Argument " + str(n), line)
1410 if lineArg > endline and endline != 0:
1413 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", lineArg)
1414 # we have to assure that no other inset is in the Argument
1415 beginInset = find_token(document.body, "\\begin_inset", beginPlain)
1416 endInset = find_token(document.body, "\\end_inset", beginPlain)
1419 while beginInset < endInset and beginInset != -1:
1420 beginInset = find_token(document.body, "\\begin_inset", k)
1421 endInset = find_token(document.body, "\\end_inset", l)
1424 if environment == False:
1426 document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("}{")
1427 del(document.body[lineArg : beginPlain + 1])
1430 document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("]")
1431 document.body[lineArg : beginPlain + 1] = put_cmd_in_ert("[")
1434 document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("}")
1435 document.body[lineArg : beginPlain + 1] = put_cmd_in_ert("{")
1441 def convert_TeX_brace_to_Argument(document, line, n, nmax, inset, environment):
1443 Converts TeX code for mandatory arguments to an InsetArgument
1444 The conversion of TeX code for optional arguments must be done with another routine
1445 !!! Be careful if the braces are different in your case as expected here:
1446 - "}{" separates mandatory arguments of commands
1447 - "}" + "{" separates mandatory arguments of commands
1448 - "}" + " " + "{" separates mandatory arguments of commands
1449 - { and } surround a mandatory argument of an environment
1451 convert_TeX_brace_to_Argument(document, LineOfBeginLayout/Inset, StartArgument, EndArgument, isInset, isEnvironment)
1452 LineOfBeginLayout/Inset is the line of the \begin_layout or \begin_inset statement
1453 StartArgument is the number of the first ERT that needs to be converted
1454 EndArgument is the number of the last ERT that needs to be converted
1455 isInset must be true, if braces inside an InsetLayout needs to be converted
1456 isEnvironment must be true, if the layout is for a LaTeX environment
1458 Todo: this routine can currently handle only one mandatory argument of environments
1463 while lineERT != -1 and n < nmax + 1:
1464 lineERT = find_token(document.body, "\\begin_inset ERT", lineERT)
1465 if environment == False and lineERT != -1:
1466 bracePair = find_token(document.body, "}{", lineERT)
1467 # assure that the "}{" is in this ERT
1468 if bracePair == lineERT + 5:
1469 end = find_token(document.body, "\\end_inset", bracePair)
1470 document.body[lineERT : end + 1] = ["\\end_layout", "", "\\end_inset"]
1472 # in the case that n > 1 we have optional arguments before
1473 # therefore detect them if any
1475 # first check if there is an argument
1476 lineArg = find_token(document.body, "\\begin_inset Argument", line)
1477 if lineArg < lineERT and lineArg != -1:
1478 # we have an argument, so now search backwards for its end
1479 # we must now assure that we don't find other insets like e.g. a newline
1480 endInsetArg = lineERT
1481 endLayoutArg = endInsetArg
1482 while endInsetArg != endLayoutArg + 2 and endInsetArg != -1:
1483 endInsetArg = endInsetArg - 1
1484 endLayoutArg = endInsetArg
1485 endInsetArg = find_token_backwards(document.body, "\\end_inset", endInsetArg)
1486 endLayoutArg = find_token_backwards(document.body, "\\end_layout", endLayoutArg)
1487 line = endInsetArg + 1
1489 document.body[line + 1 : line + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1491 document.body[line + 4 : line + 4] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1493 document.body[endn : endn] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1497 # now check the case that we have "}" + "{" in two ERTs
1499 endBrace = find_token(document.body, "}", lineERT)
1500 if endBrace == lineERT + 5:
1501 beginBrace = find_token(document.body, "{", endBrace)
1502 # assure that the ERTs are consecutive (11 or 12 depending if there is a space between the ERTs or not)
1503 if beginBrace == endBrace + 11 or beginBrace == endBrace + 12:
1504 end = find_token(document.body, "\\end_inset", beginBrace)
1505 document.body[lineERT : end + 1] = ["\\end_layout", "", "\\end_inset"]
1507 # in the case that n > 1 we have optional arguments before
1508 # therefore detect them if any
1510 # first check if there is an argument
1511 lineArg = find_token(document.body, "\\begin_inset Argument", line)
1512 if lineArg < lineERT and lineArg != -1:
1513 # we have an argument, so now search backwards for its end
1514 # we must now assure that we don't find other insets like e.g. a newline
1515 endInsetArg = lineERT
1516 endLayoutArg = endInsetArg
1517 while endInsetArg != endLayoutArg + 2 and endInsetArg != -1:
1518 endInsetArg = endInsetArg - 1
1519 endLayoutArg = endInsetArg
1520 endInsetArg = find_token_backwards(document.body, "\\end_inset", endInsetArg)
1521 endLayoutArg = find_token_backwards(document.body, "\\end_layout", endLayoutArg)
1522 line = endInsetArg + 1
1524 document.body[line + 1 : line + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1526 document.body[line + 4 : line + 4] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1528 document.body[endn : endn] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1531 # set the line where the next argument will be inserted
1532 if beginBrace == endBrace + 11:
1537 lineERT = lineERT + 1
1538 if environment == True and lineERT != -1:
1539 opening = find_token(document.body, "{", lineERT)
1540 if opening == lineERT + 5: # assure that the "{" is in this ERT
1541 end = find_token(document.body, "\\end_inset", opening)
1542 document.body[lineERT : end + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1544 lineERT2 = find_token(document.body, "\\begin_inset ERT", lineERT)
1545 closing = find_token(document.body, "}", lineERT2)
1546 if closing == lineERT2 + 5: # assure that the "}" is in this ERT
1547 end2 = find_token(document.body, "\\end_inset", closing)
1548 document.body[lineERT2 : end2 + 1] = ["\\end_layout", "", "\\end_inset"]
1550 lineERT = lineERT + 1
1553 def revert_IEEEtran(document):
1555 Reverts InsetArgument of
1558 Biography without photo
1561 if document.textclass == "IEEEtran":
1568 i = find_token(document.body, "\\begin_layout Page headings", i)
1570 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1573 i2 = find_token(document.body, "\\begin_inset Flex Paragraph Start", i2)
1575 revert_Argument_to_TeX_brace(document, i2, 0, 1, 1, False, False)
1578 j = find_token(document.body, "\\begin_layout Biography without photo", j)
1580 revert_Argument_to_TeX_brace(document, j, 0, 1, 1, True, False)
1583 k = find_token(document.body, "\\begin_layout Biography", k)
1584 kA = find_token(document.body, "\\begin_layout Biography without photo", k)
1585 if k == kA and k != -1:
1589 # start with the second argument, therefore 2
1590 revert_Argument_to_TeX_brace(document, k, 0, 2, 2, True, False)
1592 if i == -1 and i2 == -1 and j == -1 and k == -1:
1596 def revert_IEEEtran_2(document):
1598 Reverts Flex Paragraph Start to TeX-code
1600 if document.textclass == "IEEEtran":
1604 begin = find_token(document.body, "\\begin_inset Flex Paragraph Start", begin)
1606 end1 = find_end_of_inset(document.body, begin)
1607 document.body[end1 - 2 : end1 + 1] = put_cmd_in_ert("}")
1608 document.body[begin : begin + 4] = put_cmd_in_ert("\\IEEEPARstart{")
1614 def convert_IEEEtran(document):
1619 Biography without photo
1622 if document.textclass == "IEEEtran":
1628 i = find_token(document.body, "\\begin_layout Page headings", i)
1630 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1633 j = find_token(document.body, "\\begin_layout Biography without photo", j)
1635 convert_TeX_brace_to_Argument(document, j, 1, 1, False, True)
1638 # assure that we don't handle Biography Biography without photo
1639 k = find_token(document.body, "\\begin_layout Biography", k)
1640 kA = find_token(document.body, "\\begin_layout Biography without photo", k - 1)
1641 if k == kA and k != -1:
1645 # the argument we want to convert is the second one
1646 convert_TeX_brace_to_Argument(document, k, 2, 2, False, True)
1648 if i == -1 and j == -1 and k == -1:
1652 def revert_AASTeX(document):
1653 " Reverts InsetArgument of Altaffilation to TeX-code "
1654 if document.textclass == "aastex":
1658 i = find_token(document.body, "\\begin_layout Altaffilation", i)
1660 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1666 def convert_AASTeX(document):
1667 " Converts ERT of Altaffilation to InsetArgument "
1668 if document.textclass == "aastex":
1672 i = find_token(document.body, "\\begin_layout Altaffilation", i)
1674 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1680 def revert_AGUTeX(document):
1681 " Reverts InsetArgument of Author affiliation to TeX-code "
1682 if document.textclass == "agutex":
1686 i = find_token(document.body, "\\begin_layout Author affiliation", i)
1688 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1694 def convert_AGUTeX(document):
1695 " Converts ERT of Author affiliation to InsetArgument "
1696 if document.textclass == "agutex":
1700 i = find_token(document.body, "\\begin_layout Author affiliation", i)
1702 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1708 def revert_IJMP(document):
1709 " Reverts InsetArgument of MarkBoth to TeX-code "
1710 if document.textclass == "ijmpc" or document.textclass == "ijmpd":
1714 i = find_token(document.body, "\\begin_layout MarkBoth", i)
1716 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1722 def convert_IJMP(document):
1723 " Converts ERT of MarkBoth to InsetArgument "
1724 if document.textclass == "ijmpc" or document.textclass == "ijmpd":
1728 i = find_token(document.body, "\\begin_layout MarkBoth", i)
1730 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1736 def revert_SIGPLAN(document):
1737 " Reverts InsetArguments of SIGPLAN to TeX-code "
1738 if document.textclass == "sigplanconf":
1743 i = find_token(document.body, "\\begin_layout Conference", i)
1745 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1748 j = find_token(document.body, "\\begin_layout Author", j)
1750 revert_Argument_to_TeX_brace(document, j, 0, 1, 2, False, False)
1752 if i == -1 and j == -1:
1756 def convert_SIGPLAN(document):
1757 " Converts ERT of SIGPLAN to InsetArgument "
1758 if document.textclass == "sigplanconf":
1763 i = find_token(document.body, "\\begin_layout Conference", i)
1765 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1768 j = find_token(document.body, "\\begin_layout Author", j)
1770 convert_TeX_brace_to_Argument(document, j, 1, 2, False, False)
1772 if i == -1 and j == -1:
1776 def revert_SIGGRAPH(document):
1777 " Reverts InsetArgument of Flex CRcat to TeX-code "
1778 if document.textclass == "acmsiggraph":
1782 i = find_token(document.body, "\\begin_inset Flex CRcat", i)
1784 revert_Argument_to_TeX_brace(document, i, 0, 1, 3, False, False)
1790 def convert_SIGGRAPH(document):
1791 " Converts ERT of Flex CRcat to InsetArgument "
1792 if document.textclass == "acmsiggraph":
1796 i = find_token(document.body, "\\begin_inset Flex CRcat", i)
1798 convert_TeX_brace_to_Argument(document, i, 1, 3, True, False)
1804 def revert_EuropeCV(document):
1805 " Reverts InsetArguments of europeCV to TeX-code "
1806 if document.textclass == "europecv":
1813 i = find_token(document.body, "\\begin_layout Item", i)
1815 revert_Argument_to_TeX_brace(document, i, 0, 2, 2, False, False)
1818 j = find_token(document.body, "\\begin_layout BulletedItem", j)
1820 revert_Argument_to_TeX_brace(document, j, 0, 2, 2, False, False)
1823 k = find_token(document.body, "\\begin_layout Language", k)
1825 revert_Argument_to_TeX_brace(document, k, 0, 2, 6, False, False)
1828 m = find_token(document.body, "\\begin_layout LastLanguage", m)
1830 revert_Argument_to_TeX_brace(document, m, 0, 2, 6, False, False)
1832 if i == -1 and j == -1 and k == -1 and m == -1:
1836 def convert_EuropeCV(document):
1837 " Converts ERT of europeCV to InsetArgument "
1838 if document.textclass == "europecv":
1845 i = find_token(document.body, "\\begin_layout Item", i)
1847 convert_TeX_brace_to_Argument(document, i, 2, 2, False, False)
1850 j = find_token(document.body, "\\begin_layout BulletedItem", j)
1852 convert_TeX_brace_to_Argument(document, j, 2, 2, False, False)
1855 k = find_token(document.body, "\\begin_layout Language", k)
1857 convert_TeX_brace_to_Argument(document, k, 2, 6, False, False)
1860 m = find_token(document.body, "\\begin_layout LastLanguage", m)
1862 convert_TeX_brace_to_Argument(document, m, 2, 6, False, False)
1864 if i == -1 and j == -1 and k == -1 and m == -1:
1868 def revert_ModernCV(document):
1869 " Reverts InsetArguments of modernCV to TeX-code "
1870 if document.textclass == "moderncv":
1878 j = find_token(document.body, "\\begin_layout Entry", j)
1880 revert_Argument_to_TeX_brace(document, j, 0, 1, 5, False, False)
1883 k = find_token(document.body, "\\begin_layout Item", k)
1885 revert_Argument_to_TeX_brace(document, k, 0, 1, 1, False, False)
1888 m = find_token(document.body, "\\begin_layout ItemWithComment", m)
1890 revert_Argument_to_TeX_brace(document, m, 0, 1, 2, False, False)
1891 document.body[m] = document.body[m].replace("\\begin_layout ItemWithComment", "\\begin_layout Language")
1894 o = find_token(document.body, "\\begin_layout DoubleItem", o)
1896 revert_Argument_to_TeX_brace(document, o, 0, 1, 3, False, False)
1897 document.body[o] = document.body[o].replace("\\begin_layout DoubleItem", "\\begin_layout Computer")
1900 p = find_token(document.body, "\\begin_layout Social", p)
1902 revert_Argument_to_TeX_brace(document, p, 0, 1, 1, False, True)
1904 if j == -1 and k == -1 and m == -1 and o == -1 and p == -1:
1908 def revert_ModernCV_2(document):
1909 " Reverts the Flex:Column inset of modernCV to TeX-code "
1910 if document.textclass == "moderncv":
1915 flex = find_token(document.body, "\\begin_inset Flex Column", flex)
1917 flexEnd = find_end_of_inset(document.body, flex)
1918 wasOpt = revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, False, True)
1919 revert_Argument_to_TeX_brace(document, flex, 0, 2, 2, False, False)
1920 flexEnd = find_end_of_inset(document.body, flex)
1922 document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\cvcolumn")
1924 document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\cvcolumn{")
1925 document.body[flexEnd + 4 : flexEnd + 7] = put_cmd_in_ert("}")
1931 def revert_ModernCV_3(document):
1932 " Reverts the Column style of modernCV to TeX-code "
1933 if document.textclass == "moderncv":
1934 # revert the layouts
1935 revert_ModernCV(document)
1937 # get the position of the end of the last column inset
1938 LastFlexEnd = revert_ModernCV_2(document)
1941 p = find_token(document.body, "\\begin_layout Columns", p)
1943 pEnd = find_end_of_layout(document.body, p)
1944 document.body[p] = document.body[p].replace("\\begin_layout Columns", "\\begin_layout Standard")
1945 if LastFlexEnd != -1:
1946 document.body[p + 1 : p + 1] = put_cmd_in_ert("\\begin{cvcolumns}")
1947 document.body[LastFlexEnd + 24 : LastFlexEnd + 24] = put_cmd_in_ert("\\end{cvcolumns}")
1953 def revert_ModernCV_4(document):
1954 " Reverts the style Social to TeX-code "
1955 if document.textclass == "moderncv":
1956 # revert the layouts
1957 revert_ModernCV(document)
1961 p = find_token(document.body, "\\begin_layout Social", p)
1963 pEnd = find_end_of_layout(document.body, p)
1964 document.body[p] = document.body[p].replace("\\begin_layout Social", "\\begin_layout Standard")
1965 document.body[p + 1 : p + 1] = put_cmd_in_ert("\\social")
1966 hasOpt = find_token(document.body, "[", p + 9)
1968 document.body[p + 30 : p + 30] = put_cmd_in_ert("{")
1969 document.body[p + 41 : p + 41] = put_cmd_in_ert("}")
1971 document.body[p + 11 : p + 11] = put_cmd_in_ert("{")
1972 document.body[p + 21 : p + 21] = put_cmd_in_ert("}")
1978 def convert_ModernCV(document):
1979 " Converts ERT of modernCV to InsetArgument "
1980 if document.textclass == "moderncv":
1988 i = find_token(document.body, "\\begin_layout DoubleItem", i)
1990 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1991 document.body[o] = document.body[o].replace("\\begin_layout DoubleItem", "\\begin_layout DoubleListItem")
1994 j = find_token(document.body, "\\begin_layout Entry", j)
1996 convert_TeX_brace_to_Argument(document, j, 1, 5, False, False)
1999 k = find_token(document.body, "\\begin_layout Item", k)
2001 convert_TeX_brace_to_Argument(document, k, 1, 1, False, False)
2004 m = find_token(document.body, "\\begin_layout Language", m)
2006 convert_TeX_brace_to_Argument(document, m, 1, 2, False, False)
2008 if i == -1 and j == -1 and k == -1 and m == -1:
2012 def revert_Initials(document):
2013 " Reverts InsetArgument of Initial to TeX-code "
2017 i = find_token(document.body, "\\begin_layout Initial", i)
2019 # first arg (optional) and second arg (first mandatory) are supported in LyX 2.0.x
2020 revert_Argument_to_TeX_brace(document, i, 0, 3, 3, False, False)
2026 def convert_Initials(document):
2027 " Converts ERT of Initial to InsetArgument "
2031 i = find_token(document.body, "\\begin_layout Initial", i)
2033 convert_TeX_brace_to_Argument(document, i, 3, 3, False, False)
2039 def revert_literate(document):
2040 " Revert Literate document to old format "
2041 if del_token(document.header, "noweb", 0):
2042 document.textclass = "literate-" + document.textclass
2045 i = find_token(document.body, "\\begin_layout Chunk", i)
2048 document.body[i] = "\\begin_layout Scrap"
2052 def convert_literate(document):
2053 " Convert Literate document to new format"
2054 i = find_token(document.header, "\\textclass", 0)
2055 if (i != -1) and "literate-" in document.header[i]:
2056 document.textclass = document.header[i].replace("\\textclass literate-", "")
2057 j = find_token(document.header, "\\begin_modules", 0)
2059 document.header.insert(j + 1, "noweb")
2061 document.header.insert(i + 1, "\\end_modules")
2062 document.header.insert(i + 1, "noweb")
2063 document.header.insert(i + 1, "\\begin_modules")
2066 i = find_token(document.body, "\\begin_layout Scrap", i)
2069 document.body[i] = "\\begin_layout Chunk"
2073 def revert_itemargs(document):
2074 " Reverts \\item arguments to TeX-code "
2077 i = find_token(document.body, "\\begin_inset Argument item:", i)
2080 j = find_end_of_inset(document.body, i)
2081 # Find containing paragraph layout
2082 parent = get_containing_layout(document.body, i)
2084 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2088 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2089 endPlain = find_end_of_layout(document.body, beginPlain)
2090 content = document.body[beginPlain + 1 : endPlain]
2091 del document.body[i:j+1]
2092 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2093 document.body[parbeg : parbeg] = subst
2097 def revert_garamondx_newtxmath(document):
2098 " Revert native garamond newtxmath definition to LaTeX "
2100 i = find_token(document.header, "\\font_math", 0)
2103 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
2104 val = get_value(document.header, "\\font_math", i)
2105 if val == "garamondx-ntxm":
2106 add_to_preamble(document, "\\usepackage[garamondx]{newtxmath}")
2107 document.header[i] = "\\font_math auto"
2110 def revert_garamondx(document):
2111 " Revert native garamond font definition to LaTeX "
2113 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
2114 i = find_token(document.header, "\\font_roman garamondx", 0)
2117 j = find_token(document.header, "\\font_osf true", 0)
2120 preamble = "\\usepackage"
2122 preamble += "[osfI]"
2123 preamble += "{garamondx}"
2124 add_to_preamble(document, [preamble])
2125 document.header[i] = "\\font_roman default"
2128 def convert_beamerargs(document):
2129 " Converts beamer arguments to new layout "
2131 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2132 if document.textclass not in beamer_classes:
2135 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
2136 list_layouts = ["Itemize", "Enumerate", "Description"]
2137 rx = re.compile(r'^\\begin_inset Argument (\d+)$')
2141 i = find_token(document.body, "\\begin_inset Argument", i)
2144 # Find containing paragraph layout
2145 parent = get_containing_layout(document.body, i)
2147 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2152 layoutname = parent[0]
2153 for p in range(parbeg, parend):
2154 if layoutname in shifted_layouts:
2155 m = rx.match(document.body[p])
2157 argnr = int(m.group(1))
2159 document.body[p] = "\\begin_inset Argument %d" % argnr
2160 if layoutname == "AgainFrame":
2161 m = rx.match(document.body[p])
2163 document.body[p] = "\\begin_inset Argument 3"
2164 if document.body[p + 4] == "\\begin_inset ERT":
2165 if document.body[p + 9].startswith("<"):
2166 # This is an overlay specification
2168 document.body[p + 9] = document.body[p + 9][1:]
2169 if document.body[p + 9].endswith(">"):
2171 document.body[p + 9] = document.body[p + 9][:-1]
2173 document.body[p] = "\\begin_inset Argument 2"
2174 if layoutname in list_layouts:
2175 m = rx.match(document.body[p])
2177 if m.group(1) == "1":
2178 if document.body[p + 4] == "\\begin_inset ERT":
2179 if document.body[p + 9].startswith("<"):
2180 # This is an overlay specification
2182 document.body[p + 9] = document.body[p + 9][1:]
2183 if document.body[p + 9].endswith(">"):
2185 document.body[p + 9] = document.body[p + 9][:-1]
2186 elif layoutname != "Itemize":
2188 document.body[p] = "\\begin_inset Argument 2"
2192 def convert_againframe_args(document):
2193 " Converts beamer AgainFrame to new layout "
2195 # FIXME: This currently only works if the arguments are in one single ERT
2197 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2198 if document.textclass not in beamer_classes:
2203 i = find_token(document.body, "\\begin_layout AgainFrame", i)
2206 parent = get_containing_layout(document.body, i)
2208 document.warning("Wrong parent layout!")
2212 if document.body[parbeg] == "\\begin_inset ERT":
2213 ertcont = parbeg + 5
2214 if document.body[ertcont].startswith("[<"):
2215 # This is a default overlay specification
2217 document.body[ertcont] = document.body[ertcont][2:]
2218 if document.body[ertcont].endswith(">]"):
2220 document.body[ertcont] = document.body[ertcont][:-2]
2221 elif document.body[ertcont].endswith("]"):
2223 tok = document.body[ertcont].find('>][')
2225 subst = [document.body[ertcont][:tok],
2226 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2227 'status collapsed', '', '\\begin_layout Plain Layout',
2228 document.body[ertcont][tok + 3:-1]]
2229 document.body[ertcont : ertcont + 1] = subst
2230 # Convert to ArgInset
2231 document.body[parbeg] = "\\begin_inset Argument 2"
2234 elif document.body[ertcont].startswith("<"):
2235 # This is an overlay specification
2237 document.body[ertcont] = document.body[ertcont][1:]
2238 if document.body[ertcont].endswith(">"):
2240 document.body[ertcont] = document.body[ertcont][:-1]
2241 # Convert to ArgInset
2242 document.body[parbeg] = "\\begin_inset Argument 1"
2243 elif document.body[ertcont].endswith(">]"):
2245 tok = document.body[ertcont].find('>[<')
2247 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2248 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2249 'status collapsed', '', '\\begin_layout Plain Layout',
2250 document.body[ertcont][tok + 3:-2]]
2251 # Convert to ArgInset
2252 document.body[parbeg] = "\\begin_inset Argument 1"
2253 elif document.body[ertcont].endswith("]"):
2255 tok = document.body[ertcont].find('>[<')
2258 tokk = document.body[ertcont].find('>][')
2260 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2261 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2262 'status collapsed', '', '\\begin_layout Plain Layout',
2263 document.body[ertcont][tok + 3:tokk],
2264 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2265 'status collapsed', '', '\\begin_layout Plain Layout',
2266 document.body[ertcont][tokk + 3:-1]]
2268 tokk = document.body[ertcont].find('>[')
2270 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tokk],
2271 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2272 'status collapsed', '', '\\begin_layout Plain Layout',
2273 document.body[ertcont][tokk + 2:-1]]
2274 # Convert to ArgInset
2275 document.body[parbeg] = "\\begin_inset Argument 1"
2278 elif document.body[ertcont].startswith("["):
2279 # This is an ERT option
2281 document.body[ertcont] = document.body[ertcont][1:]
2282 if document.body[ertcont].endswith("]"):
2284 document.body[ertcont] = document.body[ertcont][:-1]
2285 # Convert to ArgInset
2286 document.body[parbeg] = "\\begin_inset Argument 3"
2292 def convert_corollary_args(document):
2293 " Converts beamer corrolary-style ERT arguments native InsetArgs "
2295 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2296 if document.textclass not in beamer_classes:
2299 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2300 for lay in corollary_layouts:
2303 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2306 parent = get_containing_layout(document.body, i)
2308 document.warning("Wrong parent layout!")
2312 if document.body[parbeg] == "\\begin_inset ERT":
2313 ertcont = parbeg + 5
2314 if document.body[ertcont].startswith("<"):
2315 # This is an overlay specification
2317 document.body[ertcont] = document.body[ertcont][1:]
2318 if document.body[ertcont].endswith(">"):
2320 document.body[ertcont] = document.body[ertcont][:-1]
2321 elif document.body[ertcont].endswith("]"):
2323 tok = document.body[ertcont].find('>[')
2325 subst = [document.body[ertcont][:tok],
2326 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2327 'status collapsed', '', '\\begin_layout Plain Layout',
2328 document.body[ertcont][tok + 2:-1]]
2329 document.body[ertcont : ertcont + 1] = subst
2330 # Convert to ArgInset
2331 document.body[parbeg] = "\\begin_inset Argument 1"
2334 elif document.body[ertcont].startswith("["):
2335 # This is an ERT option
2337 document.body[ertcont] = document.body[ertcont][1:]
2338 if document.body[ertcont].endswith("]"):
2340 document.body[ertcont] = document.body[ertcont][:-1]
2341 # Convert to ArgInset
2342 document.body[parbeg] = "\\begin_inset Argument 2"
2349 def convert_quote_args(document):
2350 " Converts beamer quote style ERT args to native InsetArgs "
2352 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2353 if document.textclass not in beamer_classes:
2356 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2357 for lay in quote_layouts:
2360 i = find_token(document.body, "\\begin_layout " + lay, i)
2363 parent = get_containing_layout(document.body, i)
2365 document.warning("Wrong parent layout!")
2369 if document.body[parbeg] == "\\begin_inset ERT":
2370 if document.body[i + 6].startswith("<"):
2371 # This is an overlay specification
2373 document.body[i + 6] = document.body[i + 6][1:]
2374 if document.body[i + 6].endswith(">"):
2376 document.body[i + 6] = document.body[i + 6][:-1]
2377 # Convert to ArgInset
2378 document.body[i + 1] = "\\begin_inset Argument 1"
2382 def revert_beamerargs(document):
2383 " Reverts beamer arguments to old layout "
2385 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2386 if document.textclass not in beamer_classes:
2390 list_layouts = ["Itemize", "Enumerate", "Description"]
2391 headings = ["Part", "Section", "Section*", "Subsection", "Subsection*",
2392 "Subsubsection", "Subsubsection*", "FrameSubtitle", "NoteItem"]
2393 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2394 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2395 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2398 i = find_token(document.body, "\\begin_inset Argument", i)
2401 # Find containing paragraph layout
2402 parent = get_containing_layout(document.body, i)
2404 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2409 realparbeg = parent[3]
2410 layoutname = parent[0]
2412 for p in range(parbeg, parend):
2416 if layoutname in headings:
2417 m = rx.match(document.body[p])
2421 # Find containing paragraph layout
2422 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2423 endPlain = find_end_of_layout(document.body, beginPlain)
2424 endInset = find_end_of_inset(document.body, p)
2425 argcontent = document.body[beginPlain + 1 : endPlain]
2427 realparend = realparend - len(document.body[p : endInset + 1])
2429 del document.body[p : endInset + 1]
2430 if layoutname == "FrameSubtitle":
2431 pre = put_cmd_in_ert("\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2432 elif layoutname == "NoteItem":
2433 pre = put_cmd_in_ert("\\note<") + argcontent + put_cmd_in_ert(">[item]")
2434 elif layoutname.endswith('*'):
2435 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower()[:-1] + "<") + argcontent + put_cmd_in_ert(">*")
2437 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2438 secarg = find_token(document.body, "\\begin_inset Argument 2", parbeg, parend)
2440 # Find containing paragraph layout
2441 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", secarg)
2442 endPlain = find_end_of_layout(document.body, beginPlain)
2443 endInset = find_end_of_inset(document.body, secarg)
2444 argcontent = document.body[beginPlain + 1 : endPlain]
2446 realparend = realparend - len(document.body[secarg : endInset + 1])
2447 del document.body[secarg : endInset + 1]
2448 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2449 pre += put_cmd_in_ert("{")
2450 document.body[parbeg] = "\\begin_layout Standard"
2451 document.body[realparbeg : realparbeg] = pre
2452 pe = find_end_of_layout(document.body, parbeg)
2453 post = put_cmd_in_ert("}")
2454 document.body[pe : pe] = post
2455 realparend += len(pre) + len(post)
2456 if layoutname == "AgainFrame":
2457 m = rx.match(document.body[p])
2461 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2462 endPlain = find_end_of_layout(document.body, beginPlain)
2463 endInset = find_end_of_inset(document.body, p)
2464 content = document.body[beginPlain + 1 : endPlain]
2466 realparend = realparend - len(document.body[p : endInset + 1])
2468 del document.body[p : endInset + 1]
2469 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2470 document.body[realparbeg : realparbeg] = subst
2471 if layoutname == "Overprint":
2472 m = rx.match(document.body[p])
2476 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2477 endPlain = find_end_of_layout(document.body, beginPlain)
2478 endInset = find_end_of_inset(document.body, p)
2479 content = document.body[beginPlain + 1 : endPlain]
2481 realparend = realparend - len(document.body[p : endInset + 1])
2483 del document.body[p : endInset + 1]
2484 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2485 document.body[realparbeg : realparbeg] = subst
2486 if layoutname == "OverlayArea":
2487 m = rx.match(document.body[p])
2491 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2492 endPlain = find_end_of_layout(document.body, beginPlain)
2493 endInset = find_end_of_inset(document.body, p)
2494 content = document.body[beginPlain + 1 : endPlain]
2496 realparend = realparend - len(document.body[p : endInset + 1])
2498 del document.body[p : endInset + 1]
2499 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2500 document.body[realparbeg : realparbeg] = subst
2501 if layoutname in list_layouts:
2502 m = rx.match(document.body[p])
2506 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2507 endPlain = find_end_of_layout(document.body, beginPlain)
2508 endInset = find_end_of_inset(document.body, p)
2509 content = document.body[beginPlain + 1 : endPlain]
2510 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2511 realparend = realparend + len(subst) - len(content)
2512 document.body[beginPlain + 1 : endPlain] = subst
2513 elif argnr == "item:1":
2514 j = find_end_of_inset(document.body, i)
2515 # Find containing paragraph layout
2516 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2517 endPlain = find_end_of_layout(document.body, beginPlain)
2518 content = document.body[beginPlain + 1 : endPlain]
2519 del document.body[i:j+1]
2520 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2521 document.body[realparbeg : realparbeg] = subst
2522 elif argnr == "item:2":
2523 j = find_end_of_inset(document.body, i)
2524 # Find containing paragraph layout
2525 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2526 endPlain = find_end_of_layout(document.body, beginPlain)
2527 content = document.body[beginPlain + 1 : endPlain]
2528 del document.body[i:j+1]
2529 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2530 document.body[realparbeg : realparbeg] = subst
2531 if layoutname in quote_layouts:
2532 m = rx.match(document.body[p])
2536 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2537 endPlain = find_end_of_layout(document.body, beginPlain)
2538 endInset = find_end_of_inset(document.body, p)
2539 content = document.body[beginPlain + 1 : endPlain]
2541 realparend = realparend - len(document.body[p : endInset + 1])
2543 del document.body[p : endInset + 1]
2544 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2545 document.body[realparbeg : realparbeg] = subst
2546 if layoutname in corollary_layouts:
2547 m = rx.match(document.body[p])
2551 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2552 endPlain = find_end_of_layout(document.body, beginPlain)
2553 endInset = find_end_of_inset(document.body, p)
2554 content = document.body[beginPlain + 1 : endPlain]
2556 realparend = realparend - len(document.body[p : endInset + 1])
2558 del document.body[p : endInset + 1]
2559 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2560 document.body[realparbeg : realparbeg] = subst
2565 def revert_beamerargs2(document):
2566 " Reverts beamer arguments to old layout, step 2 "
2568 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2569 if document.textclass not in beamer_classes:
2573 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
2574 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2575 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2578 i = find_token(document.body, "\\begin_inset Argument", i)
2581 # Find containing paragraph layout
2582 parent = get_containing_layout(document.body, i)
2584 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2589 realparbeg = parent[3]
2590 layoutname = parent[0]
2592 for p in range(parbeg, parend):
2596 if layoutname in shifted_layouts:
2597 m = rx.match(document.body[p])
2601 document.body[p] = "\\begin_inset Argument 1"
2602 if layoutname in corollary_layouts:
2603 m = rx.match(document.body[p])
2607 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2608 endPlain = find_end_of_layout(document.body, beginPlain)
2609 endInset = find_end_of_inset(document.body, p)
2610 content = document.body[beginPlain + 1 : endPlain]
2612 realparend = realparend - len(document.body[p : endInset + 1])
2614 del document.body[p : endInset + 1]
2615 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2616 document.body[realparbeg : realparbeg] = subst
2617 if layoutname == "OverlayArea":
2618 m = rx.match(document.body[p])
2622 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2623 endPlain = find_end_of_layout(document.body, beginPlain)
2624 endInset = find_end_of_inset(document.body, p)
2625 content = document.body[beginPlain + 1 : endPlain]
2627 realparend = realparend - len(document.body[p : endInset + 1])
2629 del document.body[p : endInset + 1]
2630 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2631 document.body[realparbeg : realparbeg] = subst
2632 if layoutname == "AgainFrame":
2633 m = rx.match(document.body[p])
2637 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2638 endPlain = find_end_of_layout(document.body, beginPlain)
2639 endInset = find_end_of_inset(document.body, p)
2640 content = document.body[beginPlain + 1 : endPlain]
2642 realparend = realparend - len(document.body[p : endInset + 1])
2644 del document.body[p : endInset + 1]
2645 subst = put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
2646 document.body[realparbeg : realparbeg] = subst
2650 def revert_beamerargs3(document):
2651 " Reverts beamer arguments to old layout, step 3 "
2653 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2654 if document.textclass not in beamer_classes:
2657 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2660 i = find_token(document.body, "\\begin_inset Argument", i)
2663 # Find containing paragraph layout
2664 parent = get_containing_layout(document.body, i)
2666 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2671 realparbeg = parent[3]
2672 layoutname = parent[0]
2674 for p in range(parbeg, parend):
2678 if layoutname == "AgainFrame":
2679 m = rx.match(document.body[p])
2683 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2684 endPlain = find_end_of_layout(document.body, beginPlain)
2685 endInset = find_end_of_inset(document.body, p)
2686 content = document.body[beginPlain + 1 : endPlain]
2688 realparend = realparend - len(document.body[p : endInset + 1])
2690 del document.body[p : endInset + 1]
2691 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2692 document.body[realparbeg : realparbeg] = subst
2696 def revert_beamerflex(document):
2697 " Reverts beamer Flex insets "
2699 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2700 if document.textclass not in beamer_classes:
2703 new_flexes = {"Bold" : "\\textbf", "Emphasize" : "\\emph", "Only" : "\\only",
2704 "Uncover" : "\\uncover", "Visible" : "\\visible",
2705 "Invisible" : "\\invisible", "Alternative" : "\\alt",
2706 "Beamer_Note" : "\\note"}
2707 old_flexes = {"Alert" : "\\alert", "Structure" : "\\structure"}
2708 rx = re.compile(r'^\\begin_inset Flex (.+)$')
2712 i = find_token(document.body, "\\begin_inset Flex", i)
2715 m = rx.match(document.body[i])
2717 flextype = m.group(1)
2718 z = find_end_of_inset(document.body, i)
2720 document.warning("Can't find end of Flex " + flextype + " inset.")
2723 if flextype in new_flexes:
2724 pre = put_cmd_in_ert(new_flexes[flextype])
2725 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2727 argend = find_end_of_inset(document.body, arg)
2729 document.warning("Can't find end of Argument!")
2732 # Find containing paragraph layout
2733 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2734 endPlain = find_end_of_layout(document.body, beginPlain)
2735 argcontent = document.body[beginPlain + 1 : endPlain]
2737 z = z - len(document.body[arg : argend + 1])
2739 del document.body[arg : argend + 1]
2740 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2741 arg = find_token(document.body, "\\begin_inset Argument 2", i, z)
2743 argend = find_end_of_inset(document.body, arg)
2745 document.warning("Can't find end of Argument!")
2748 # Find containing paragraph layout
2749 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2750 endPlain = find_end_of_layout(document.body, beginPlain)
2751 argcontent = document.body[beginPlain + 1 : endPlain]
2753 z = z - len(document.body[arg : argend + 1])
2755 del document.body[arg : argend + 1]
2756 if flextype == "Alternative":
2757 pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
2759 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2760 pre += put_cmd_in_ert("{")
2761 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2762 endPlain = find_end_of_layout(document.body, beginPlain)
2764 z = z - len(document.body[i : beginPlain + 1])
2766 document.body[i : beginPlain + 1] = pre
2767 post = put_cmd_in_ert("}")
2768 document.body[z - 2 : z + 1] = post
2769 elif flextype in old_flexes:
2770 pre = put_cmd_in_ert(old_flexes[flextype])
2771 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2775 argend = find_end_of_inset(document.body, arg)
2777 document.warning("Can't find end of Argument!")
2780 # Find containing paragraph layout
2781 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2782 endPlain = find_end_of_layout(document.body, beginPlain)
2783 argcontent = document.body[beginPlain + 1 : endPlain]
2785 z = z - len(document.body[arg : argend + 1])
2787 del document.body[arg : argend + 1]
2788 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2789 pre += put_cmd_in_ert("{")
2790 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2791 endPlain = find_end_of_layout(document.body, beginPlain)
2793 z = z - len(document.body[i : beginPlain + 1])
2795 document.body[i : beginPlain + 1] = pre
2796 post = put_cmd_in_ert("}")
2797 document.body[z - 2 : z + 1] = post
2802 def revert_beamerblocks(document):
2803 " Reverts beamer block arguments to ERT "
2805 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2806 if document.textclass not in beamer_classes:
2809 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2811 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2814 i = find_token(document.body, "\\begin_inset Argument", i)
2817 # Find containing paragraph layout
2818 parent = get_containing_layout(document.body, i)
2820 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2825 realparbeg = parent[3]
2826 layoutname = parent[0]
2828 for p in range(parbeg, parend):
2832 if layoutname in blocks:
2833 m = rx.match(document.body[p])
2837 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2838 endPlain = find_end_of_layout(document.body, beginPlain)
2839 endInset = find_end_of_inset(document.body, p)
2840 content = document.body[beginPlain + 1 : endPlain]
2842 realparend = realparend - len(document.body[p : endInset + 1])
2844 del document.body[p : endInset + 1]
2845 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2846 document.body[realparbeg : realparbeg] = subst
2848 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2849 endPlain = find_end_of_layout(document.body, beginPlain)
2850 endInset = find_end_of_inset(document.body, p)
2851 content = document.body[beginPlain + 1 : endPlain]
2853 realparend = realparend - len(document.body[p : endInset + 1])
2855 del document.body[p : endInset + 1]
2856 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2857 document.body[realparbeg : realparbeg] = subst
2862 def convert_beamerblocks(document):
2863 " Converts beamer block ERT args to native InsetArgs "
2865 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2866 if document.textclass not in beamer_classes:
2869 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2873 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2876 parent = get_containing_layout(document.body, i)
2877 if parent == False or parent[1] != i:
2878 document.warning("Wrong parent layout!")
2884 if document.body[parbeg] == "\\begin_inset ERT":
2885 ertcont = parbeg + 5
2887 if document.body[ertcont].startswith("<"):
2888 # This is an overlay specification
2890 document.body[ertcont] = document.body[ertcont][1:]
2891 if document.body[ertcont].endswith(">"):
2893 document.body[ertcont] = document.body[ertcont][:-1]
2894 # Convert to ArgInset
2895 document.body[parbeg] = "\\begin_inset Argument 1"
2896 elif document.body[ertcont].endswith("}"):
2898 tok = document.body[ertcont].find('>{')
2900 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2901 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2902 'status collapsed', '', '\\begin_layout Plain Layout',
2903 document.body[ertcont][tok + 2:-1]]
2904 # Convert to ArgInset
2905 document.body[parbeg] = "\\begin_inset Argument 1"
2906 elif document.body[ertcont].startswith("{"):
2907 # This is the block title
2908 if document.body[ertcont].endswith("}"):
2909 # strip off the braces
2910 document.body[ertcont] = document.body[ertcont][1:-1]
2911 # Convert to ArgInset
2912 document.body[parbeg] = "\\begin_inset Argument 2"
2913 elif count_pars_in_inset(document.body, ertcont) > 1:
2914 # Multipar ERT. Skip this.
2917 convert_TeX_brace_to_Argument(document, i, 2, 2, False, True)
2920 j = find_end_of_layout(document.body, i)
2922 document.warning("end of layout not found!")
2923 k = find_token(document.body, "\\begin_inset Argument", i, j)
2925 document.warning("InsetArgument not found!")
2927 l = find_end_of_inset(document.body, k)
2928 m = find_token(document.body, "\\begin_inset ERT", l, j)
2936 def convert_overprint(document):
2937 " Convert old beamer overprint layouts to ERT "
2939 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2940 if document.textclass not in beamer_classes:
2945 i = find_token(document.body, "\\begin_layout Overprint", i)
2948 # Find end of sequence
2949 j = find_end_of_sequence(document.body, i)
2951 document.warning("Malformed LyX document. Cannot find end of Overprint sequence!")
2955 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
2957 if document.body[j] == "\\end_deeper":
2958 esubst = ["", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
2960 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
2961 endseq = endseq + len(esubst) - len(document.body[j : j])
2962 document.body[j : j] = esubst
2963 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
2965 argend = find_end_of_layout(document.body, argbeg)
2967 document.warning("Malformed LyX document. Cannot find end of Overprint argument!")
2970 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
2971 endPlain = find_end_of_layout(document.body, beginPlain)
2972 content = document.body[beginPlain + 1 : endPlain]
2974 endseq = endseq - len(document.body[argbeg : argend + 1])
2976 del document.body[argbeg : argend + 1]
2977 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2979 endseq = endseq - len(document.body[i : i])
2980 document.body[i : i] = subst + ["\\end_layout"]
2981 endseq += len(subst)
2983 for p in range(i, endseq):
2984 if document.body[p] == "\\begin_layout Overprint":
2985 document.body[p] = "\\begin_layout Standard"
2990 def revert_overprint(document):
2991 " Revert old beamer overprint layouts to ERT "
2993 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2994 if document.textclass not in beamer_classes:
2999 i = find_token(document.body, "\\begin_layout Overprint", i)
3002 # Find end of sequence
3003 j = find_end_of_sequence(document.body, i)
3005 document.warning("Malformed LyX document. Cannot find end of Overprint sequence!")
3009 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
3010 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}")
3011 endseq = endseq + len(esubst) - len(document.body[j : j])
3012 if document.body[j] == "\\end_deeper":
3013 document.body[j : j] = ["\\end_deeper", ""] + esubst
3015 document.body[j : j] = esubst
3018 if document.body[r] == "\\begin_deeper":
3019 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3021 document.body[r] = ""
3022 document.body[s] = ""
3026 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
3028 argend = find_end_of_inset(document.body, argbeg)
3030 document.warning("Malformed LyX document. Cannot find end of Overprint argument!")
3033 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3034 endPlain = find_end_of_layout(document.body, beginPlain)
3035 content = document.body[beginPlain + 1 : endPlain]
3037 endseq = endseq - len(document.body[argbeg : argend])
3039 del document.body[argbeg : argend + 1]
3040 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3042 endseq = endseq - len(document.body[i : i])
3043 document.body[i : i] = subst + ["\\end_layout"]
3044 endseq += len(subst)
3050 if document.body[p] == "\\begin_layout Overprint":
3051 q = find_end_of_layout(document.body, p)
3053 document.warning("Malformed LyX document. Cannot find end of Overprint layout!")
3056 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\onslide")
3057 argbeg = find_token(document.body, "\\begin_inset Argument item:1", p, q)
3059 argend = find_end_of_inset(document.body, argbeg)
3061 document.warning("Malformed LyX document. Cannot find end of Overprint item argument!")
3064 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3065 endPlain = find_end_of_layout(document.body, beginPlain)
3066 content = document.body[beginPlain + 1 : endPlain]
3068 endseq = endseq - len(document.body[argbeg : argend + 1])
3070 del document.body[argbeg : argend + 1]
3071 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3072 endseq = endseq - len(document.body[p : p + 1]) + len(subst)
3073 document.body[p : p + 1] = subst
3079 def revert_frametitle(document):
3080 " Reverts beamer frametitle layout to ERT "
3082 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3083 if document.textclass not in beamer_classes:
3086 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
3089 i = find_token(document.body, "\\begin_layout FrameTitle", i)
3092 j = find_end_of_layout(document.body, i)
3094 document.warning("Malformed LyX document: Can't find end of FrameTitle layout")
3098 document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
3099 endlay += len(put_cmd_in_ert("}"))
3100 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\frametitle")
3101 for p in range(i, j):
3104 m = rx.match(document.body[p])
3108 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3109 endPlain = find_end_of_layout(document.body, beginPlain)
3110 endInset = find_end_of_inset(document.body, p)
3111 content = document.body[beginPlain + 1 : endPlain]
3113 endlay = endlay - len(document.body[p : endInset + 1])
3115 del document.body[p : endInset + 1]
3116 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3118 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3119 endPlain = find_end_of_layout(document.body, beginPlain)
3120 endInset = find_end_of_inset(document.body, p)
3121 content = document.body[beginPlain + 1 : endPlain]
3123 endlay = endlay - len(document.body[p : endInset + 1])
3125 del document.body[p : endInset + 1]
3126 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3128 subst += put_cmd_in_ert("{")
3129 document.body[i : i + 1] = subst
3133 def convert_epigraph(document):
3134 " Converts memoir epigraph to new syntax "
3136 if document.textclass != "memoir":
3141 i = find_token(document.body, "\\begin_layout Epigraph", i)
3144 j = find_end_of_layout(document.body, i)
3146 document.warning("Malformed LyX document: Can't find end of Epigraph layout")
3151 ert = find_token(document.body, "\\begin_inset ERT", i, j)
3153 endInset = find_end_of_inset(document.body, ert)
3154 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", ert)
3155 endPlain = find_end_of_layout(document.body, beginPlain)
3156 ertcont = beginPlain + 2
3157 if document.body[ertcont] == "}{":
3159 # Convert to ArgInset
3160 endlay = endlay - 2 * len(document.body[j])
3161 begsubst = ['\\begin_inset Argument post:1', 'status collapsed', '',
3162 '\\begin_layout Plain Layout']
3163 endsubst = ['\\end_layout', '', '\\end_inset', '', document.body[j]]
3164 document.body[j : j + 1] = endsubst
3165 document.body[endInset + 1 : endInset + 1] = begsubst
3167 endlay += len(begsubst) + len(endsubst)
3168 endlay = endlay - len(document.body[ert : endInset + 1])
3169 del document.body[ert : endInset + 1]
3174 def revert_epigraph(document):
3175 " Reverts memoir epigraph argument to ERT "
3177 if document.textclass != "memoir":
3182 i = find_token(document.body, "\\begin_layout Epigraph", i)
3185 j = find_end_of_layout(document.body, i)
3187 document.warning("Malformed LyX document: Can't find end of Epigraph layout")
3192 p = find_token(document.body, "\\begin_layout Argument post:1", i, j)
3194 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3195 endPlain = find_end_of_layout(document.body, beginPlain)
3196 endInset = find_end_of_inset(document.body, p)
3197 content = document.body[beginPlain + 1 : endPlain]
3199 endlay = endlay - len(document.body[p : endInset + 1])
3201 del document.body[p : endInset + 1]
3202 subst += put_cmd_in_ert("}{") + content
3204 subst += put_cmd_in_ert("}{")
3206 document.body[j : j] = subst + document.body[j : j]
3210 def convert_captioninsets(document):
3211 " Converts caption insets to new syntax "
3215 i = find_token(document.body, "\\begin_inset Caption", i)
3218 document.body[i] = "\\begin_inset Caption Standard"
3222 def revert_captioninsets(document):
3223 " Reverts caption insets to old syntax "
3227 i = find_token(document.body, "\\begin_inset Caption Standard", i)
3230 document.body[i] = "\\begin_inset Caption"
3234 def convert_captionlayouts(document):
3235 " Convert caption layouts to caption insets. "
3238 "Captionabove": "Above",
3239 "Captionbelow": "Below",
3240 "FigCaption" : "FigCaption",
3241 "Table_Caption" : "Table",
3242 "CenteredCaption" : "Centered",
3243 "Bicaption" : "Bicaption",
3248 i = find_token(document.body, "\\begin_layout", i)
3251 val = get_value(document.body, "\\begin_layout", i)
3252 if val in caption_dict.keys():
3253 j = find_end_of_layout(document.body, i)
3255 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3258 document.body[j:j] = ["\\end_layout", "", "\\end_inset", "", ""]
3259 document.body[i:i+1] = ["\\begin_layout %s" % document.default_layout,
3260 "\\begin_inset Caption %s" % caption_dict[val], "",
3261 "\\begin_layout %s" % document.default_layout]
3265 def revert_captionlayouts(document):
3266 " Revert caption insets to caption layouts. "
3269 "Above" : "Captionabove",
3270 "Below" : "Captionbelow",
3271 "FigCaption" : "FigCaption",
3272 "Table" : "Table_Caption",
3273 "Centered" : "CenteredCaption",
3274 "Bicaption" : "Bicaption",
3278 rx = re.compile(r'^\\begin_inset Caption (\S+)$')
3280 i = find_token(document.body, "\\begin_inset Caption", i)
3284 m = rx.match(document.body[i])
3288 if val not in caption_dict.keys():
3292 # We either need to delete the previous \begin_layout line, or we
3293 # need to end the previous layout if this inset is not in the first
3294 # position of the paragraph.
3295 layout_before = find_token_backwards(document.body, "\\begin_layout", i)
3296 if layout_before == -1:
3297 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3299 layout_line = document.body[layout_before]
3300 del_layout_before = True
3301 l = layout_before + 1
3303 if document.body[l] != "":
3304 del_layout_before = False
3307 if del_layout_before:
3308 del document.body[layout_before:i]
3311 document.body[i:i] = ["\\end_layout", ""]
3314 # Find start of layout in the inset and end of inset
3315 j = find_token(document.body, "\\begin_layout", i)
3317 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3319 k = find_end_of_inset(document.body, i)
3321 document.warning("Malformed LyX document: Missing `\\end_inset'.")
3324 # We either need to delete the following \end_layout line, or we need
3325 # to restart the old layout if this inset is not at the paragraph end.
3326 layout_after = find_token(document.body, "\\end_layout", k)
3327 if layout_after == -1:
3328 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3330 del_layout_after = True
3332 while l < layout_after:
3333 if document.body[l] != "":
3334 del_layout_after = False
3337 if del_layout_after:
3338 del document.body[k+1:layout_after+1]
3340 document.body[k+1:k+1] = [layout_line, ""]
3342 # delete \begin_layout and \end_inset and replace \begin_inset with
3343 # "\begin_layout XXX". This works because we can only have one
3344 # paragraph in the caption inset: The old \end_layout will be recycled.
3345 del document.body[k]
3346 if document.body[k] == "":
3347 del document.body[k]
3348 del document.body[j]
3349 if document.body[j] == "":
3350 del document.body[j]
3351 document.body[i] = "\\begin_layout %s" % caption_dict[val]
3352 if document.body[i+1] == "":
3353 del document.body[i+1]
3357 def revert_fragileframe(document):
3358 " Reverts beamer FragileFrame layout to ERT "
3360 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3361 if document.textclass not in beamer_classes:
3366 i = find_token(document.body, "\\begin_layout FragileFrame", i)
3369 # Find end of sequence
3370 j = find_end_of_sequence(document.body, i)
3372 document.warning("Malformed LyX document. Cannot find end of FragileFrame sequence!")
3376 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{frame}")
3377 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{frame}")
3378 endseq = endseq + len(esubst) - len(document.body[j : j])
3379 if document.body[j] == "\\end_deeper":
3380 document.body[j : j] = ["\\end_deeper", ""] + esubst
3382 document.body[j : j] = esubst
3383 for q in range(i, j):
3384 if document.body[q] == "\\begin_layout FragileFrame":
3385 document.body[q] = "\\begin_layout %s" % document.default_layout
3388 if document.body[r] == "\\begin_deeper":
3389 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3391 document.body[r] = ""
3392 document.body[s] = ""
3396 for p in range(1, 5):
3397 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, j)
3400 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3401 endPlain = find_end_of_layout(document.body, beginPlain)
3402 endInset = find_end_of_inset(document.body, arg)
3403 content = document.body[beginPlain + 1 : endPlain]
3405 j = j - len(document.body[arg : endInset + 1])
3407 del document.body[arg : endInset + 1]
3408 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3410 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3411 endPlain = find_end_of_layout(document.body, beginPlain)
3412 endInset = find_end_of_inset(document.body, arg)
3413 content = document.body[beginPlain + 1 : endPlain]
3415 j = j - len(document.body[arg : endInset + 1])
3417 del document.body[arg : endInset + 1]
3418 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3420 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3421 endPlain = find_end_of_layout(document.body, beginPlain)
3422 endInset = find_end_of_inset(document.body, arg)
3423 content = document.body[beginPlain + 1 : endPlain]
3425 j = j - len(document.body[arg : endInset + 1])
3427 del document.body[arg : endInset + 1]
3428 subst += put_cmd_in_ert("[fragile,") + content + put_cmd_in_ert("]")
3430 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3431 endPlain = find_end_of_layout(document.body, beginPlain)
3432 endInset = find_end_of_inset(document.body, arg)
3433 content = document.body[beginPlain + 1 : endPlain]
3435 j = j - len(document.body[arg : endInset + 1])
3437 del document.body[arg : endInset + 1]
3438 subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
3440 subst += put_cmd_in_ert("[fragile]")
3442 document.body[i : i + 1] = subst
3446 def revert_newframes(document):
3447 " Reverts beamer Frame and PlainFrame layouts to old forms "
3449 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3450 if document.textclass not in beamer_classes:
3454 "Frame" : "BeginFrame",
3455 "PlainFrame" : "BeginPlainFrame",
3458 rx = re.compile(r'^\\begin_layout (\S+)$')
3461 i = find_token(document.body, "\\begin_layout", i)
3465 m = rx.match(document.body[i])
3469 if val not in frame_dict.keys():
3472 # Find end of sequence
3473 j = find_end_of_sequence(document.body, i)
3475 document.warning("Malformed LyX document. Cannot find end of Frame sequence!")
3479 subst = ["\\begin_layout %s" % frame_dict[val]]
3480 esubst = ["\\end_layout", "", "\\begin_layout EndFrame", "", "\\end_layout"]
3481 endseq = endseq + len(esubst) - len(document.body[j : j])
3482 if document.body[j] == "\\end_deeper":
3483 document.body[j : j] = ["\\end_deeper", ""] + esubst
3485 document.body[j : j] = esubst
3486 for q in range(i, j):
3487 if document.body[q] == "\\begin_layout %s" % val:
3488 document.body[q] = "\\begin_layout %s" % document.default_layout
3491 if document.body[r] == "\\begin_deeper":
3492 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3494 document.body[r] = ""
3495 document.body[s] = ""
3499 l = find_end_of_layout(document.body, i)
3500 for p in range(1, 5):
3501 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, l)
3504 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3505 endPlain = find_end_of_layout(document.body, beginPlain)
3506 endInset = find_end_of_inset(document.body, arg)
3507 content = document.body[beginPlain + 1 : endPlain]
3509 l = l - len(document.body[arg : endInset + 1])
3511 del document.body[arg : endInset + 1]
3512 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3514 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3515 endPlain = find_end_of_layout(document.body, beginPlain)
3516 endInset = find_end_of_inset(document.body, arg)
3517 content = document.body[beginPlain + 1 : endPlain]
3519 l = l - len(document.body[arg : endInset + 1])
3521 del document.body[arg : endInset + 1]
3522 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3524 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3525 endPlain = find_end_of_layout(document.body, beginPlain)
3526 endInset = find_end_of_inset(document.body, arg)
3527 content = document.body[beginPlain + 1 : endPlain]
3529 l = l - len(document.body[arg : endInset + 1])
3531 del document.body[arg : endInset + 1]
3532 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3534 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3535 endPlain = find_end_of_layout(document.body, beginPlain)
3536 endInset = find_end_of_inset(document.body, arg)
3537 content = document.body[beginPlain + 1 : endPlain]
3539 l = l - len(document.body[arg : endInset + 1])
3541 del document.body[arg : endInset + 1]
3544 document.body[i : i + 1] = subst
3547 # known encodings that do not change their names (same LyX and LaTeX names)
3548 known_enc_tuple = ("auto", "default", "ansinew", "applemac", "armscii8", "ascii",
3549 "cp437", "cp437de", "cp850", "cp852", "cp855", "cp858", "cp862", "cp865", "cp866",
3550 "cp1250", "cp1251", "cp1252", "cp1255", "cp1256", "cp1257", "koi8-r", "koi8-u",
3551 "pt154", "pt254", "tis620-0", "utf8", "utf8x", "utf8-plain")
3553 def convert_encodings(document):
3554 "Use the LyX names of the encodings instead of the LaTeX names."
3555 LaTeX2LyX_enc_dict = {
3556 "8859-6": "iso8859-6",
3557 "8859-8": "iso8859-8",
3559 "euc": "euc-jp-platex",
3564 "iso88595": "iso8859-5",
3565 "iso-8859-7": "iso8859-7",
3567 "jis": "jis-platex",
3569 "l7xenc": "iso8859-13",
3570 "latin1": "iso8859-1",
3571 "latin2": "iso8859-2",
3572 "latin3": "iso8859-3",
3573 "latin4": "iso8859-4",
3574 "latin5": "iso8859-9",
3575 "latin9": "iso8859-15",
3576 "latin10": "iso8859-16",
3577 "SJIS": "shift-jis",
3578 "sjis": "shift-jis-platex",
3581 i = find_token(document.header, "\\inputencoding" , 0)
3584 val = get_value(document.header, "\\inputencoding", i)
3585 if val in LaTeX2LyX_enc_dict.keys():
3586 document.header[i] = "\\inputencoding %s" % LaTeX2LyX_enc_dict[val]
3587 elif val not in known_enc_tuple:
3588 document.warning("Ignoring unknown input encoding: `%s'" % val)
3591 def revert_encodings(document):
3592 """Revert to using the LaTeX names of the encodings instead of the LyX names.
3593 Also revert utf8-platex to sjis, the language default when using Japanese.
3595 LyX2LaTeX_enc_dict = {
3600 "euc-jp-platex": "euc",
3603 "iso8859-1": "latin1",
3604 "iso8859-2": "latin2",
3605 "iso8859-3": "latin3",
3606 "iso8859-4": "latin4",
3607 "iso8859-5": "iso88595",
3608 "iso8859-6": "8859-6",
3609 "iso8859-7": "iso-8859-7",
3610 "iso8859-8": "8859-8",
3611 "iso8859-9": "latin5",
3612 "iso8859-13": "l7xenc",
3613 "iso8859-15": "latin9",
3614 "iso8859-16": "latin10",
3616 "jis-platex": "jis",
3617 "shift-jis": "SJIS",
3618 "shift-jis-platex": "sjis",
3620 "utf8-platex": "sjis"
3622 i = find_token(document.header, "\\inputencoding" , 0)
3625 val = get_value(document.header, "\\inputencoding", i)
3626 if val in LyX2LaTeX_enc_dict.keys():
3627 document.header[i] = "\\inputencoding %s" % LyX2LaTeX_enc_dict[val]
3628 elif val not in known_enc_tuple:
3629 document.warning("Ignoring unknown input encoding: `%s'" % val)
3632 def revert_IEEEtran_3(document):
3634 Reverts Flex Insets to TeX-code
3636 if document.textclass == "IEEEtran":
3642 h = find_token(document.body, "\\begin_inset Flex Author Mark", h)
3644 endh = find_end_of_inset(document.body, h)
3645 document.body[endh - 2 : endh + 1] = put_cmd_in_ert("}")
3646 document.body[h : h + 4] = put_cmd_in_ert("\\IEEEauthorrefmark{")
3649 i = find_token(document.body, "\\begin_inset Flex Author Name", i)
3651 endi = find_end_of_inset(document.body, i)
3652 document.body[endi - 2 : endi + 1] = put_cmd_in_ert("}")
3653 document.body[i : i + 4] = put_cmd_in_ert("\\IEEEauthorblockN{")
3656 j = find_token(document.body, "\\begin_inset Flex Author Affiliation", j)
3658 endj = find_end_of_inset(document.body, j)
3659 document.body[endj - 2 : endj + 1] = put_cmd_in_ert("}")
3660 document.body[j : j + 4] = put_cmd_in_ert("\\IEEEauthorblockA{")
3662 if i == -1 and j == -1 and h == -1:
3666 def revert_kurier_fonts(document):
3667 " Revert kurier font definition to LaTeX "
3669 i = find_token(document.header, "\\font_math", 0)
3671 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3672 val = get_value(document.header, "\\font_math", i)
3673 if val == "kurier-math":
3674 add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
3675 "\\usepackage[math]{kurier}\n" \
3676 "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
3677 document.header[i] = "\\font_math auto"
3679 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3680 kurier_fonts = ["kurier", "kurierc", "kurierl", "kurierlc"]
3681 k = find_token(document.header, "\\font_sans kurier", 0)
3683 sf = get_value(document.header, "\\font_sans", k)
3684 if sf in kurier_fonts:
3685 add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
3686 document.header[k] = "\\font_sans default"
3688 def revert_iwona_fonts(document):
3689 " Revert iwona font definition to LaTeX "
3691 i = find_token(document.header, "\\font_math", 0)
3693 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3694 val = get_value(document.header, "\\font_math", i)
3695 if val == "iwona-math":
3696 add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
3697 "\\usepackage[math]{iwona}\n" \
3698 "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
3699 document.header[i] = "\\font_math auto"
3701 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3702 iwona_fonts = ["iwona", "iwonac", "iwonal", "iwonalc"]
3703 k = find_token(document.header, "\\font_sans iwona", 0)
3705 sf = get_value(document.header, "\\font_sans", k)
3706 if sf in iwona_fonts:
3707 add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
3708 document.header[k] = "\\font_sans default"
3711 def revert_new_libertines(document):
3712 " Revert new libertine font definition to LaTeX "
3714 if find_token(document.header, "\\use_non_tex_fonts true", 0) != -1:
3717 i = find_token(document.header, "\\font_typewriter libertine-mono", 0)
3719 preamble = "\\usepackage"
3720 sc = find_token(document.header, "\\font_tt_scale", 0)
3722 scval = get_value(document.header, "\\font_tt_scale", sc)
3724 preamble += "[scale=%f]" % (float(scval) / 100)
3725 document.header[sc] = "\\font_tt_scale 100"
3726 preamble += "{libertineMono-type1}"
3727 add_to_preamble(document, [preamble])
3728 document.header[i] = "\\font_typewriter default"
3730 k = find_token(document.header, "\\font_sans biolinum", 0)
3732 preamble = "\\usepackage"
3734 j = find_token(document.header, "\\font_osf true", 0)
3739 sc = find_token(document.header, "\\font_sf_scale", 0)
3741 scval = get_value(document.header, "\\font_sf_scale", sc)
3743 options += ",scale=%f" % (float(scval) / 100)
3744 document.header[sc] = "\\font_sf_scale 100"
3746 preamble += "[" + options +"]"
3747 preamble += "{biolinum-type1}"
3748 add_to_preamble(document, [preamble])
3749 document.header[k] = "\\font_sans default"
3752 def convert_lyxframes(document):
3753 " Converts old beamer frames to new style "
3755 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3756 if document.textclass not in beamer_classes:
3759 framebeg = ["BeginFrame", "BeginPlainFrame"]
3760 frameend = ["Frame", "PlainFrame", "EndFrame", "BeginFrame", "BeginPlainFrame", "AgainFrame",
3761 "Section", "Section*", "Subsection", "Subsection*", "Subsubsection", "Subsubsection*"]
3762 for lay in framebeg:
3765 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
3768 parent = get_containing_layout(document.body, i)
3769 if parent == False or parent[1] != i:
3770 document.warning("Wrong parent layout!")
3773 frametype = parent[0]
3777 # Step I: Convert ERT arguments
3778 # FIXME: This currently only works if the arguments are in one single ERT
3780 if document.body[parbeg] == "\\begin_inset ERT":
3781 ertend = find_end_of_inset(document.body, parbeg)
3783 document.warning("Malformed LyX document: missing ERT \\end_inset")
3785 ertcont = parbeg + 5
3786 if document.body[ertcont].startswith("[<"):
3787 # This is a default overlay specification
3789 document.body[ertcont] = document.body[ertcont][2:]
3790 if document.body[ertcont].endswith(">]"):
3792 document.body[ertcont] = document.body[ertcont][:-2]
3793 elif document.body[ertcont].endswith("]"):
3795 tok = document.body[ertcont].find('>][')
3797 subst = [document.body[ertcont][:tok],
3798 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
3799 'status collapsed', '', '\\begin_layout Plain Layout',
3800 document.body[ertcont][tok + 3:-1]]
3801 document.body[ertcont : ertcont + 1] = subst
3803 # Convert to ArgInset
3804 document.body[parbeg] = "\\begin_inset Argument 2"
3805 elif document.body[ertcont].startswith("<"):
3806 # This is an overlay specification
3808 document.body[ertcont] = document.body[ertcont][1:]
3809 if document.body[ertcont].endswith(">"):
3811 document.body[ertcont] = document.body[ertcont][:-1]
3812 # Convert to ArgInset
3813 document.body[parbeg] = "\\begin_inset Argument 1"
3814 elif document.body[ertcont].endswith(">]"):
3816 tok = document.body[ertcont].find('>[<')
3818 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
3819 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
3820 'status collapsed', '', '\\begin_layout Plain Layout',
3821 document.body[ertcont][tok + 3:-2]]
3822 # Convert to ArgInset
3823 document.body[parbeg] = "\\begin_inset Argument 1"
3825 elif document.body[ertcont].endswith("]"):
3827 tok = document.body[ertcont].find('>[<')
3830 tokk = document.body[ertcont].find('>][')
3832 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
3833 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
3834 'status collapsed', '', '\\begin_layout Plain Layout',
3835 document.body[ertcont][tok + 3:tokk],
3836 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
3837 'status collapsed', '', '\\begin_layout Plain Layout',
3838 document.body[ertcont][tokk + 3:-1]]
3841 tokk = document.body[ertcont].find('>[')
3843 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tokk],
3844 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
3845 'status collapsed', '', '\\begin_layout Plain Layout',
3846 document.body[ertcont][tokk + 2:-1]]
3848 # Convert to ArgInset
3849 document.body[parbeg] = "\\begin_inset Argument 1"
3850 elif document.body[ertcont].startswith("["):
3851 # This is an ERT option
3853 document.body[ertcont] = document.body[ertcont][1:]
3854 if document.body[ertcont].endswith("]"):
3856 document.body[ertcont] = document.body[ertcont][:-1]
3857 # Convert to ArgInset
3858 document.body[parbeg] = "\\begin_inset Argument 3"
3859 # End of argument conversion
3860 # Step II: Now rename the layout and convert the title to an argument
3861 j = find_end_of_layout(document.body, i)
3862 document.body[j : j + 1] = ['\\end_layout', '', '\\end_inset', '', '\\end_layout']
3863 if lay == "BeginFrame":
3864 document.body[i] = "\\begin_layout Frame"
3866 document.body[i] = "\\begin_layout PlainFrame"
3867 document.body[ertend + 1 : ertend + 1] = ['\\begin_inset Argument 4',
3868 'status open', '', '\\begin_layout Plain Layout']
3869 # Step III: find real frame end
3873 fend = find_token(document.body, "\\begin_layout", jj)
3875 document.warning("Malformed LyX document: No real frame end!")
3877 val = get_value(document.body, "\\begin_layout", fend)
3878 if val not in frameend:
3881 old = document.body[fend]
3882 if val == frametype:
3883 document.body[fend : fend] = ['\\end_deeper', '', '\\begin_layout Separator', '', '\\end_layout']
3885 document.body[fend : fend] = ['\\end_deeper']
3886 document.body[j + 1 : j + 1] = ['', '\\begin_deeper']
3891 def remove_endframes(document):
3892 " Remove deprecated beamer endframes "
3894 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3895 if document.textclass not in beamer_classes:
3900 i = find_token_exact(document.body, "\\begin_layout EndFrame", i)
3903 j = find_end_of_layout(document.body, i)
3905 document.warning("Malformed LyX document: Missing \\end_layout to EndFrame")
3908 del document.body[i : j + 1]
3911 def revert_powerdot_flexes(document):
3912 " Reverts powerdot flex insets "
3914 if document.textclass != "powerdot":
3917 flexes = {"Onslide" : "\\onslide",
3918 "Onslide*" : "\\onslide*",
3919 "Onslide+" : "\\onslide+"}
3920 rx = re.compile(r'^\\begin_inset Flex (.+)$')
3924 i = find_token(document.body, "\\begin_inset Flex", i)
3927 m = rx.match(document.body[i])
3929 flextype = m.group(1)
3930 z = find_end_of_inset(document.body, i)
3932 document.warning("Can't find end of Flex " + flextype + " inset.")
3935 if flextype in flexes:
3936 pre = put_cmd_in_ert(flexes[flextype])
3937 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
3939 argend = find_end_of_inset(document.body, arg)
3941 document.warning("Can't find end of Argument!")
3944 # Find containing paragraph layout
3945 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3946 endPlain = find_end_of_layout(document.body, beginPlain)
3947 argcontent = document.body[beginPlain + 1 : endPlain]
3949 z = z - len(document.body[arg : argend + 1])
3951 del document.body[arg : argend + 1]
3952 pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
3953 pre += put_cmd_in_ert("{")
3954 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
3955 endPlain = find_end_of_layout(document.body, beginPlain)
3957 z = z - len(document.body[i : beginPlain + 1])
3959 document.body[i : beginPlain + 1] = pre
3960 post = put_cmd_in_ert("}")
3961 document.body[z - 2 : z + 1] = post
3965 def revert_powerdot_pause(document):
3966 " Reverts powerdot pause layout to ERT "
3968 if document.textclass != "powerdot":
3973 i = find_token(document.body, "\\begin_layout Pause", i)
3976 j = find_end_of_layout(document.body, i)
3978 document.warning("Malformed LyX document: Can't find end of Pause layout")
3982 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\pause")
3983 for p in range(i, j):
3986 arg = find_token(document.body, "\\begin_inset Argument 1", i, j)
3988 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3989 endPlain = find_end_of_layout(document.body, beginPlain)
3990 endInset = find_end_of_inset(document.body, p)
3991 content = document.body[beginPlain + 1 : endPlain]
3993 endlay = endlay - len(document.body[p : endInset + 1])
3995 del document.body[p : endInset + 1]
3996 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3998 document.body[i : i + 1] = subst
4002 def revert_powerdot_itemargs(document):
4003 " Reverts powerdot item arguments to ERT "
4005 if document.textclass != "powerdot":
4009 list_layouts = ["Itemize", "ItemizeType1", "Enumerate", "EnumerateType1"]
4010 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
4013 i = find_token(document.body, "\\begin_inset Argument", i)
4016 # Find containing paragraph layout
4017 parent = get_containing_layout(document.body, i)
4019 document.warning("Malformed LyX document: Can't find parent paragraph layout")
4024 realparbeg = parent[3]
4025 layoutname = parent[0]
4027 for p in range(parbeg, parend):
4031 if layoutname in list_layouts:
4032 m = rx.match(document.body[p])
4035 if argnr == "item:1":
4036 j = find_end_of_inset(document.body, i)
4037 # Find containing paragraph layout
4038 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
4039 endPlain = find_end_of_layout(document.body, beginPlain)
4040 content = document.body[beginPlain + 1 : endPlain]
4041 del document.body[i:j+1]
4042 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
4043 document.body[realparbeg : realparbeg] = subst
4044 elif argnr == "item:2":
4045 j = find_end_of_inset(document.body, i)
4046 # Find containing paragraph layout
4047 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
4048 endPlain = find_end_of_layout(document.body, beginPlain)
4049 content = document.body[beginPlain + 1 : endPlain]
4050 del document.body[i:j+1]
4051 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
4052 document.body[realparbeg : realparbeg] = subst
4057 def revert_powerdot_columns(document):
4058 " Reverts powerdot twocolumn to TeX-code "
4059 if document.textclass != "powerdot":
4062 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
4065 i = find_token(document.body, "\\begin_layout Twocolumn", i)
4068 j = find_end_of_layout(document.body, i)
4070 document.warning("Malformed LyX document: Can't find end of Twocolumn layout")
4074 document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
4075 endlay += len(put_cmd_in_ert("}"))
4076 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\twocolumn")
4077 for p in range(i, j):
4080 m = rx.match(document.body[p])
4084 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
4085 endPlain = find_end_of_layout(document.body, beginPlain)
4086 endInset = find_end_of_inset(document.body, p)
4087 content = document.body[beginPlain + 1 : endPlain]
4089 endlay = endlay - len(document.body[p : endInset + 1])
4091 del document.body[p : endInset + 1]
4092 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
4094 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
4095 endPlain = find_end_of_layout(document.body, beginPlain)
4096 endInset = find_end_of_inset(document.body, p)
4097 content = document.body[beginPlain + 1 : endPlain]
4099 endlay = endlay - len(document.body[p : endInset + 1])
4101 del document.body[p : endInset + 1]
4102 subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
4104 subst += put_cmd_in_ert("{")
4105 document.body[i : i + 1] = subst
4109 def revert_mbox_fbox(document):
4110 'Convert revert mbox/fbox boxes to TeX-code'
4113 i = find_token(document.body, "\\begin_inset Box", i)
4116 j = find_token(document.body, "width", i)
4118 document.warning("Malformed LyX document: Can't find box width")
4120 width = get_value(document.body, "width", j)
4121 k = find_end_of_inset(document.body, j)
4123 document.warning("Malformed LyX document: Can't find end of box inset")
4126 BeginLayout = find_token(document.body, "\\begin_layout Plain Layout", j)
4127 EndLayout = find_token(document.body, "\\end_layout", BeginLayout)
4128 # replace if width is ""
4130 document.body[EndLayout:k + 1] = put_cmd_in_ert("}")
4131 if document.body[i] == "\\begin_inset Box Frameless":
4132 document.body[i:BeginLayout + 1] = put_cmd_in_ert("\\mbox{")
4133 if document.body[i] == "\\begin_inset Box Boxed":
4134 document.body[i:BeginLayout + 1] = put_cmd_in_ert("\\fbox{")
4138 def revert_starred_caption(document):
4139 " Reverts unnumbered longtable caption insets "
4143 i = find_token(document.body, "\\begin_inset Caption LongTableNoNumber", i)
4146 # This is not equivalent, but since the caption inset is a full blown
4147 # text inset a true conversion to ERT is too difficult.
4148 document.body[i] = "\\begin_inset Caption Standard"
4152 def revert_forced_local_layout(document):
4155 i = find_token(document.header, "\\begin_forced_local_layout", i)
4158 j = find_end_of(document.header, i, "\\begin_forced_local_layout", "\\end_forced_local_layout")
4160 # this should not happen
4162 regexp = re.compile(r'\s*forcelocal', re.IGNORECASE)
4163 k = find_re(document.header, regexp, i, j)
4165 del document.header[k]
4167 k = find_re(document.header, regexp, i, j)
4168 k = find_token(document.header, "\\begin_local_layout", 0)
4170 document.header[i] = "\\begin_local_layout"
4171 document.header[j] = "\\end_local_layout"
4173 l = find_end_of(document.header, k, "\\begin_local_layout", "\\end_local_layout")
4175 # this should not happen
4177 lines = document.header[i+1 : j]
4179 document.header[k+1 : k+1] = lines
4180 document.header[i : j ] = []
4182 document.header[i : j ] = []
4183 document.header[k+1 : k+1] = lines
4186 def revert_aa1(document):
4187 " Reverts InsetArguments of aa to TeX-code "
4188 if document.textclass == "aa":
4192 i = find_token(document.body, "\\begin_layout Abstract (structured)", i)
4194 revert_Argument_to_TeX_brace(document, i, 0, 1, 4, False, False)
4200 def revert_aa2(document):
4201 " Reverts InsetArguments of aa to TeX-code "
4202 if document.textclass == "aa":
4206 i = find_token(document.body, "\\begin_layout Abstract (structured)", i)
4208 document.body[i] = "\\begin_layout Abstract"
4214 def revert_tibetan(document):
4215 "Set the document language for Tibetan to English"
4217 if document.language == "tibetan":
4218 document.language = "english"
4219 i = find_token(document.header, "\\language", 0)
4221 document.header[i] = "\\language english"
4223 while j < len(document.body):
4224 j = find_token(document.body, "\\lang tibetan", j)
4226 document.body[j] = document.body[j].replace("\\lang tibetan", "\\lang english")
4229 j = len(document.body)
4238 # the idea here is that we will have a sequence of chunk paragraphs
4239 # we want to convert them to paragraphs in a chunk inset
4240 # the last will be discarded
4241 # the first should look like: <<FROGS>>=
4242 # will will discard the delimiters, and put the contents into the
4243 # optional argument of the inset
4244 def convert_chunks(document):
4245 first_re = re.compile(r'<<(.*)>>=')
4248 # the beginning of this sequence
4250 # find start of a block of chunks
4251 i = find_token(document.body, "\\begin_layout Chunk", i)
4259 # process the one we just found
4260 j = find_end_of_layout(document.body, i)
4262 document.warning("Malformed LyX documents. Can't find end of Chunk layout!")
4264 thischunk = "".join(document.body[i + 1:j])
4265 contents.append(document.body[i + 1:j])
4267 if thischunk == "@":
4270 # look for the next one
4272 i = find_token(document.body, "\\begin_layout", i)
4276 layout = get_value(document.body, "\\begin_layout", i)
4277 #sys.stderr.write(layout+ '\n')
4278 if layout != "Chunk":
4282 # error, but we can try to continue
4289 # the last chunk should simply have an "@" in it
4291 if ''.join(contents[-1]) != "@":
4292 document.warning("Unexpected chunk contents.")
4297 # the first item should look like: <<FROGS>>=
4298 # we want the inside
4299 optarg = ' '.join(contents[0])
4301 match = first_re.search(optarg)
4303 optarg = match.groups()[0]
4306 newstuff = ['\\begin_layout Standard',
4307 '\\begin_inset Flex Chunk',
4309 '\\begin_layout Plain Layout', '']
4313 ['\\begin_inset Argument 1',
4315 '\\begin_layout Plain Layout',
4323 newstuff.extend(['', '\\begin_layout Plain Layout', ''])
4327 newstuff.append('\\end_layout')
4329 newstuff.extend(['', '\\end_inset', '', '\\end_layout', ''])
4331 document.body[start:end] = newstuff
4333 k += len(newstuff) - (end - start)
4336 def revert_chunks(document):
4339 i = find_token(document.body, "\\begin_inset Flex Chunk", i)
4343 iend = find_end_of_inset(document.body, i)
4345 document.warning("Can't find end of Chunk!")
4349 # Look for optional argument
4351 ostart = find_token(document.body, "\\begin_inset Argument 1", i, iend)
4353 oend = find_end_of_inset(document.body, ostart)
4354 k = find_token(document.body, "\\begin_layout Plain Layout", ostart, oend)
4356 document.warning("Malformed LyX document: Can't find argument contents!")
4358 m = find_end_of_layout(document.body, k)
4359 optarg = "".join(document.body[k+1:m])
4362 # We now remove the optional argument, so we have something
4363 # uniform on which to work
4364 document.body[ostart : oend + 1] = []
4365 # iend is now invalid
4366 iend = find_end_of_inset(document.body, i)
4368 retval = get_containing_layout(document.body, i)
4370 document.warning("Can't find containing layout for Chunk!")
4373 (lname, lstart, lend, pstart) = retval
4374 # we now want to work through the various paragraphs, and collect their contents
4378 k = find_token(document.body, "\\begin_layout Plain Layout", k, lend)
4381 j = find_end_of_layout(document.body, k)
4383 document.warning("Can't find end of layout inside chunk!")
4385 parlist.append(document.body[k+1:j])
4387 # we now need to wrap all of these paragraphs in chunks
4390 newlines.extend(["\\begin_layout Chunk", "", "<<" + optarg + ">>=", "\\end_layout", ""])
4391 for stuff in parlist:
4392 newlines.extend(["\\begin_layout Chunk"] + stuff + ["\\end_layout", ""])
4393 newlines.extend(["\\begin_layout Chunk", "", "@", "\\end_layout", ""])
4394 # replace old content with new content
4395 document.body[lstart : lend + 1] = newlines
4396 i = lstart + len(newlines)
4403 supported_versions = ["2.1.0","2.1"]
4406 [415, [convert_undertilde]],
4408 [417, [convert_japanese_encodings]],
4411 [420, [convert_biblio_style]],
4412 [421, [convert_longtable_captions]],
4413 [422, [convert_use_packages]],
4414 [423, [convert_use_mathtools]],
4415 [424, [convert_cite_engine_type]],
4419 [428, [convert_cell_rotation]],
4420 [429, [convert_table_rotation]],
4421 [430, [convert_listoflistings]],
4422 [431, [convert_use_amssymb]],
4424 [433, [convert_armenian]],
4432 [441, [convert_mdnomath]],
4437 [446, [convert_latexargs]],
4438 [447, [convert_IEEEtran, convert_AASTeX, convert_AGUTeX, convert_IJMP, convert_SIGPLAN, convert_SIGGRAPH, convert_EuropeCV, convert_Initials, convert_ModernCV]],
4439 [448, [convert_literate]],
4442 [451, [convert_beamerargs, convert_againframe_args, convert_corollary_args, convert_quote_args]],
4443 [452, [convert_beamerblocks]],
4444 [453, [convert_use_stmaryrd]],
4445 [454, [convert_overprint]],
4447 [456, [convert_epigraph]],
4448 [457, [convert_use_stackrel]],
4449 [458, [convert_captioninsets, convert_captionlayouts]],
4454 [463, [convert_encodings]],
4455 [464, [convert_use_cancel]],
4456 [465, [convert_lyxframes, remove_endframes]],
4462 [471, [convert_cite_engine_type_default]],
4465 [474, [convert_chunks]],
4469 [473, [revert_chunks]],
4470 [472, [revert_tibetan]],
4471 [471, [revert_aa1,revert_aa2]],
4472 [470, [revert_cite_engine_type_default]],
4473 [469, [revert_forced_local_layout]],
4474 [468, [revert_starred_caption]],
4475 [467, [revert_mbox_fbox]],
4476 [466, [revert_iwona_fonts]],
4477 [465, [revert_powerdot_flexes, revert_powerdot_pause, revert_powerdot_itemargs, revert_powerdot_columns]],
4479 [463, [revert_use_cancel]],
4480 [462, [revert_encodings]],
4481 [461, [revert_new_libertines]],
4482 [460, [revert_kurier_fonts]],
4483 [459, [revert_IEEEtran_3]],
4484 [458, [revert_fragileframe, revert_newframes]],
4485 [457, [revert_captioninsets, revert_captionlayouts]],
4486 [456, [revert_use_stackrel]],
4487 [455, [revert_epigraph]],
4488 [454, [revert_frametitle]],
4489 [453, [revert_overprint]],
4490 [452, [revert_use_stmaryrd]],
4491 [451, [revert_beamerblocks]],
4492 [450, [revert_beamerargs, revert_beamerargs2, revert_beamerargs3, revert_beamerflex]],
4493 [449, [revert_garamondx, revert_garamondx_newtxmath]],
4494 [448, [revert_itemargs]],
4495 [447, [revert_literate]],
4496 [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]],
4497 [445, [revert_latexargs]],
4498 [444, [revert_uop]],
4499 [443, [revert_biolinum]],
4501 [441, [revert_newtxmath]],
4502 [440, [revert_mdnomath]],
4503 [439, [revert_mathfonts]],
4504 [438, [revert_minionpro]],
4505 [437, [revert_ipadeco, revert_ipachar]],
4506 [436, [revert_texgyre]],
4507 [435, [revert_mathdesign]],
4508 [434, [revert_txtt]],
4509 [433, [revert_libertine]],
4510 [432, [revert_armenian]],
4511 [431, [revert_languages, revert_ancientgreek]],
4512 [430, [revert_use_amssymb]],
4513 [429, [revert_listoflistings]],
4514 [428, [revert_table_rotation]],
4515 [427, [revert_cell_rotation]],
4516 [426, [revert_tipa]],
4517 [425, [revert_verbatim]],
4518 [424, [revert_cancel]],
4519 [423, [revert_cite_engine_type]],
4520 [422, [revert_use_mathtools]],
4521 [421, [revert_use_packages]],
4522 [420, [revert_longtable_captions]],
4523 [419, [revert_biblio_style]],
4524 [418, [revert_australian]],
4525 [417, [revert_justification]],
4526 [416, [revert_japanese_encodings]],
4527 [415, [revert_negative_space, revert_math_spaces]],
4528 [414, [revert_undertilde]],
4529 [413, [revert_visible_space]]
4533 if __name__ == "__main__":