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:
1540 if environment == True and lineERT != -1:
1541 opening = find_token(document.body, "{", lineERT)
1542 if opening == lineERT + 5: # assure that the "{" is in this ERT
1543 end = find_token(document.body, "\\end_inset", opening)
1544 document.body[lineERT : end + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1546 lineERT2 = find_token(document.body, "\\begin_inset ERT", lineERT)
1547 closing = find_token(document.body, "}", lineERT2)
1548 if closing == lineERT2 + 5: # assure that the "}" is in this ERT
1549 end2 = find_token(document.body, "\\end_inset", closing)
1550 document.body[lineERT2 : end2 + 1] = ["\\end_layout", "", "\\end_inset"]
1555 def revert_IEEEtran(document):
1557 Reverts InsetArgument of
1560 Biography without photo
1563 if document.textclass == "IEEEtran":
1570 i = find_token(document.body, "\\begin_layout Page headings", i)
1572 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1575 i2 = find_token(document.body, "\\begin_inset Flex Paragraph Start", i2)
1577 revert_Argument_to_TeX_brace(document, i2, 0, 1, 1, False, False)
1580 j = find_token(document.body, "\\begin_layout Biography without photo", j)
1582 revert_Argument_to_TeX_brace(document, j, 0, 1, 1, True, False)
1585 k = find_token(document.body, "\\begin_layout Biography", k)
1586 kA = find_token(document.body, "\\begin_layout Biography without photo", k)
1587 if k == kA and k != -1:
1591 # start with the second argument, therefore 2
1592 revert_Argument_to_TeX_brace(document, k, 0, 2, 2, True, False)
1594 if i == -1 and i2 == -1 and j == -1 and k == -1:
1598 def revert_IEEEtran_2(document):
1600 Reverts Flex Paragraph Start to TeX-code
1602 if document.textclass == "IEEEtran":
1606 begin = find_token(document.body, "\\begin_inset Flex Paragraph Start", begin)
1608 end1 = find_end_of_inset(document.body, begin)
1609 document.body[end1 - 2 : end1 + 1] = put_cmd_in_ert("}")
1610 document.body[begin : begin + 4] = put_cmd_in_ert("\\IEEEPARstart{")
1616 def convert_IEEEtran(document):
1621 Biography without photo
1624 if document.textclass == "IEEEtran":
1630 i = find_token(document.body, "\\begin_layout Page headings", i)
1632 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1635 j = find_token(document.body, "\\begin_layout Biography without photo", j)
1637 convert_TeX_brace_to_Argument(document, j, 1, 1, False, True)
1640 # assure that we don't handle Biography Biography without photo
1641 k = find_token(document.body, "\\begin_layout Biography", k)
1642 kA = find_token(document.body, "\\begin_layout Biography without photo", k - 1)
1643 if k == kA and k != -1:
1647 # the argument we want to convert is the second one
1648 convert_TeX_brace_to_Argument(document, k, 2, 2, False, True)
1650 if i == -1 and j == -1 and k == -1:
1654 def revert_AASTeX(document):
1655 " Reverts InsetArgument of Altaffilation to TeX-code "
1656 if document.textclass == "aastex":
1660 i = find_token(document.body, "\\begin_layout Altaffilation", i)
1662 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1668 def convert_AASTeX(document):
1669 " Converts ERT of Altaffilation to InsetArgument "
1670 if document.textclass == "aastex":
1674 i = find_token(document.body, "\\begin_layout Altaffilation", i)
1676 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1682 def revert_AGUTeX(document):
1683 " Reverts InsetArgument of Author affiliation to TeX-code "
1684 if document.textclass == "agutex":
1688 i = find_token(document.body, "\\begin_layout Author affiliation", i)
1690 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1696 def convert_AGUTeX(document):
1697 " Converts ERT of Author affiliation to InsetArgument "
1698 if document.textclass == "agutex":
1702 i = find_token(document.body, "\\begin_layout Author affiliation", i)
1704 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1710 def revert_IJMP(document):
1711 " Reverts InsetArgument of MarkBoth to TeX-code "
1712 if document.textclass == "ijmpc" or document.textclass == "ijmpd":
1716 i = find_token(document.body, "\\begin_layout MarkBoth", i)
1718 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1724 def convert_IJMP(document):
1725 " Converts ERT of MarkBoth to InsetArgument "
1726 if document.textclass == "ijmpc" or document.textclass == "ijmpd":
1730 i = find_token(document.body, "\\begin_layout MarkBoth", i)
1732 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1738 def revert_SIGPLAN(document):
1739 " Reverts InsetArguments of SIGPLAN to TeX-code "
1740 if document.textclass == "sigplanconf":
1745 i = find_token(document.body, "\\begin_layout Conference", i)
1747 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1750 j = find_token(document.body, "\\begin_layout Author", j)
1752 revert_Argument_to_TeX_brace(document, j, 0, 1, 2, False, False)
1754 if i == -1 and j == -1:
1758 def convert_SIGPLAN(document):
1759 " Converts ERT of SIGPLAN to InsetArgument "
1760 if document.textclass == "sigplanconf":
1765 i = find_token(document.body, "\\begin_layout Conference", i)
1767 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1770 j = find_token(document.body, "\\begin_layout Author", j)
1772 convert_TeX_brace_to_Argument(document, j, 1, 2, False, False)
1774 if i == -1 and j == -1:
1778 def revert_SIGGRAPH(document):
1779 " Reverts InsetArgument of Flex CRcat to TeX-code "
1780 if document.textclass == "acmsiggraph":
1784 i = find_token(document.body, "\\begin_inset Flex CRcat", i)
1786 revert_Argument_to_TeX_brace(document, i, 0, 1, 3, False, False)
1792 def convert_SIGGRAPH(document):
1793 " Converts ERT of Flex CRcat to InsetArgument "
1794 if document.textclass == "acmsiggraph":
1798 i = find_token(document.body, "\\begin_inset Flex CRcat", i)
1800 convert_TeX_brace_to_Argument(document, i, 1, 3, True, False)
1806 def revert_EuropeCV(document):
1807 " Reverts InsetArguments of europeCV to TeX-code "
1808 if document.textclass == "europecv":
1815 i = find_token(document.body, "\\begin_layout Item", i)
1817 revert_Argument_to_TeX_brace(document, i, 0, 2, 2, False, False)
1820 j = find_token(document.body, "\\begin_layout BulletedItem", j)
1822 revert_Argument_to_TeX_brace(document, j, 0, 2, 2, False, False)
1825 k = find_token(document.body, "\\begin_layout Language", k)
1827 revert_Argument_to_TeX_brace(document, k, 0, 2, 6, False, False)
1830 m = find_token(document.body, "\\begin_layout LastLanguage", m)
1832 revert_Argument_to_TeX_brace(document, m, 0, 2, 6, False, False)
1834 if i == -1 and j == -1 and k == -1 and m == -1:
1838 def convert_EuropeCV(document):
1839 " Converts ERT of europeCV to InsetArgument "
1840 if document.textclass == "europecv":
1847 i = find_token(document.body, "\\begin_layout Item", i)
1849 convert_TeX_brace_to_Argument(document, i, 2, 2, False, False)
1852 j = find_token(document.body, "\\begin_layout BulletedItem", j)
1854 convert_TeX_brace_to_Argument(document, j, 2, 2, False, False)
1857 k = find_token(document.body, "\\begin_layout Language", k)
1859 convert_TeX_brace_to_Argument(document, k, 2, 6, False, False)
1862 m = find_token(document.body, "\\begin_layout LastLanguage", m)
1864 convert_TeX_brace_to_Argument(document, m, 2, 6, False, False)
1866 if i == -1 and j == -1 and k == -1 and m == -1:
1870 def revert_ModernCV(document):
1871 " Reverts InsetArguments of modernCV to TeX-code "
1872 if document.textclass == "moderncv":
1880 j = find_token(document.body, "\\begin_layout Entry", j)
1882 revert_Argument_to_TeX_brace(document, j, 0, 1, 5, False, False)
1885 k = find_token(document.body, "\\begin_layout Item", k)
1887 revert_Argument_to_TeX_brace(document, k, 0, 1, 1, False, False)
1890 m = find_token(document.body, "\\begin_layout ItemWithComment", m)
1892 revert_Argument_to_TeX_brace(document, m, 0, 1, 2, False, False)
1893 document.body[m] = document.body[m].replace("\\begin_layout ItemWithComment", "\\begin_layout Language")
1896 o = find_token(document.body, "\\begin_layout DoubleItem", o)
1898 revert_Argument_to_TeX_brace(document, o, 0, 1, 3, False, False)
1899 document.body[o] = document.body[o].replace("\\begin_layout DoubleItem", "\\begin_layout Computer")
1902 p = find_token(document.body, "\\begin_layout Social", p)
1904 revert_Argument_to_TeX_brace(document, p, 0, 1, 1, False, True)
1906 if j == -1 and k == -1 and m == -1 and o == -1 and p == -1:
1910 def revert_ModernCV_2(document):
1911 " Reverts the Flex:Column inset of modernCV to TeX-code "
1912 if document.textclass == "moderncv":
1917 flex = find_token(document.body, "\\begin_inset Flex Column", flex)
1919 flexEnd = find_end_of_inset(document.body, flex)
1920 wasOpt = revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, False, True)
1921 revert_Argument_to_TeX_brace(document, flex, 0, 2, 2, False, False)
1922 flexEnd = find_end_of_inset(document.body, flex)
1924 document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\cvcolumn")
1926 document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\cvcolumn{")
1927 document.body[flexEnd + 4 : flexEnd + 7] = put_cmd_in_ert("}")
1933 def revert_ModernCV_3(document):
1934 " Reverts the Column style of modernCV to TeX-code "
1935 if document.textclass == "moderncv":
1936 # revert the layouts
1937 revert_ModernCV(document)
1939 # get the position of the end of the last column inset
1940 LastFlexEnd = revert_ModernCV_2(document)
1943 p = find_token(document.body, "\\begin_layout Columns", p)
1945 pEnd = find_end_of_layout(document.body, p)
1946 document.body[p] = document.body[p].replace("\\begin_layout Columns", "\\begin_layout Standard")
1947 if LastFlexEnd != -1:
1948 document.body[p + 1 : p + 1] = put_cmd_in_ert("\\begin{cvcolumns}")
1949 document.body[LastFlexEnd + 24 : LastFlexEnd + 24] = put_cmd_in_ert("\\end{cvcolumns}")
1955 def revert_ModernCV_4(document):
1956 " Reverts the style Social to TeX-code "
1957 if document.textclass == "moderncv":
1958 # revert the layouts
1959 revert_ModernCV(document)
1963 p = find_token(document.body, "\\begin_layout Social", p)
1965 pEnd = find_end_of_layout(document.body, p)
1966 document.body[p] = document.body[p].replace("\\begin_layout Social", "\\begin_layout Standard")
1967 document.body[p + 1 : p + 1] = put_cmd_in_ert("\\social")
1968 hasOpt = find_token(document.body, "[", p + 9)
1970 document.body[p + 30 : p + 30] = put_cmd_in_ert("{")
1971 document.body[p + 41 : p + 41] = put_cmd_in_ert("}")
1973 document.body[p + 11 : p + 11] = put_cmd_in_ert("{")
1974 document.body[p + 21 : p + 21] = put_cmd_in_ert("}")
1980 def convert_ModernCV(document):
1981 " Converts ERT of modernCV to InsetArgument "
1982 if document.textclass == "moderncv":
1990 i = find_token(document.body, "\\begin_layout DoubleItem", i)
1992 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1993 document.body[o] = document.body[o].replace("\\begin_layout DoubleItem", "\\begin_layout DoubleListItem")
1996 j = find_token(document.body, "\\begin_layout Entry", j)
1998 convert_TeX_brace_to_Argument(document, j, 1, 5, False, False)
2001 k = find_token(document.body, "\\begin_layout Item", k)
2003 convert_TeX_brace_to_Argument(document, k, 1, 1, False, False)
2006 m = find_token(document.body, "\\begin_layout Language", m)
2008 convert_TeX_brace_to_Argument(document, m, 1, 2, False, False)
2010 if i == -1 and j == -1 and k == -1 and m == -1:
2014 def revert_Initials(document):
2015 " Reverts InsetArgument of Initial to TeX-code "
2018 i = find_token(document.body, "\\begin_layout Initial", i)
2021 # first arg (optional) and second arg (first mandatory) are supported in LyX 2.0.x
2022 revert_Argument_to_TeX_brace(document, i, 0, 3, 3, False, False)
2026 def convert_Initials(document):
2027 " Converts ERT of Initial to InsetArgument "
2030 i = find_token(document.body, "\\begin_layout Initial", i)
2033 document.warning(str(i))
2034 convert_TeX_brace_to_Argument(document, i, 3, 3, False, False)
2038 def revert_literate(document):
2039 " Revert Literate document to old format "
2040 if del_token(document.header, "noweb", 0):
2041 document.textclass = "literate-" + document.textclass
2044 i = find_token(document.body, "\\begin_layout Chunk", i)
2047 document.body[i] = "\\begin_layout Scrap"
2051 def convert_literate(document):
2052 " Convert Literate document to new format"
2053 i = find_token(document.header, "\\textclass", 0)
2054 if (i != -1) and "literate-" in document.header[i]:
2055 document.textclass = document.header[i].replace("\\textclass literate-", "")
2056 j = find_token(document.header, "\\begin_modules", 0)
2058 document.header.insert(j + 1, "noweb")
2060 document.header.insert(i + 1, "\\end_modules")
2061 document.header.insert(i + 1, "noweb")
2062 document.header.insert(i + 1, "\\begin_modules")
2065 i = find_token(document.body, "\\begin_layout Scrap", i)
2068 document.body[i] = "\\begin_layout Chunk"
2072 def revert_itemargs(document):
2073 " Reverts \\item arguments to TeX-code "
2076 i = find_token(document.body, "\\begin_inset Argument item:", i)
2079 j = find_end_of_inset(document.body, i)
2080 # Find containing paragraph layout
2081 parent = get_containing_layout(document.body, i)
2083 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2087 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2088 endPlain = find_end_of_layout(document.body, beginPlain)
2089 content = document.body[beginPlain + 1 : endPlain]
2090 del document.body[i:j+1]
2091 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2092 document.body[parbeg : parbeg] = subst
2096 def revert_garamondx_newtxmath(document):
2097 " Revert native garamond newtxmath definition to LaTeX "
2099 i = find_token(document.header, "\\font_math", 0)
2102 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
2103 val = get_value(document.header, "\\font_math", i)
2104 if val == "garamondx-ntxm":
2105 add_to_preamble(document, "\\usepackage[garamondx]{newtxmath}")
2106 document.header[i] = "\\font_math auto"
2109 def revert_garamondx(document):
2110 " Revert native garamond font definition to LaTeX "
2112 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
2113 i = find_token(document.header, "\\font_roman garamondx", 0)
2116 j = find_token(document.header, "\\font_osf true", 0)
2119 preamble = "\\usepackage"
2121 preamble += "[osfI]"
2122 preamble += "{garamondx}"
2123 add_to_preamble(document, [preamble])
2124 document.header[i] = "\\font_roman default"
2127 def convert_beamerargs(document):
2128 " Converts beamer arguments to new layout "
2130 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2131 if document.textclass not in beamer_classes:
2134 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
2135 list_layouts = ["Itemize", "Enumerate", "Description"]
2136 rx = re.compile(r'^\\begin_inset Argument (\d+)$')
2140 i = find_token(document.body, "\\begin_inset Argument", i)
2143 # Find containing paragraph layout
2144 parent = get_containing_layout(document.body, i)
2146 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2151 layoutname = parent[0]
2152 for p in range(parbeg, parend):
2153 if layoutname in shifted_layouts:
2154 m = rx.match(document.body[p])
2156 argnr = int(m.group(1))
2158 document.body[p] = "\\begin_inset Argument %d" % argnr
2159 if layoutname == "AgainFrame":
2160 m = rx.match(document.body[p])
2162 document.body[p] = "\\begin_inset Argument 3"
2163 if document.body[p + 4] == "\\begin_inset ERT":
2164 if document.body[p + 9].startswith("<"):
2165 # This is an overlay specification
2167 document.body[p + 9] = document.body[p + 9][1:]
2168 if document.body[p + 9].endswith(">"):
2170 document.body[p + 9] = document.body[p + 9][:-1]
2172 document.body[p] = "\\begin_inset Argument 2"
2173 if layoutname in list_layouts:
2174 m = rx.match(document.body[p])
2176 if m.group(1) == "1":
2177 if document.body[p + 4] == "\\begin_inset ERT":
2178 if document.body[p + 9].startswith("<"):
2179 # This is an overlay specification
2181 document.body[p + 9] = document.body[p + 9][1:]
2182 if document.body[p + 9].endswith(">"):
2184 document.body[p + 9] = document.body[p + 9][:-1]
2185 elif layoutname != "Itemize":
2187 document.body[p] = "\\begin_inset Argument 2"
2191 def convert_againframe_args(document):
2192 " Converts beamer AgainFrame to new layout "
2194 # FIXME: This currently only works if the arguments are in one single ERT
2196 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2197 if document.textclass not in beamer_classes:
2202 i = find_token(document.body, "\\begin_layout AgainFrame", i)
2205 parent = get_containing_layout(document.body, i)
2207 document.warning("Wrong parent layout!")
2211 if document.body[parbeg] == "\\begin_inset ERT":
2212 ertcont = parbeg + 5
2213 if document.body[ertcont].startswith("[<"):
2214 # This is a default overlay specification
2216 document.body[ertcont] = document.body[ertcont][2:]
2217 if document.body[ertcont].endswith(">]"):
2219 document.body[ertcont] = document.body[ertcont][:-2]
2220 elif document.body[ertcont].endswith("]"):
2222 tok = document.body[ertcont].find('>][')
2224 subst = [document.body[ertcont][:tok],
2225 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2226 'status collapsed', '', '\\begin_layout Plain Layout',
2227 document.body[ertcont][tok + 3:-1]]
2228 document.body[ertcont : ertcont + 1] = subst
2229 # Convert to ArgInset
2230 document.body[parbeg] = "\\begin_inset Argument 2"
2233 elif document.body[ertcont].startswith("<"):
2234 # This is an overlay specification
2236 document.body[ertcont] = document.body[ertcont][1:]
2237 if document.body[ertcont].endswith(">"):
2239 document.body[ertcont] = document.body[ertcont][:-1]
2240 # Convert to ArgInset
2241 document.body[parbeg] = "\\begin_inset Argument 1"
2242 elif document.body[ertcont].endswith(">]"):
2244 tok = document.body[ertcont].find('>[<')
2246 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2247 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2248 'status collapsed', '', '\\begin_layout Plain Layout',
2249 document.body[ertcont][tok + 3:-2]]
2250 # Convert to ArgInset
2251 document.body[parbeg] = "\\begin_inset Argument 1"
2252 elif document.body[ertcont].endswith("]"):
2254 tok = document.body[ertcont].find('>[<')
2257 tokk = document.body[ertcont].find('>][')
2259 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2260 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2261 'status collapsed', '', '\\begin_layout Plain Layout',
2262 document.body[ertcont][tok + 3:tokk],
2263 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2264 'status collapsed', '', '\\begin_layout Plain Layout',
2265 document.body[ertcont][tokk + 3:-1]]
2267 tokk = document.body[ertcont].find('>[')
2269 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tokk],
2270 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2271 'status collapsed', '', '\\begin_layout Plain Layout',
2272 document.body[ertcont][tokk + 2:-1]]
2273 # Convert to ArgInset
2274 document.body[parbeg] = "\\begin_inset Argument 1"
2277 elif document.body[ertcont].startswith("["):
2278 # This is an ERT option
2280 document.body[ertcont] = document.body[ertcont][1:]
2281 if document.body[ertcont].endswith("]"):
2283 document.body[ertcont] = document.body[ertcont][:-1]
2284 # Convert to ArgInset
2285 document.body[parbeg] = "\\begin_inset Argument 3"
2291 def convert_corollary_args(document):
2292 " Converts beamer corrolary-style ERT arguments native InsetArgs "
2294 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2295 if document.textclass not in beamer_classes:
2298 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2299 for lay in corollary_layouts:
2302 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2305 parent = get_containing_layout(document.body, i)
2307 document.warning("Wrong parent layout!")
2311 if document.body[parbeg] == "\\begin_inset ERT":
2312 ertcont = parbeg + 5
2313 if document.body[ertcont].startswith("<"):
2314 # This is an overlay specification
2316 document.body[ertcont] = document.body[ertcont][1:]
2317 if document.body[ertcont].endswith(">"):
2319 document.body[ertcont] = document.body[ertcont][:-1]
2320 elif document.body[ertcont].endswith("]"):
2322 tok = document.body[ertcont].find('>[')
2324 subst = [document.body[ertcont][:tok],
2325 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2326 'status collapsed', '', '\\begin_layout Plain Layout',
2327 document.body[ertcont][tok + 2:-1]]
2328 document.body[ertcont : ertcont + 1] = subst
2329 # Convert to ArgInset
2330 document.body[parbeg] = "\\begin_inset Argument 1"
2333 elif document.body[ertcont].startswith("["):
2334 # This is an ERT option
2336 document.body[ertcont] = document.body[ertcont][1:]
2337 if document.body[ertcont].endswith("]"):
2339 document.body[ertcont] = document.body[ertcont][:-1]
2340 # Convert to ArgInset
2341 document.body[parbeg] = "\\begin_inset Argument 2"
2348 def convert_quote_args(document):
2349 " Converts beamer quote style ERT args to native InsetArgs "
2351 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2352 if document.textclass not in beamer_classes:
2355 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2356 for lay in quote_layouts:
2359 i = find_token(document.body, "\\begin_layout " + lay, i)
2362 parent = get_containing_layout(document.body, i)
2364 document.warning("Wrong parent layout!")
2368 if document.body[parbeg] == "\\begin_inset ERT":
2369 if document.body[i + 6].startswith("<"):
2370 # This is an overlay specification
2372 document.body[i + 6] = document.body[i + 6][1:]
2373 if document.body[i + 6].endswith(">"):
2375 document.body[i + 6] = document.body[i + 6][:-1]
2376 # Convert to ArgInset
2377 document.body[i + 1] = "\\begin_inset Argument 1"
2381 def revert_beamerargs(document):
2382 " Reverts beamer arguments to old layout "
2384 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2385 if document.textclass not in beamer_classes:
2389 list_layouts = ["Itemize", "Enumerate", "Description"]
2390 headings = ["Part", "Section", "Section*", "Subsection", "Subsection*",
2391 "Subsubsection", "Subsubsection*", "FrameSubtitle", "NoteItem"]
2392 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2393 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2394 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2397 i = find_token(document.body, "\\begin_inset Argument", i)
2400 # Find containing paragraph layout
2401 parent = get_containing_layout(document.body, i)
2403 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2408 realparbeg = parent[3]
2409 layoutname = parent[0]
2411 for p in range(parbeg, parend):
2415 if layoutname in headings:
2416 m = rx.match(document.body[p])
2420 # Find containing paragraph layout
2421 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2422 endPlain = find_end_of_layout(document.body, beginPlain)
2423 endInset = find_end_of_inset(document.body, p)
2424 argcontent = document.body[beginPlain + 1 : endPlain]
2426 realparend = realparend - len(document.body[p : endInset + 1])
2428 del document.body[p : endInset + 1]
2429 if layoutname == "FrameSubtitle":
2430 pre = put_cmd_in_ert("\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2431 elif layoutname == "NoteItem":
2432 pre = put_cmd_in_ert("\\note<") + argcontent + put_cmd_in_ert(">[item]")
2433 elif layoutname.endswith('*'):
2434 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower()[:-1] + "<") + argcontent + put_cmd_in_ert(">*")
2436 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2437 secarg = find_token(document.body, "\\begin_inset Argument 2", parbeg, parend)
2439 # Find containing paragraph layout
2440 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", secarg)
2441 endPlain = find_end_of_layout(document.body, beginPlain)
2442 endInset = find_end_of_inset(document.body, secarg)
2443 argcontent = document.body[beginPlain + 1 : endPlain]
2445 realparend = realparend - len(document.body[secarg : endInset + 1])
2446 del document.body[secarg : endInset + 1]
2447 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2448 pre += put_cmd_in_ert("{")
2449 document.body[parbeg] = "\\begin_layout Standard"
2450 document.body[realparbeg : realparbeg] = pre
2451 pe = find_end_of_layout(document.body, parbeg)
2452 post = put_cmd_in_ert("}")
2453 document.body[pe : pe] = post
2454 realparend += len(pre) + len(post)
2455 if layoutname == "AgainFrame":
2456 m = rx.match(document.body[p])
2460 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2461 endPlain = find_end_of_layout(document.body, beginPlain)
2462 endInset = find_end_of_inset(document.body, p)
2463 content = document.body[beginPlain + 1 : endPlain]
2465 realparend = realparend - len(document.body[p : endInset + 1])
2467 del document.body[p : endInset + 1]
2468 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2469 document.body[realparbeg : realparbeg] = subst
2470 if layoutname == "Overprint":
2471 m = rx.match(document.body[p])
2475 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2476 endPlain = find_end_of_layout(document.body, beginPlain)
2477 endInset = find_end_of_inset(document.body, p)
2478 content = document.body[beginPlain + 1 : endPlain]
2480 realparend = realparend - len(document.body[p : endInset + 1])
2482 del document.body[p : endInset + 1]
2483 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2484 document.body[realparbeg : realparbeg] = subst
2485 if layoutname == "OverlayArea":
2486 m = rx.match(document.body[p])
2490 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2491 endPlain = find_end_of_layout(document.body, beginPlain)
2492 endInset = find_end_of_inset(document.body, p)
2493 content = document.body[beginPlain + 1 : endPlain]
2495 realparend = realparend - len(document.body[p : endInset + 1])
2497 del document.body[p : endInset + 1]
2498 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2499 document.body[realparbeg : realparbeg] = subst
2500 if layoutname in list_layouts:
2501 m = rx.match(document.body[p])
2505 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2506 endPlain = find_end_of_layout(document.body, beginPlain)
2507 endInset = find_end_of_inset(document.body, p)
2508 content = document.body[beginPlain + 1 : endPlain]
2509 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2510 realparend = realparend + len(subst) - len(content)
2511 document.body[beginPlain + 1 : endPlain] = subst
2512 elif argnr == "item:1":
2513 j = find_end_of_inset(document.body, i)
2514 # Find containing paragraph layout
2515 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2516 endPlain = find_end_of_layout(document.body, beginPlain)
2517 content = document.body[beginPlain + 1 : endPlain]
2518 del document.body[i:j+1]
2519 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2520 document.body[realparbeg : realparbeg] = subst
2521 elif argnr == "item:2":
2522 j = find_end_of_inset(document.body, i)
2523 # Find containing paragraph layout
2524 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2525 endPlain = find_end_of_layout(document.body, beginPlain)
2526 content = document.body[beginPlain + 1 : endPlain]
2527 del document.body[i:j+1]
2528 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2529 document.body[realparbeg : realparbeg] = subst
2530 if layoutname in quote_layouts:
2531 m = rx.match(document.body[p])
2535 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2536 endPlain = find_end_of_layout(document.body, beginPlain)
2537 endInset = find_end_of_inset(document.body, p)
2538 content = document.body[beginPlain + 1 : endPlain]
2540 realparend = realparend - len(document.body[p : endInset + 1])
2542 del document.body[p : endInset + 1]
2543 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2544 document.body[realparbeg : realparbeg] = subst
2545 if layoutname in corollary_layouts:
2546 m = rx.match(document.body[p])
2550 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2551 endPlain = find_end_of_layout(document.body, beginPlain)
2552 endInset = find_end_of_inset(document.body, p)
2553 content = document.body[beginPlain + 1 : endPlain]
2555 realparend = realparend - len(document.body[p : endInset + 1])
2557 del document.body[p : endInset + 1]
2558 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2559 document.body[realparbeg : realparbeg] = subst
2564 def revert_beamerargs2(document):
2565 " Reverts beamer arguments to old layout, step 2 "
2567 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2568 if document.textclass not in beamer_classes:
2572 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
2573 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2574 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2577 i = find_token(document.body, "\\begin_inset Argument", i)
2580 # Find containing paragraph layout
2581 parent = get_containing_layout(document.body, i)
2583 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2588 realparbeg = parent[3]
2589 layoutname = parent[0]
2591 for p in range(parbeg, parend):
2595 if layoutname in shifted_layouts:
2596 m = rx.match(document.body[p])
2600 document.body[p] = "\\begin_inset Argument 1"
2601 if layoutname in corollary_layouts:
2602 m = rx.match(document.body[p])
2606 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2607 endPlain = find_end_of_layout(document.body, beginPlain)
2608 endInset = find_end_of_inset(document.body, p)
2609 content = document.body[beginPlain + 1 : endPlain]
2611 realparend = realparend - len(document.body[p : endInset + 1])
2613 del document.body[p : endInset + 1]
2614 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2615 document.body[realparbeg : realparbeg] = subst
2616 if layoutname == "OverlayArea":
2617 m = rx.match(document.body[p])
2621 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2622 endPlain = find_end_of_layout(document.body, beginPlain)
2623 endInset = find_end_of_inset(document.body, p)
2624 content = document.body[beginPlain + 1 : endPlain]
2626 realparend = realparend - len(document.body[p : endInset + 1])
2628 del document.body[p : endInset + 1]
2629 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2630 document.body[realparbeg : realparbeg] = subst
2631 if layoutname == "AgainFrame":
2632 m = rx.match(document.body[p])
2636 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2637 endPlain = find_end_of_layout(document.body, beginPlain)
2638 endInset = find_end_of_inset(document.body, p)
2639 content = document.body[beginPlain + 1 : endPlain]
2641 realparend = realparend - len(document.body[p : endInset + 1])
2643 del document.body[p : endInset + 1]
2644 subst = put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
2645 document.body[realparbeg : realparbeg] = subst
2649 def revert_beamerargs3(document):
2650 " Reverts beamer arguments to old layout, step 3 "
2652 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2653 if document.textclass not in beamer_classes:
2656 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2659 i = find_token(document.body, "\\begin_inset Argument", i)
2662 # Find containing paragraph layout
2663 parent = get_containing_layout(document.body, i)
2665 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2670 realparbeg = parent[3]
2671 layoutname = parent[0]
2673 for p in range(parbeg, parend):
2677 if layoutname == "AgainFrame":
2678 m = rx.match(document.body[p])
2682 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2683 endPlain = find_end_of_layout(document.body, beginPlain)
2684 endInset = find_end_of_inset(document.body, p)
2685 content = document.body[beginPlain + 1 : endPlain]
2687 realparend = realparend - len(document.body[p : endInset + 1])
2689 del document.body[p : endInset + 1]
2690 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2691 document.body[realparbeg : realparbeg] = subst
2695 def revert_beamerflex(document):
2696 " Reverts beamer Flex insets "
2698 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2699 if document.textclass not in beamer_classes:
2702 new_flexes = {"Bold" : "\\textbf", "Emphasize" : "\\emph", "Only" : "\\only",
2703 "Uncover" : "\\uncover", "Visible" : "\\visible",
2704 "Invisible" : "\\invisible", "Alternative" : "\\alt",
2705 "Beamer_Note" : "\\note"}
2706 old_flexes = {"Alert" : "\\alert", "Structure" : "\\structure"}
2707 rx = re.compile(r'^\\begin_inset Flex (.+)$')
2711 i = find_token(document.body, "\\begin_inset Flex", i)
2714 m = rx.match(document.body[i])
2716 flextype = m.group(1)
2717 z = find_end_of_inset(document.body, i)
2719 document.warning("Can't find end of Flex " + flextype + " inset.")
2722 if flextype in new_flexes:
2723 pre = put_cmd_in_ert(new_flexes[flextype])
2724 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2726 argend = find_end_of_inset(document.body, arg)
2728 document.warning("Can't find end of Argument!")
2731 # Find containing paragraph layout
2732 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2733 endPlain = find_end_of_layout(document.body, beginPlain)
2734 argcontent = document.body[beginPlain + 1 : endPlain]
2736 z = z - len(document.body[arg : argend + 1])
2738 del document.body[arg : argend + 1]
2739 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2740 arg = find_token(document.body, "\\begin_inset Argument 2", i, z)
2742 argend = find_end_of_inset(document.body, arg)
2744 document.warning("Can't find end of Argument!")
2747 # Find containing paragraph layout
2748 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2749 endPlain = find_end_of_layout(document.body, beginPlain)
2750 argcontent = document.body[beginPlain + 1 : endPlain]
2752 z = z - len(document.body[arg : argend + 1])
2754 del document.body[arg : argend + 1]
2755 if flextype == "Alternative":
2756 pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
2758 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2759 pre += put_cmd_in_ert("{")
2760 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2761 endPlain = find_end_of_layout(document.body, beginPlain)
2763 z = z - len(document.body[i : beginPlain + 1])
2765 document.body[i : beginPlain + 1] = pre
2766 post = put_cmd_in_ert("}")
2767 document.body[z - 2 : z + 1] = post
2768 elif flextype in old_flexes:
2769 pre = put_cmd_in_ert(old_flexes[flextype])
2770 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2774 argend = find_end_of_inset(document.body, arg)
2776 document.warning("Can't find end of Argument!")
2779 # Find containing paragraph layout
2780 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2781 endPlain = find_end_of_layout(document.body, beginPlain)
2782 argcontent = document.body[beginPlain + 1 : endPlain]
2784 z = z - len(document.body[arg : argend + 1])
2786 del document.body[arg : argend + 1]
2787 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2788 pre += put_cmd_in_ert("{")
2789 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2790 endPlain = find_end_of_layout(document.body, beginPlain)
2792 z = z - len(document.body[i : beginPlain + 1])
2794 document.body[i : beginPlain + 1] = pre
2795 post = put_cmd_in_ert("}")
2796 document.body[z - 2 : z + 1] = post
2801 def revert_beamerblocks(document):
2802 " Reverts beamer block arguments to ERT "
2804 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2805 if document.textclass not in beamer_classes:
2808 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2810 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2813 i = find_token(document.body, "\\begin_inset Argument", i)
2816 # Find containing paragraph layout
2817 parent = get_containing_layout(document.body, i)
2819 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2824 realparbeg = parent[3]
2825 layoutname = parent[0]
2827 for p in range(parbeg, parend):
2831 if layoutname in blocks:
2832 m = rx.match(document.body[p])
2836 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2837 endPlain = find_end_of_layout(document.body, beginPlain)
2838 endInset = find_end_of_inset(document.body, p)
2839 content = document.body[beginPlain + 1 : endPlain]
2841 realparend = realparend - len(document.body[p : endInset + 1])
2843 del document.body[p : endInset + 1]
2844 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2845 document.body[realparbeg : realparbeg] = subst
2847 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2848 endPlain = find_end_of_layout(document.body, beginPlain)
2849 endInset = find_end_of_inset(document.body, p)
2850 content = document.body[beginPlain + 1 : endPlain]
2852 realparend = realparend - len(document.body[p : endInset + 1])
2854 del document.body[p : endInset + 1]
2855 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2856 document.body[realparbeg : realparbeg] = subst
2861 def convert_beamerblocks(document):
2862 " Converts beamer block ERT args to native InsetArgs "
2864 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2865 if document.textclass not in beamer_classes:
2868 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2872 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2875 parent = get_containing_layout(document.body, i)
2876 if parent == False or parent[1] != i:
2877 document.warning("Wrong parent layout!")
2883 if document.body[parbeg] == "\\begin_inset ERT":
2884 ertcont = parbeg + 5
2886 if document.body[ertcont].startswith("<"):
2887 # This is an overlay specification
2889 document.body[ertcont] = document.body[ertcont][1:]
2890 if document.body[ertcont].endswith(">"):
2892 document.body[ertcont] = document.body[ertcont][:-1]
2893 # Convert to ArgInset
2894 document.body[parbeg] = "\\begin_inset Argument 1"
2895 elif document.body[ertcont].endswith("}"):
2897 tok = document.body[ertcont].find('>{')
2899 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2900 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2901 'status collapsed', '', '\\begin_layout Plain Layout',
2902 document.body[ertcont][tok + 2:-1]]
2903 # Convert to ArgInset
2904 document.body[parbeg] = "\\begin_inset Argument 1"
2905 elif document.body[ertcont].startswith("{"):
2906 # This is the block title
2907 if document.body[ertcont].endswith("}"):
2908 # strip off the braces
2909 document.body[ertcont] = document.body[ertcont][1:-1]
2910 # Convert to ArgInset
2911 document.body[parbeg] = "\\begin_inset Argument 2"
2912 elif count_pars_in_inset(document.body, ertcont) > 1:
2913 # Multipar ERT. Skip this.
2916 convert_TeX_brace_to_Argument(document, i, 2, 2, False, True)
2919 j = find_end_of_layout(document.body, i)
2921 document.warning("end of layout not found!")
2922 k = find_token(document.body, "\\begin_inset Argument", i, j)
2924 document.warning("InsetArgument not found!")
2926 l = find_end_of_inset(document.body, k)
2927 m = find_token(document.body, "\\begin_inset ERT", l, j)
2935 def convert_overprint(document):
2936 " Convert old beamer overprint layouts to ERT "
2938 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2939 if document.textclass not in beamer_classes:
2944 i = find_token(document.body, "\\begin_layout Overprint", i)
2947 # Find end of sequence
2948 j = find_end_of_sequence(document.body, i)
2950 document.warning("Malformed LyX document. Cannot find end of Overprint sequence!")
2954 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
2956 if document.body[j] == "\\end_deeper":
2957 esubst = ["", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
2959 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
2960 endseq = endseq + len(esubst) - len(document.body[j : j])
2961 document.body[j : j] = esubst
2962 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
2964 argend = find_end_of_layout(document.body, argbeg)
2966 document.warning("Malformed LyX document. Cannot find end of Overprint argument!")
2969 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
2970 endPlain = find_end_of_layout(document.body, beginPlain)
2971 content = document.body[beginPlain + 1 : endPlain]
2973 endseq = endseq - len(document.body[argbeg : argend + 1])
2975 del document.body[argbeg : argend + 1]
2976 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2978 endseq = endseq - len(document.body[i : i])
2979 document.body[i : i] = subst + ["\\end_layout"]
2980 endseq += len(subst)
2982 for p in range(i, endseq):
2983 if document.body[p] == "\\begin_layout Overprint":
2984 document.body[p] = "\\begin_layout Standard"
2989 def revert_overprint(document):
2990 " Revert old beamer overprint layouts to ERT "
2992 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2993 if document.textclass not in beamer_classes:
2998 i = find_token(document.body, "\\begin_layout Overprint", i)
3001 # Find end of sequence
3002 j = find_end_of_sequence(document.body, i)
3004 document.warning("Malformed LyX document. Cannot find end of Overprint sequence!")
3008 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
3009 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}")
3010 endseq = endseq + len(esubst) - len(document.body[j : j])
3011 if document.body[j] == "\\end_deeper":
3012 document.body[j : j] = ["\\end_deeper", ""] + esubst
3014 document.body[j : j] = esubst
3017 if document.body[r] == "\\begin_deeper":
3018 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3020 document.body[r] = ""
3021 document.body[s] = ""
3025 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
3027 argend = find_end_of_inset(document.body, argbeg)
3029 document.warning("Malformed LyX document. Cannot find end of Overprint argument!")
3032 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3033 endPlain = find_end_of_layout(document.body, beginPlain)
3034 content = document.body[beginPlain + 1 : endPlain]
3036 endseq = endseq - len(document.body[argbeg : argend])
3038 del document.body[argbeg : argend + 1]
3039 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3041 endseq = endseq - len(document.body[i : i])
3042 document.body[i : i] = subst + ["\\end_layout"]
3043 endseq += len(subst)
3049 if document.body[p] == "\\begin_layout Overprint":
3050 q = find_end_of_layout(document.body, p)
3052 document.warning("Malformed LyX document. Cannot find end of Overprint layout!")
3055 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\onslide")
3056 argbeg = find_token(document.body, "\\begin_inset Argument item:1", p, q)
3058 argend = find_end_of_inset(document.body, argbeg)
3060 document.warning("Malformed LyX document. Cannot find end of Overprint item argument!")
3063 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3064 endPlain = find_end_of_layout(document.body, beginPlain)
3065 content = document.body[beginPlain + 1 : endPlain]
3067 endseq = endseq - len(document.body[argbeg : argend + 1])
3069 del document.body[argbeg : argend + 1]
3070 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3071 endseq = endseq - len(document.body[p : p + 1]) + len(subst)
3072 document.body[p : p + 1] = subst
3078 def revert_frametitle(document):
3079 " Reverts beamer frametitle layout to ERT "
3081 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3082 if document.textclass not in beamer_classes:
3085 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
3088 i = find_token(document.body, "\\begin_layout FrameTitle", i)
3091 j = find_end_of_layout(document.body, i)
3093 document.warning("Malformed LyX document: Can't find end of FrameTitle layout")
3097 document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
3098 endlay += len(put_cmd_in_ert("}"))
3099 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\frametitle")
3100 for p in range(i, j):
3103 m = rx.match(document.body[p])
3107 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3108 endPlain = find_end_of_layout(document.body, beginPlain)
3109 endInset = find_end_of_inset(document.body, p)
3110 content = document.body[beginPlain + 1 : endPlain]
3112 endlay = endlay - len(document.body[p : endInset + 1])
3114 del document.body[p : endInset + 1]
3115 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3117 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3118 endPlain = find_end_of_layout(document.body, beginPlain)
3119 endInset = find_end_of_inset(document.body, p)
3120 content = document.body[beginPlain + 1 : endPlain]
3122 endlay = endlay - len(document.body[p : endInset + 1])
3124 del document.body[p : endInset + 1]
3125 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3127 subst += put_cmd_in_ert("{")
3128 document.body[i : i + 1] = subst
3132 def convert_epigraph(document):
3133 " Converts memoir epigraph to new syntax "
3135 if document.textclass != "memoir":
3140 i = find_token(document.body, "\\begin_layout Epigraph", i)
3143 j = find_end_of_layout(document.body, i)
3145 document.warning("Malformed LyX document: Can't find end of Epigraph layout")
3150 ert = find_token(document.body, "\\begin_inset ERT", i, j)
3152 endInset = find_end_of_inset(document.body, ert)
3153 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", ert)
3154 endPlain = find_end_of_layout(document.body, beginPlain)
3155 ertcont = beginPlain + 2
3156 if document.body[ertcont] == "}{":
3158 # Convert to ArgInset
3159 endlay = endlay - 2 * len(document.body[j])
3160 begsubst = ['\\begin_inset Argument post:1', 'status collapsed', '',
3161 '\\begin_layout Plain Layout']
3162 endsubst = ['\\end_layout', '', '\\end_inset', '', document.body[j]]
3163 document.body[j : j + 1] = endsubst
3164 document.body[endInset + 1 : endInset + 1] = begsubst
3166 endlay += len(begsubst) + len(endsubst)
3167 endlay = endlay - len(document.body[ert : endInset + 1])
3168 del document.body[ert : endInset + 1]
3173 def revert_epigraph(document):
3174 " Reverts memoir epigraph argument to ERT "
3176 if document.textclass != "memoir":
3181 i = find_token(document.body, "\\begin_layout Epigraph", i)
3184 j = find_end_of_layout(document.body, i)
3186 document.warning("Malformed LyX document: Can't find end of Epigraph layout")
3191 p = find_token(document.body, "\\begin_layout Argument post:1", i, j)
3193 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3194 endPlain = find_end_of_layout(document.body, beginPlain)
3195 endInset = find_end_of_inset(document.body, p)
3196 content = document.body[beginPlain + 1 : endPlain]
3198 endlay = endlay - len(document.body[p : endInset + 1])
3200 del document.body[p : endInset + 1]
3201 subst += put_cmd_in_ert("}{") + content
3203 subst += put_cmd_in_ert("}{")
3205 document.body[j : j] = subst + document.body[j : j]
3209 def convert_captioninsets(document):
3210 " Converts caption insets to new syntax "
3214 i = find_token(document.body, "\\begin_inset Caption", i)
3217 document.body[i] = "\\begin_inset Caption Standard"
3221 def revert_captioninsets(document):
3222 " Reverts caption insets to old syntax "
3226 i = find_token(document.body, "\\begin_inset Caption Standard", i)
3229 document.body[i] = "\\begin_inset Caption"
3233 def convert_captionlayouts(document):
3234 " Convert caption layouts to caption insets. "
3237 "Captionabove": "Above",
3238 "Captionbelow": "Below",
3239 "FigCaption" : "FigCaption",
3240 "Table_Caption" : "Table",
3241 "CenteredCaption" : "Centered",
3242 "Bicaption" : "Bicaption",
3247 i = find_token(document.body, "\\begin_layout", i)
3250 val = get_value(document.body, "\\begin_layout", i)
3251 if val in caption_dict.keys():
3252 j = find_end_of_layout(document.body, i)
3254 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3257 document.body[j:j] = ["\\end_layout", "", "\\end_inset", "", ""]
3258 document.body[i:i+1] = ["\\begin_layout %s" % document.default_layout,
3259 "\\begin_inset Caption %s" % caption_dict[val], "",
3260 "\\begin_layout %s" % document.default_layout]
3264 def revert_captionlayouts(document):
3265 " Revert caption insets to caption layouts. "
3268 "Above" : "Captionabove",
3269 "Below" : "Captionbelow",
3270 "FigCaption" : "FigCaption",
3271 "Table" : "Table_Caption",
3272 "Centered" : "CenteredCaption",
3273 "Bicaption" : "Bicaption",
3277 rx = re.compile(r'^\\begin_inset Caption (\S+)$')
3279 i = find_token(document.body, "\\begin_inset Caption", i)
3283 m = rx.match(document.body[i])
3287 if val not in caption_dict.keys():
3291 # We either need to delete the previous \begin_layout line, or we
3292 # need to end the previous layout if this inset is not in the first
3293 # position of the paragraph.
3294 layout_before = find_token_backwards(document.body, "\\begin_layout", i)
3295 if layout_before == -1:
3296 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3298 layout_line = document.body[layout_before]
3299 del_layout_before = True
3300 l = layout_before + 1
3302 if document.body[l] != "":
3303 del_layout_before = False
3306 if del_layout_before:
3307 del document.body[layout_before:i]
3310 document.body[i:i] = ["\\end_layout", ""]
3313 # Find start of layout in the inset and end of inset
3314 j = find_token(document.body, "\\begin_layout", i)
3316 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3318 k = find_end_of_inset(document.body, i)
3320 document.warning("Malformed LyX document: Missing `\\end_inset'.")
3323 # We either need to delete the following \end_layout line, or we need
3324 # to restart the old layout if this inset is not at the paragraph end.
3325 layout_after = find_token(document.body, "\\end_layout", k)
3326 if layout_after == -1:
3327 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3329 del_layout_after = True
3331 while l < layout_after:
3332 if document.body[l] != "":
3333 del_layout_after = False
3336 if del_layout_after:
3337 del document.body[k+1:layout_after+1]
3339 document.body[k+1:k+1] = [layout_line, ""]
3341 # delete \begin_layout and \end_inset and replace \begin_inset with
3342 # "\begin_layout XXX". This works because we can only have one
3343 # paragraph in the caption inset: The old \end_layout will be recycled.
3344 del document.body[k]
3345 if document.body[k] == "":
3346 del document.body[k]
3347 del document.body[j]
3348 if document.body[j] == "":
3349 del document.body[j]
3350 document.body[i] = "\\begin_layout %s" % caption_dict[val]
3351 if document.body[i+1] == "":
3352 del document.body[i+1]
3356 def revert_fragileframe(document):
3357 " Reverts beamer FragileFrame layout to ERT "
3359 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3360 if document.textclass not in beamer_classes:
3365 i = find_token(document.body, "\\begin_layout FragileFrame", i)
3368 # Find end of sequence
3369 j = find_end_of_sequence(document.body, i)
3371 document.warning("Malformed LyX document. Cannot find end of FragileFrame sequence!")
3375 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{frame}")
3376 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{frame}")
3377 endseq = endseq + len(esubst) - len(document.body[j : j])
3378 if document.body[j] == "\\end_deeper":
3379 document.body[j : j] = ["\\end_deeper", ""] + esubst
3381 document.body[j : j] = esubst
3382 for q in range(i, j):
3383 if document.body[q] == "\\begin_layout FragileFrame":
3384 document.body[q] = "\\begin_layout %s" % document.default_layout
3387 if document.body[r] == "\\begin_deeper":
3388 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3390 document.body[r] = ""
3391 document.body[s] = ""
3395 for p in range(1, 5):
3396 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, j)
3399 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3400 endPlain = find_end_of_layout(document.body, beginPlain)
3401 endInset = find_end_of_inset(document.body, arg)
3402 content = document.body[beginPlain + 1 : endPlain]
3404 j = j - len(document.body[arg : endInset + 1])
3406 del document.body[arg : endInset + 1]
3407 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3409 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3410 endPlain = find_end_of_layout(document.body, beginPlain)
3411 endInset = find_end_of_inset(document.body, arg)
3412 content = document.body[beginPlain + 1 : endPlain]
3414 j = j - len(document.body[arg : endInset + 1])
3416 del document.body[arg : endInset + 1]
3417 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3419 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3420 endPlain = find_end_of_layout(document.body, beginPlain)
3421 endInset = find_end_of_inset(document.body, arg)
3422 content = document.body[beginPlain + 1 : endPlain]
3424 j = j - len(document.body[arg : endInset + 1])
3426 del document.body[arg : endInset + 1]
3427 subst += put_cmd_in_ert("[fragile,") + content + put_cmd_in_ert("]")
3429 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3430 endPlain = find_end_of_layout(document.body, beginPlain)
3431 endInset = find_end_of_inset(document.body, arg)
3432 content = document.body[beginPlain + 1 : endPlain]
3434 j = j - len(document.body[arg : endInset + 1])
3436 del document.body[arg : endInset + 1]
3437 subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
3439 subst += put_cmd_in_ert("[fragile]")
3441 document.body[i : i + 1] = subst
3445 def revert_newframes(document):
3446 " Reverts beamer Frame and PlainFrame layouts to old forms "
3448 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3449 if document.textclass not in beamer_classes:
3453 "Frame" : "BeginFrame",
3454 "PlainFrame" : "BeginPlainFrame",
3457 rx = re.compile(r'^\\begin_layout (\S+)$')
3460 i = find_token(document.body, "\\begin_layout", i)
3464 m = rx.match(document.body[i])
3468 if val not in frame_dict.keys():
3471 # Find end of sequence
3472 j = find_end_of_sequence(document.body, i)
3474 document.warning("Malformed LyX document. Cannot find end of Frame sequence!")
3478 subst = ["\\begin_layout %s" % frame_dict[val]]
3479 esubst = ["\\end_layout", "", "\\begin_layout EndFrame", "", "\\end_layout"]
3480 endseq = endseq + len(esubst) - len(document.body[j : j])
3481 if document.body[j] == "\\end_deeper":
3482 document.body[j : j] = ["\\end_deeper", ""] + esubst
3484 document.body[j : j] = esubst
3485 for q in range(i, j):
3486 if document.body[q] == "\\begin_layout %s" % val:
3487 document.body[q] = "\\begin_layout %s" % document.default_layout
3490 if document.body[r] == "\\begin_deeper":
3491 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3493 document.body[r] = ""
3494 document.body[s] = ""
3498 l = find_end_of_layout(document.body, i)
3499 for p in range(1, 5):
3500 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, l)
3503 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3504 endPlain = find_end_of_layout(document.body, beginPlain)
3505 endInset = find_end_of_inset(document.body, arg)
3506 content = document.body[beginPlain + 1 : endPlain]
3508 l = l - len(document.body[arg : endInset + 1])
3510 del document.body[arg : endInset + 1]
3511 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3513 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3514 endPlain = find_end_of_layout(document.body, beginPlain)
3515 endInset = find_end_of_inset(document.body, arg)
3516 content = document.body[beginPlain + 1 : endPlain]
3518 l = l - len(document.body[arg : endInset + 1])
3520 del document.body[arg : endInset + 1]
3521 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3523 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3524 endPlain = find_end_of_layout(document.body, beginPlain)
3525 endInset = find_end_of_inset(document.body, arg)
3526 content = document.body[beginPlain + 1 : endPlain]
3528 l = l - len(document.body[arg : endInset + 1])
3530 del document.body[arg : endInset + 1]
3531 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3533 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3534 endPlain = find_end_of_layout(document.body, beginPlain)
3535 endInset = find_end_of_inset(document.body, arg)
3536 content = document.body[beginPlain + 1 : endPlain]
3538 l = l - len(document.body[arg : endInset + 1])
3540 del document.body[arg : endInset + 1]
3543 document.body[i : i + 1] = subst
3546 # known encodings that do not change their names (same LyX and LaTeX names)
3547 known_enc_tuple = ("auto", "default", "ansinew", "applemac", "armscii8", "ascii",
3548 "cp437", "cp437de", "cp850", "cp852", "cp855", "cp858", "cp862", "cp865", "cp866",
3549 "cp1250", "cp1251", "cp1252", "cp1255", "cp1256", "cp1257", "koi8-r", "koi8-u",
3550 "pt154", "pt254", "tis620-0", "utf8", "utf8x", "utf8-plain")
3552 def convert_encodings(document):
3553 "Use the LyX names of the encodings instead of the LaTeX names."
3554 LaTeX2LyX_enc_dict = {
3555 "8859-6": "iso8859-6",
3556 "8859-8": "iso8859-8",
3558 "euc": "euc-jp-platex",
3563 "iso88595": "iso8859-5",
3564 "iso-8859-7": "iso8859-7",
3566 "jis": "jis-platex",
3568 "l7xenc": "iso8859-13",
3569 "latin1": "iso8859-1",
3570 "latin2": "iso8859-2",
3571 "latin3": "iso8859-3",
3572 "latin4": "iso8859-4",
3573 "latin5": "iso8859-9",
3574 "latin9": "iso8859-15",
3575 "latin10": "iso8859-16",
3576 "SJIS": "shift-jis",
3577 "sjis": "shift-jis-platex",
3580 i = find_token(document.header, "\\inputencoding" , 0)
3583 val = get_value(document.header, "\\inputencoding", i)
3584 if val in LaTeX2LyX_enc_dict.keys():
3585 document.header[i] = "\\inputencoding %s" % LaTeX2LyX_enc_dict[val]
3586 elif val not in known_enc_tuple:
3587 document.warning("Ignoring unknown input encoding: `%s'" % val)
3590 def revert_encodings(document):
3591 """Revert to using the LaTeX names of the encodings instead of the LyX names.
3592 Also revert utf8-platex to sjis, the language default when using Japanese.
3594 LyX2LaTeX_enc_dict = {
3599 "euc-jp-platex": "euc",
3602 "iso8859-1": "latin1",
3603 "iso8859-2": "latin2",
3604 "iso8859-3": "latin3",
3605 "iso8859-4": "latin4",
3606 "iso8859-5": "iso88595",
3607 "iso8859-6": "8859-6",
3608 "iso8859-7": "iso-8859-7",
3609 "iso8859-8": "8859-8",
3610 "iso8859-9": "latin5",
3611 "iso8859-13": "l7xenc",
3612 "iso8859-15": "latin9",
3613 "iso8859-16": "latin10",
3615 "jis-platex": "jis",
3616 "shift-jis": "SJIS",
3617 "shift-jis-platex": "sjis",
3619 "utf8-platex": "sjis"
3621 i = find_token(document.header, "\\inputencoding" , 0)
3624 val = get_value(document.header, "\\inputencoding", i)
3625 if val in LyX2LaTeX_enc_dict.keys():
3626 document.header[i] = "\\inputencoding %s" % LyX2LaTeX_enc_dict[val]
3627 elif val not in known_enc_tuple:
3628 document.warning("Ignoring unknown input encoding: `%s'" % val)
3631 def revert_IEEEtran_3(document):
3633 Reverts Flex Insets to TeX-code
3635 if document.textclass == "IEEEtran":
3641 h = find_token(document.body, "\\begin_inset Flex Author Mark", h)
3643 endh = find_end_of_inset(document.body, h)
3644 document.body[endh - 2 : endh + 1] = put_cmd_in_ert("}")
3645 document.body[h : h + 4] = put_cmd_in_ert("\\IEEEauthorrefmark{")
3648 i = find_token(document.body, "\\begin_inset Flex Author Name", i)
3650 endi = find_end_of_inset(document.body, i)
3651 document.body[endi - 2 : endi + 1] = put_cmd_in_ert("}")
3652 document.body[i : i + 4] = put_cmd_in_ert("\\IEEEauthorblockN{")
3655 j = find_token(document.body, "\\begin_inset Flex Author Affiliation", j)
3657 endj = find_end_of_inset(document.body, j)
3658 document.body[endj - 2 : endj + 1] = put_cmd_in_ert("}")
3659 document.body[j : j + 4] = put_cmd_in_ert("\\IEEEauthorblockA{")
3661 if i == -1 and j == -1 and h == -1:
3665 def revert_kurier_fonts(document):
3666 " Revert kurier font definition to LaTeX "
3668 i = find_token(document.header, "\\font_math", 0)
3670 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3671 val = get_value(document.header, "\\font_math", i)
3672 if val == "kurier-math":
3673 add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
3674 "\\usepackage[math]{kurier}\n" \
3675 "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
3676 document.header[i] = "\\font_math auto"
3678 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3679 kurier_fonts = ["kurier", "kurierc", "kurierl", "kurierlc"]
3680 k = find_token(document.header, "\\font_sans kurier", 0)
3682 sf = get_value(document.header, "\\font_sans", k)
3683 if sf in kurier_fonts:
3684 add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
3685 document.header[k] = "\\font_sans default"
3687 def revert_iwona_fonts(document):
3688 " Revert iwona font definition to LaTeX "
3690 i = find_token(document.header, "\\font_math", 0)
3692 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3693 val = get_value(document.header, "\\font_math", i)
3694 if val == "iwona-math":
3695 add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
3696 "\\usepackage[math]{iwona}\n" \
3697 "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
3698 document.header[i] = "\\font_math auto"
3700 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3701 iwona_fonts = ["iwona", "iwonac", "iwonal", "iwonalc"]
3702 k = find_token(document.header, "\\font_sans iwona", 0)
3704 sf = get_value(document.header, "\\font_sans", k)
3705 if sf in iwona_fonts:
3706 add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
3707 document.header[k] = "\\font_sans default"
3710 def revert_new_libertines(document):
3711 " Revert new libertine font definition to LaTeX "
3713 if find_token(document.header, "\\use_non_tex_fonts true", 0) != -1:
3716 i = find_token(document.header, "\\font_typewriter libertine-mono", 0)
3718 preamble = "\\usepackage"
3719 sc = find_token(document.header, "\\font_tt_scale", 0)
3721 scval = get_value(document.header, "\\font_tt_scale", sc)
3723 preamble += "[scale=%f]" % (float(scval) / 100)
3724 document.header[sc] = "\\font_tt_scale 100"
3725 preamble += "{libertineMono-type1}"
3726 add_to_preamble(document, [preamble])
3727 document.header[i] = "\\font_typewriter default"
3729 k = find_token(document.header, "\\font_sans biolinum", 0)
3731 preamble = "\\usepackage"
3733 j = find_token(document.header, "\\font_osf true", 0)
3738 sc = find_token(document.header, "\\font_sf_scale", 0)
3740 scval = get_value(document.header, "\\font_sf_scale", sc)
3742 options += ",scale=%f" % (float(scval) / 100)
3743 document.header[sc] = "\\font_sf_scale 100"
3745 preamble += "[" + options +"]"
3746 preamble += "{biolinum-type1}"
3747 add_to_preamble(document, [preamble])
3748 document.header[k] = "\\font_sans default"
3751 def convert_lyxframes(document):
3752 " Converts old beamer frames to new style "
3754 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3755 if document.textclass not in beamer_classes:
3758 framebeg = ["BeginFrame", "BeginPlainFrame"]
3759 frameend = ["Frame", "PlainFrame", "EndFrame", "BeginFrame", "BeginPlainFrame", "AgainFrame",
3760 "Section", "Section*", "Subsection", "Subsection*", "Subsubsection", "Subsubsection*"]
3761 for lay in framebeg:
3764 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
3767 parent = get_containing_layout(document.body, i)
3768 if parent == False or parent[1] != i:
3769 document.warning("Wrong parent layout!")
3772 frametype = parent[0]
3776 # Step I: Convert ERT arguments
3777 # FIXME: This currently only works if the arguments are in one single ERT
3779 if document.body[parbeg] == "\\begin_inset ERT":
3780 ertend = find_end_of_inset(document.body, parbeg)
3782 document.warning("Malformed LyX document: missing ERT \\end_inset")
3784 ertcont = parbeg + 5
3785 if document.body[ertcont].startswith("[<"):
3786 # This is a default overlay specification
3788 document.body[ertcont] = document.body[ertcont][2:]
3789 if document.body[ertcont].endswith(">]"):
3791 document.body[ertcont] = document.body[ertcont][:-2]
3792 elif document.body[ertcont].endswith("]"):
3794 tok = document.body[ertcont].find('>][')
3796 subst = [document.body[ertcont][:tok],
3797 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
3798 'status collapsed', '', '\\begin_layout Plain Layout',
3799 document.body[ertcont][tok + 3:-1]]
3800 document.body[ertcont : ertcont + 1] = subst
3802 # Convert to ArgInset
3803 document.body[parbeg] = "\\begin_inset Argument 2"
3804 elif document.body[ertcont].startswith("<"):
3805 # This is an overlay specification
3807 document.body[ertcont] = document.body[ertcont][1:]
3808 if document.body[ertcont].endswith(">"):
3810 document.body[ertcont] = document.body[ertcont][:-1]
3811 # Convert to ArgInset
3812 document.body[parbeg] = "\\begin_inset Argument 1"
3813 elif document.body[ertcont].endswith(">]"):
3815 tok = document.body[ertcont].find('>[<')
3817 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
3818 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
3819 'status collapsed', '', '\\begin_layout Plain Layout',
3820 document.body[ertcont][tok + 3:-2]]
3821 # Convert to ArgInset
3822 document.body[parbeg] = "\\begin_inset Argument 1"
3824 elif document.body[ertcont].endswith("]"):
3826 tok = document.body[ertcont].find('>[<')
3829 tokk = document.body[ertcont].find('>][')
3831 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
3832 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
3833 'status collapsed', '', '\\begin_layout Plain Layout',
3834 document.body[ertcont][tok + 3:tokk],
3835 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
3836 'status collapsed', '', '\\begin_layout Plain Layout',
3837 document.body[ertcont][tokk + 3:-1]]
3840 tokk = document.body[ertcont].find('>[')
3842 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tokk],
3843 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
3844 'status collapsed', '', '\\begin_layout Plain Layout',
3845 document.body[ertcont][tokk + 2:-1]]
3847 # Convert to ArgInset
3848 document.body[parbeg] = "\\begin_inset Argument 1"
3849 elif document.body[ertcont].startswith("["):
3850 # This is an ERT option
3852 document.body[ertcont] = document.body[ertcont][1:]
3853 if document.body[ertcont].endswith("]"):
3855 document.body[ertcont] = document.body[ertcont][:-1]
3856 # Convert to ArgInset
3857 document.body[parbeg] = "\\begin_inset Argument 3"
3858 # End of argument conversion
3859 # Step II: Now rename the layout and convert the title to an argument
3860 j = find_end_of_layout(document.body, i)
3861 document.body[j : j + 1] = ['\\end_layout', '', '\\end_inset', '', '\\end_layout']
3862 if lay == "BeginFrame":
3863 document.body[i] = "\\begin_layout Frame"
3865 document.body[i] = "\\begin_layout PlainFrame"
3866 document.body[ertend + 1 : ertend + 1] = ['\\begin_inset Argument 4',
3867 'status open', '', '\\begin_layout Plain Layout']
3868 # Step III: find real frame end
3872 fend = find_token(document.body, "\\begin_layout", jj)
3874 document.warning("Malformed LyX document: No real frame end!")
3876 val = get_value(document.body, "\\begin_layout", fend)
3877 if val not in frameend:
3880 old = document.body[fend]
3881 if val == frametype:
3882 document.body[fend : fend] = ['\\end_deeper', '', '\\begin_layout Separator', '', '\\end_layout']
3884 document.body[fend : fend] = ['\\end_deeper']
3885 document.body[j + 1 : j + 1] = ['', '\\begin_deeper']
3890 def remove_endframes(document):
3891 " Remove deprecated beamer endframes "
3893 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3894 if document.textclass not in beamer_classes:
3899 i = find_token_exact(document.body, "\\begin_layout EndFrame", i)
3902 j = find_end_of_layout(document.body, i)
3904 document.warning("Malformed LyX document: Missing \\end_layout to EndFrame")
3907 del document.body[i : j + 1]
3910 def revert_powerdot_flexes(document):
3911 " Reverts powerdot flex insets "
3913 if document.textclass != "powerdot":
3916 flexes = {"Onslide" : "\\onslide",
3917 "Onslide*" : "\\onslide*",
3918 "Onslide+" : "\\onslide+"}
3919 rx = re.compile(r'^\\begin_inset Flex (.+)$')
3923 i = find_token(document.body, "\\begin_inset Flex", i)
3926 m = rx.match(document.body[i])
3928 flextype = m.group(1)
3929 z = find_end_of_inset(document.body, i)
3931 document.warning("Can't find end of Flex " + flextype + " inset.")
3934 if flextype in flexes:
3935 pre = put_cmd_in_ert(flexes[flextype])
3936 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
3938 argend = find_end_of_inset(document.body, arg)
3940 document.warning("Can't find end of Argument!")
3943 # Find containing paragraph layout
3944 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3945 endPlain = find_end_of_layout(document.body, beginPlain)
3946 argcontent = document.body[beginPlain + 1 : endPlain]
3948 z = z - len(document.body[arg : argend + 1])
3950 del document.body[arg : argend + 1]
3951 pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
3952 pre += put_cmd_in_ert("{")
3953 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
3954 endPlain = find_end_of_layout(document.body, beginPlain)
3956 z = z - len(document.body[i : beginPlain + 1])
3958 document.body[i : beginPlain + 1] = pre
3959 post = put_cmd_in_ert("}")
3960 document.body[z - 2 : z + 1] = post
3964 def revert_powerdot_pause(document):
3965 " Reverts powerdot pause layout to ERT "
3967 if document.textclass != "powerdot":
3972 i = find_token(document.body, "\\begin_layout Pause", i)
3975 j = find_end_of_layout(document.body, i)
3977 document.warning("Malformed LyX document: Can't find end of Pause layout")
3981 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\pause")
3982 for p in range(i, j):
3985 arg = find_token(document.body, "\\begin_inset Argument 1", i, j)
3987 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3988 endPlain = find_end_of_layout(document.body, beginPlain)
3989 endInset = find_end_of_inset(document.body, p)
3990 content = document.body[beginPlain + 1 : endPlain]
3992 endlay = endlay - len(document.body[p : endInset + 1])
3994 del document.body[p : endInset + 1]
3995 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3997 document.body[i : i + 1] = subst
4001 def revert_powerdot_itemargs(document):
4002 " Reverts powerdot item arguments to ERT "
4004 if document.textclass != "powerdot":
4008 list_layouts = ["Itemize", "ItemizeType1", "Enumerate", "EnumerateType1"]
4009 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
4012 i = find_token(document.body, "\\begin_inset Argument", i)
4015 # Find containing paragraph layout
4016 parent = get_containing_layout(document.body, i)
4018 document.warning("Malformed LyX document: Can't find parent paragraph layout")
4023 realparbeg = parent[3]
4024 layoutname = parent[0]
4026 for p in range(parbeg, parend):
4030 if layoutname in list_layouts:
4031 m = rx.match(document.body[p])
4034 if argnr == "item:1":
4035 j = find_end_of_inset(document.body, i)
4036 # Find containing paragraph layout
4037 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
4038 endPlain = find_end_of_layout(document.body, beginPlain)
4039 content = document.body[beginPlain + 1 : endPlain]
4040 del document.body[i:j+1]
4041 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
4042 document.body[realparbeg : realparbeg] = subst
4043 elif argnr == "item:2":
4044 j = find_end_of_inset(document.body, i)
4045 # Find containing paragraph layout
4046 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
4047 endPlain = find_end_of_layout(document.body, beginPlain)
4048 content = document.body[beginPlain + 1 : endPlain]
4049 del document.body[i:j+1]
4050 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
4051 document.body[realparbeg : realparbeg] = subst
4056 def revert_powerdot_columns(document):
4057 " Reverts powerdot twocolumn to TeX-code "
4058 if document.textclass != "powerdot":
4061 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
4064 i = find_token(document.body, "\\begin_layout Twocolumn", i)
4067 j = find_end_of_layout(document.body, i)
4069 document.warning("Malformed LyX document: Can't find end of Twocolumn layout")
4073 document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
4074 endlay += len(put_cmd_in_ert("}"))
4075 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\twocolumn")
4076 for p in range(i, j):
4079 m = rx.match(document.body[p])
4083 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
4084 endPlain = find_end_of_layout(document.body, beginPlain)
4085 endInset = find_end_of_inset(document.body, p)
4086 content = document.body[beginPlain + 1 : endPlain]
4088 endlay = endlay - len(document.body[p : endInset + 1])
4090 del document.body[p : endInset + 1]
4091 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
4093 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
4094 endPlain = find_end_of_layout(document.body, beginPlain)
4095 endInset = find_end_of_inset(document.body, p)
4096 content = document.body[beginPlain + 1 : endPlain]
4098 endlay = endlay - len(document.body[p : endInset + 1])
4100 del document.body[p : endInset + 1]
4101 subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
4103 subst += put_cmd_in_ert("{")
4104 document.body[i : i + 1] = subst
4108 def revert_mbox_fbox(document):
4109 'Convert revert mbox/fbox boxes to TeX-code'
4112 i = find_token(document.body, "\\begin_inset Box", i)
4115 j = find_token(document.body, "width", i)
4117 document.warning("Malformed LyX document: Can't find box width")
4119 width = get_value(document.body, "width", j)
4120 k = find_end_of_inset(document.body, j)
4122 document.warning("Malformed LyX document: Can't find end of box inset")
4125 BeginLayout = find_token(document.body, "\\begin_layout Plain Layout", j)
4126 EndLayout = find_token(document.body, "\\end_layout", BeginLayout)
4127 # replace if width is ""
4129 document.body[EndLayout:k + 1] = put_cmd_in_ert("}")
4130 if document.body[i] == "\\begin_inset Box Frameless":
4131 document.body[i:BeginLayout + 1] = put_cmd_in_ert("\\mbox{")
4132 if document.body[i] == "\\begin_inset Box Boxed":
4133 document.body[i:BeginLayout + 1] = put_cmd_in_ert("\\fbox{")
4137 def revert_starred_caption(document):
4138 " Reverts unnumbered longtable caption insets "
4142 i = find_token(document.body, "\\begin_inset Caption LongTableNoNumber", i)
4145 # This is not equivalent, but since the caption inset is a full blown
4146 # text inset a true conversion to ERT is too difficult.
4147 document.body[i] = "\\begin_inset Caption Standard"
4151 def revert_forced_local_layout(document):
4154 i = find_token(document.header, "\\begin_forced_local_layout", i)
4157 j = find_end_of(document.header, i, "\\begin_forced_local_layout", "\\end_forced_local_layout")
4159 # this should not happen
4161 regexp = re.compile(r'\s*forcelocal', re.IGNORECASE)
4162 k = find_re(document.header, regexp, i, j)
4164 del document.header[k]
4166 k = find_re(document.header, regexp, i, j)
4167 k = find_token(document.header, "\\begin_local_layout", 0)
4169 document.header[i] = "\\begin_local_layout"
4170 document.header[j] = "\\end_local_layout"
4172 l = find_end_of(document.header, k, "\\begin_local_layout", "\\end_local_layout")
4174 # this should not happen
4176 lines = document.header[i+1 : j]
4178 document.header[k+1 : k+1] = lines
4179 document.header[i : j ] = []
4181 document.header[i : j ] = []
4182 document.header[k+1 : k+1] = lines
4185 def revert_aa1(document):
4186 " Reverts InsetArguments of aa to TeX-code "
4187 if document.textclass == "aa":
4191 i = find_token(document.body, "\\begin_layout Abstract (structured)", i)
4193 revert_Argument_to_TeX_brace(document, i, 0, 1, 4, False, False)
4199 def revert_aa2(document):
4200 " Reverts InsetArguments of aa to TeX-code "
4201 if document.textclass == "aa":
4205 i = find_token(document.body, "\\begin_layout Abstract (structured)", i)
4207 document.body[i] = "\\begin_layout Abstract"
4213 def revert_tibetan(document):
4214 "Set the document language for Tibetan to English"
4216 if document.language == "tibetan":
4217 document.language = "english"
4218 i = find_token(document.header, "\\language", 0)
4220 document.header[i] = "\\language english"
4222 while j < len(document.body):
4223 j = find_token(document.body, "\\lang tibetan", j)
4225 document.body[j] = document.body[j].replace("\\lang tibetan", "\\lang english")
4228 j = len(document.body)
4237 # the idea here is that we will have a sequence of chunk paragraphs
4238 # we want to convert them to paragraphs in a chunk inset
4239 # the last will be discarded
4240 # the first should look like: <<FROGS>>=
4241 # will will discard the delimiters, and put the contents into the
4242 # optional argument of the inset
4243 def convert_chunks(document):
4244 first_re = re.compile(r'<<(.*)>>=')
4247 # the beginning of this sequence
4249 # find start of a block of chunks
4250 i = find_token(document.body, "\\begin_layout Chunk", i)
4258 # process the one we just found
4259 j = find_end_of_layout(document.body, i)
4261 document.warning("Malformed LyX documents. Can't find end of Chunk layout!")
4263 thischunk = "".join(document.body[i + 1:j])
4264 contents.append(document.body[i + 1:j])
4266 if thischunk == "@":
4269 # look for the next one
4271 i = find_token(document.body, "\\begin_layout", i)
4275 layout = get_value(document.body, "\\begin_layout", i)
4276 #sys.stderr.write(layout+ '\n')
4277 if layout != "Chunk":
4281 # error, but we can try to continue
4288 # the last chunk should simply have an "@" in it
4290 if ''.join(contents[-1]) != "@":
4291 document.warning("Unexpected chunk contents.")
4296 # the first item should look like: <<FROGS>>=
4297 # we want the inside
4298 optarg = ' '.join(contents[0])
4300 match = first_re.search(optarg)
4302 optarg = match.groups()[0]
4305 newstuff = ['\\begin_layout Standard',
4306 '\\begin_inset Flex Chunk',
4308 '\\begin_layout Plain Layout', '']
4312 ['\\begin_inset Argument 1',
4314 '\\begin_layout Plain Layout',
4322 newstuff.extend(['', '\\begin_layout Plain Layout', ''])
4326 newstuff.append('\\end_layout')
4328 newstuff.extend(['', '\\end_inset', '', '\\end_layout', ''])
4330 document.body[start:end] = newstuff
4332 k += len(newstuff) - (end - start)
4335 def revert_chunks(document):
4338 i = find_token(document.body, "\\begin_inset Flex Chunk", i)
4342 iend = find_end_of_inset(document.body, i)
4344 document.warning("Can't find end of Chunk!")
4348 # Look for optional argument
4350 ostart = find_token(document.body, "\\begin_inset Argument 1", i, iend)
4352 oend = find_end_of_inset(document.body, ostart)
4353 k = find_token(document.body, "\\begin_layout Plain Layout", ostart, oend)
4355 document.warning("Malformed LyX document: Can't find argument contents!")
4357 m = find_end_of_layout(document.body, k)
4358 optarg = "".join(document.body[k+1:m])
4361 # We now remove the optional argument, so we have something
4362 # uniform on which to work
4363 document.body[ostart : oend + 1] = []
4364 # iend is now invalid
4365 iend = find_end_of_inset(document.body, i)
4367 retval = get_containing_layout(document.body, i)
4369 document.warning("Can't find containing layout for Chunk!")
4372 (lname, lstart, lend, pstart) = retval
4373 # we now want to work through the various paragraphs, and collect their contents
4377 k = find_token(document.body, "\\begin_layout Plain Layout", k, lend)
4380 j = find_end_of_layout(document.body, k)
4382 document.warning("Can't find end of layout inside chunk!")
4384 parlist.append(document.body[k+1:j])
4386 # we now need to wrap all of these paragraphs in chunks
4389 newlines.extend(["\\begin_layout Chunk", "", "<<" + optarg + ">>=", "\\end_layout", ""])
4390 for stuff in parlist:
4391 newlines.extend(["\\begin_layout Chunk"] + stuff + ["\\end_layout", ""])
4392 newlines.extend(["\\begin_layout Chunk", "", "@", "\\end_layout", ""])
4393 # replace old content with new content
4394 document.body[lstart : lend + 1] = newlines
4395 i = lstart + len(newlines)
4402 supported_versions = ["2.1.0","2.1"]
4405 [415, [convert_undertilde]],
4407 [417, [convert_japanese_encodings]],
4410 [420, [convert_biblio_style]],
4411 [421, [convert_longtable_captions]],
4412 [422, [convert_use_packages]],
4413 [423, [convert_use_mathtools]],
4414 [424, [convert_cite_engine_type]],
4418 [428, [convert_cell_rotation]],
4419 [429, [convert_table_rotation]],
4420 [430, [convert_listoflistings]],
4421 [431, [convert_use_amssymb]],
4423 [433, [convert_armenian]],
4431 [441, [convert_mdnomath]],
4436 [446, [convert_latexargs]],
4437 [447, [convert_IEEEtran, convert_AASTeX, convert_AGUTeX, convert_IJMP, convert_SIGPLAN, convert_SIGGRAPH, convert_EuropeCV, convert_Initials, convert_ModernCV]],
4438 [448, [convert_literate]],
4441 [451, [convert_beamerargs, convert_againframe_args, convert_corollary_args, convert_quote_args]],
4442 [452, [convert_beamerblocks]],
4443 [453, [convert_use_stmaryrd]],
4444 [454, [convert_overprint]],
4446 [456, [convert_epigraph]],
4447 [457, [convert_use_stackrel]],
4448 [458, [convert_captioninsets, convert_captionlayouts]],
4453 [463, [convert_encodings]],
4454 [464, [convert_use_cancel]],
4455 [465, [convert_lyxframes, remove_endframes]],
4461 [471, [convert_cite_engine_type_default]],
4464 [474, [convert_chunks]],
4468 [473, [revert_chunks]],
4469 [472, [revert_tibetan]],
4470 [471, [revert_aa1,revert_aa2]],
4471 [470, [revert_cite_engine_type_default]],
4472 [469, [revert_forced_local_layout]],
4473 [468, [revert_starred_caption]],
4474 [467, [revert_mbox_fbox]],
4475 [466, [revert_iwona_fonts]],
4476 [465, [revert_powerdot_flexes, revert_powerdot_pause, revert_powerdot_itemargs, revert_powerdot_columns]],
4478 [463, [revert_use_cancel]],
4479 [462, [revert_encodings]],
4480 [461, [revert_new_libertines]],
4481 [460, [revert_kurier_fonts]],
4482 [459, [revert_IEEEtran_3]],
4483 [458, [revert_fragileframe, revert_newframes]],
4484 [457, [revert_captioninsets, revert_captionlayouts]],
4485 [456, [revert_use_stackrel]],
4486 [455, [revert_epigraph]],
4487 [454, [revert_frametitle]],
4488 [453, [revert_overprint]],
4489 [452, [revert_use_stmaryrd]],
4490 [451, [revert_beamerblocks]],
4491 [450, [revert_beamerargs, revert_beamerargs2, revert_beamerargs3, revert_beamerflex]],
4492 [449, [revert_garamondx, revert_garamondx_newtxmath]],
4493 [448, [revert_itemargs]],
4494 [447, [revert_literate]],
4495 [446, [revert_IEEEtran, revert_IEEEtran_2, revert_AASTeX, revert_AGUTeX, revert_IJMP, revert_SIGPLAN, revert_SIGGRAPH, revert_EuropeCV, revert_Initials, revert_ModernCV_3, revert_ModernCV_4]],
4496 [445, [revert_latexargs]],
4497 [444, [revert_uop]],
4498 [443, [revert_biolinum]],
4500 [441, [revert_newtxmath]],
4501 [440, [revert_mdnomath]],
4502 [439, [revert_mathfonts]],
4503 [438, [revert_minionpro]],
4504 [437, [revert_ipadeco, revert_ipachar]],
4505 [436, [revert_texgyre]],
4506 [435, [revert_mathdesign]],
4507 [434, [revert_txtt]],
4508 [433, [revert_libertine]],
4509 [432, [revert_armenian]],
4510 [431, [revert_languages, revert_ancientgreek]],
4511 [430, [revert_use_amssymb]],
4512 [429, [revert_listoflistings]],
4513 [428, [revert_table_rotation]],
4514 [427, [revert_cell_rotation]],
4515 [426, [revert_tipa]],
4516 [425, [revert_verbatim]],
4517 [424, [revert_cancel]],
4518 [423, [revert_cite_engine_type]],
4519 [422, [revert_use_mathtools]],
4520 [421, [revert_use_packages]],
4521 [420, [revert_longtable_captions]],
4522 [419, [revert_biblio_style]],
4523 [418, [revert_australian]],
4524 [417, [revert_justification]],
4525 [416, [revert_japanese_encodings]],
4526 [415, [revert_negative_space, revert_math_spaces]],
4527 [414, [revert_undertilde]],
4528 [413, [revert_visible_space]]
4532 if __name__ == "__main__":