1 # -*- coding: utf-8 -*-
2 # This file is part of lyx2lyx
3 # -*- coding: utf-8 -*-
4 # Copyright (C) 2011 The LyX team
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 2
9 # of the License, or (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 """ Convert files to the file format generated by LyX 2.1"""
26 # Uncomment only what you need to import, please.
28 from parser_tools import count_pars_in_inset, del_token, find_token, find_token_exact, \
29 find_token_backwards, find_end_of, find_end_of_inset, find_end_of_layout, \
30 find_end_of_sequence, find_re, get_option_value, get_containing_layout, \
31 get_value, get_quoted_value, set_option_value
33 #from parser_tools import find_token, find_end_of, find_tokens, \
34 #find_end_of_inset, find_end_of_layout, \
35 #is_in_inset, del_token, check_token
37 from lyx2lyx_tools import add_to_preamble, put_cmd_in_ert, get_ert
39 #from lyx2lyx_tools import insert_to_preamble, \
40 # lyx2latex, latex_length, revert_flex_inset, \
41 # revert_font_attrs, hex2ratio, str2bool
43 ####################################################################
44 # Private helper functions
46 #def remove_option(lines, m, option):
47 #''' removes option from line m. returns whether we did anything '''
48 #l = lines[m].find(option)
51 #val = lines[m][l:].split('"')[1]
52 #lines[m] = lines[m][:l - 1] + lines[m][l+len(option + '="' + val + '"'):]
56 ###############################################################################
58 ### Conversion and reversion routines
60 ###############################################################################
62 def revert_visible_space(document):
63 "Revert InsetSpace visible into its ERT counterpart"
66 i = find_token(document.body, "\\begin_inset space \\textvisiblespace{}", i)
69 end = find_end_of_inset(document.body, i)
70 subst = put_cmd_in_ert("\\textvisiblespace{}")
71 document.body[i:end + 1] = subst
74 def convert_undertilde(document):
75 " Load undertilde automatically "
76 i = find_token(document.header, "\\use_mathdots" , 0)
78 i = find_token(document.header, "\\use_mhchem" , 0)
80 i = find_token(document.header, "\\use_esint" , 0)
82 document.warning("Malformed LyX document: Can't find \\use_mathdots.")
84 j = find_token(document.preamble, "\\usepackage{undertilde}", 0)
86 document.header.insert(i + 1, "\\use_undertilde 0")
88 document.header.insert(i + 1, "\\use_undertilde 2")
89 del document.preamble[j]
92 def revert_undertilde(document):
93 " Load undertilde if used in the document "
94 undertilde = find_token(document.header, "\\use_undertilde" , 0)
96 document.warning("No \\use_undertilde line. Assuming auto.")
98 val = get_value(document.header, "\\use_undertilde", undertilde)
99 del document.header[undertilde]
103 document.warning("Invalid \\use_undertilde value: " + val + ". Assuming auto.")
104 # probably usedots has not been changed, but be safe.
112 add_to_preamble(document, ["\\usepackage{undertilde}"])
115 # so we are in the auto case. we want to load undertilde if \utilde is used.
118 i = find_token(document.body, '\\begin_inset Formula', i)
121 j = find_end_of_inset(document.body, i)
123 document.warning("Malformed LyX document: Can't find end of Formula inset at line " + str(i))
126 code = "\n".join(document.body[i:j])
127 if code.find("\\utilde") != -1:
128 add_to_preamble(document, ["\\@ifundefined{utilde}{\\usepackage{undertilde}}"])
133 def revert_negative_space(document):
134 "Revert InsetSpace negmedspace and negthickspace into its TeX-code counterpart"
139 i = find_token(document.body, "\\begin_inset space \\negmedspace{}", i)
141 j = find_token(document.body, "\\begin_inset space \\negthickspace{}", j)
143 # load amsmath in the preamble if not already loaded if we are at the end of checking
145 i = find_token(document.header, "\\use_amsmath 2", 0)
147 add_to_preamble(document, ["\\@ifundefined{negthickspace}{\\usepackage{amsmath}}"])
151 end = find_end_of_inset(document.body, i)
152 subst = put_cmd_in_ert("\\negmedspace{}")
153 document.body[i:end + 1] = subst
154 j = find_token(document.body, "\\begin_inset space \\negthickspace{}", j)
157 end = find_end_of_inset(document.body, j)
158 subst = put_cmd_in_ert("\\negthickspace{}")
159 document.body[j:end + 1] = subst
163 def revert_math_spaces(document):
164 "Revert formulas with protected custom space and protected hfills to TeX-code"
167 i = find_token(document.body, "\\begin_inset Formula", i)
170 j = document.body[i].find("\\hspace*")
172 end = find_end_of_inset(document.body, i)
173 subst = put_cmd_in_ert(document.body[i][21:])
174 document.body[i:end + 1] = subst
178 def convert_japanese_encodings(document):
179 " Rename the japanese encodings to names understood by platex "
181 "EUC-JP-pLaTeX": "euc",
183 "SJIS-pLaTeX": "sjis"
185 i = find_token(document.header, "\\inputencoding" , 0)
188 val = get_value(document.header, "\\inputencoding", i)
189 if val in jap_enc_dict.keys():
190 document.header[i] = "\\inputencoding %s" % jap_enc_dict[val]
193 def revert_japanese_encodings(document):
194 " Revert the japanese encodings name changes "
196 "euc": "EUC-JP-pLaTeX",
198 "sjis": "SJIS-pLaTeX"
200 i = find_token(document.header, "\\inputencoding" , 0)
203 val = get_value(document.header, "\\inputencoding", i)
204 if val in jap_enc_dict.keys():
205 document.header[i] = "\\inputencoding %s" % jap_enc_dict[val]
208 def revert_justification(document):
209 " Revert the \\justification buffer param"
210 if not del_token(document.header, '\\justification', 0):
211 document.warning("Malformed LyX document: Missing \\justification.")
214 def revert_australian(document):
215 "Set English language variants Australian and Newzealand to English"
217 if document.language == "australian" or document.language == "newzealand":
218 document.language = "english"
219 i = find_token(document.header, "\\language", 0)
221 document.header[i] = "\\language english"
224 j = find_token(document.body, "\\lang australian", j)
226 j = find_token(document.body, "\\lang newzealand", 0)
230 document.body[j] = document.body[j].replace("\\lang newzealand", "\\lang english")
232 document.body[j] = document.body[j].replace("\\lang australian", "\\lang english")
236 def convert_biblio_style(document):
237 "Add a sensible default for \\biblio_style based on the citation engine."
238 i = find_token(document.header, "\\cite_engine", 0)
240 engine = get_value(document.header, "\\cite_engine", i).split("_")[0]
241 style = {"basic": "plain", "natbib": "plainnat", "jurabib": "jurabib"}
242 document.header.insert(i + 1, "\\biblio_style " + style[engine])
245 def revert_biblio_style(document):
246 "BibTeX insets with default option use the style defined by \\biblio_style."
247 i = find_token(document.header, "\\biblio_style" , 0)
249 document.warning("No \\biblio_style line. Nothing to do.")
252 default_style = get_value(document.header, "\\biblio_style", i)
253 del document.header[i]
255 # We are looking for bibtex insets having the default option
258 i = find_token(document.body, "\\begin_inset CommandInset bibtex", i)
261 j = find_end_of_inset(document.body, i)
263 document.warning("Malformed LyX document: Can't find end of bibtex inset at line " + str(i))
266 k = find_token(document.body, "options", i, j)
268 options = get_quoted_value(document.body, "options", k)
269 if "default" in options.split(","):
270 document.body[k] = 'options "%s"' \
271 % options.replace("default", default_style)
275 def handle_longtable_captions(document, forward):
278 begin_table = find_token(document.body, '<lyxtabular version=', begin_table)
279 if begin_table == -1:
281 end_table = find_end_of(document.body, begin_table, '<lyxtabular', '</lyxtabular>')
283 document.warning("Malformed LyX document: Could not find end of table.")
286 fline = find_token(document.body, "<features", begin_table, end_table)
288 document.warning("Can't find features for inset at line " + str(begin_table))
291 p = document.body[fline].find("islongtable")
296 numrows = get_option_value(document.body[begin_table], "rows")
298 numrows = int(numrows)
300 document.warning(document.body[begin_table])
301 document.warning("Unable to determine rows!")
302 begin_table = end_table
304 begin_row = begin_table
305 for row in range(numrows):
306 begin_row = find_token(document.body, '<row', begin_row, end_table)
308 document.warning("Can't find row " + str(row + 1))
310 end_row = find_end_of(document.body, begin_row, '<row', '</row>')
312 document.warning("Can't find end of row " + str(row + 1))
315 if (get_option_value(document.body[begin_row], 'caption') == 'true' and
316 get_option_value(document.body[begin_row], 'endfirsthead') != 'true' and
317 get_option_value(document.body[begin_row], 'endhead') != 'true' and
318 get_option_value(document.body[begin_row], 'endfoot') != 'true' and
319 get_option_value(document.body[begin_row], 'endlastfoot') != 'true'):
320 document.body[begin_row] = set_option_value(document.body[begin_row], 'caption', 'true", endfirsthead="true')
321 elif get_option_value(document.body[begin_row], 'caption') == 'true':
322 if get_option_value(document.body[begin_row], 'endfirsthead') == 'true':
323 document.body[begin_row] = set_option_value(document.body[begin_row], 'endfirsthead', 'false')
324 if get_option_value(document.body[begin_row], 'endhead') == 'true':
325 document.body[begin_row] = set_option_value(document.body[begin_row], 'endhead', 'false')
326 if get_option_value(document.body[begin_row], 'endfoot') == 'true':
327 document.body[begin_row] = set_option_value(document.body[begin_row], 'endfoot', 'false')
328 if get_option_value(document.body[begin_row], 'endlastfoot') == 'true':
329 document.body[begin_row] = set_option_value(document.body[begin_row], 'endlastfoot', 'false')
331 # since there could be a tabular inside this one, we
332 # cannot jump to end.
336 def convert_longtable_captions(document):
337 "Add a firsthead flag to caption rows"
338 handle_longtable_captions(document, True)
341 def revert_longtable_captions(document):
342 "remove head/foot flag from caption rows"
343 handle_longtable_captions(document, False)
346 def convert_use_packages(document):
347 "use_xxx yyy => use_package xxx yyy"
348 packages = ["amsmath", "esint", "mathdots", "mhchem", "undertilde"]
350 i = find_token(document.header, "\\use_%s" % p, 0)
352 value = get_value(document.header, "\\use_%s" % p, i)
353 document.header[i] = "\\use_package %s %s" % (p, value)
356 def revert_use_packages(document):
357 "use_package xxx yyy => use_xxx yyy"
358 packages = ["amsmath", "esint", "mathdots", "mhchem", "undertilde"]
359 # the order is arbitrary for the use_package version, and not all packages need to be given.
360 # Ensure a complete list and correct order (important for older LyX versions and especially lyx2lyx)
363 regexp = re.compile(r'(\\use_package\s+%s)' % p)
364 i = find_re(document.header, regexp, j)
366 value = get_value(document.header, "\\use_package %s" % p, i).split()[1]
367 del document.header[i]
369 document.header.insert(j, "\\use_%s %s" % (p, value))
373 def convert_use_package(document, pkg):
374 i = find_token(document.header, "\\use_package", 0)
376 document.warning("Malformed LyX document: Can't find \\use_package.")
378 j = find_token(document.preamble, "\\usepackage{" + pkg + "}", 0)
380 document.header.insert(i + 1, "\\use_package " + pkg + " 0")
382 document.header.insert(i + 1, "\\use_package " + pkg + " 2")
383 del document.preamble[j]
386 def revert_use_package(document, pkg, commands, oldauto):
387 # oldauto defines how the version we are reverting to behaves:
388 # if it is true, the old version uses the package automatically.
389 # if it is false, the old version never uses the package.
390 regexp = re.compile(r'(\\use_package\s+%s)' % pkg)
391 i = find_re(document.header, regexp, 0)
392 value = "1" # default is auto
394 value = get_value(document.header, "\\use_package" , i).split()[1]
395 del document.header[i]
396 if value == "2": # on
397 add_to_preamble(document, ["\\usepackage{" + pkg + "}"])
398 elif value == "1" and not oldauto: # auto
401 i = find_token(document.body, '\\begin_inset Formula', i)
404 j = find_end_of_inset(document.body, i)
406 document.warning("Malformed LyX document: Can't find end of Formula inset at line " + str(i))
409 code = "\n".join(document.body[i:j])
411 if code.find("\\%s" % c) != -1:
412 add_to_preamble(document, ["\\usepackage{" + pkg + "}"])
417 def convert_use_mathtools(document):
418 "insert use_package mathtools"
419 convert_use_package(document, "mathtools")
422 def revert_use_mathtools(document):
423 "remove use_package mathtools"
424 commands = ["mathclap", "mathllap", "mathrlap", \
425 "lgathered", "rgathered", "vcentcolon", "dblcolon", \
426 "coloneqq", "Coloneqq", "coloneq", "Coloneq", "eqqcolon", \
427 "Eqqcolon", "eqcolon", "Eqcolon", "colonapprox", \
428 "Colonapprox", "colonsim", "Colonsim"]
429 revert_use_package(document, "mathtools", commands, False)
432 def convert_use_stmaryrd(document):
433 "insert use_package stmaryrd"
434 convert_use_package(document, "stmaryrd")
437 def revert_use_stmaryrd(document):
438 "remove use_package stmaryrd"
439 # commands provided by stmaryrd.sty but LyX uses other packages:
440 # boxdot lightning, bigtriangledown, bigtriangleup
441 commands = ["shortleftarrow", "shortrightarrow", "shortuparrow", \
442 "shortdownarrow", "Yup", "Ydown", "Yleft", "Yright", \
443 "varcurlyvee", "varcurlywedge", "minuso", "baro", \
444 "sslash", "bbslash", "moo", "varotimes", "varoast", \
445 "varobar", "varodot", "varoslash", "varobslash", \
446 "varocircle", "varoplus", "varominus", "boxast", \
447 "boxbar", "boxslash", "boxbslash", "boxcircle", \
448 "boxbox", "boxempty", "merge", "vartimes", \
449 "fatsemi", "sswarrow", "ssearrow", "curlywedgeuparrow", \
450 "curlywedgedownarrow", "fatslash", "fatbslash", "lbag", \
451 "rbag", "varbigcirc", "leftrightarroweq", \
452 "curlyveedownarrow", "curlyveeuparrow", "nnwarrow", \
453 "nnearrow", "leftslice", "rightslice", "varolessthan", \
454 "varogreaterthan", "varovee", "varowedge", "talloblong", \
455 "interleave", "obar", "obslash", "olessthan", \
456 "ogreaterthan", "ovee", "owedge", "oblong", "inplus", \
457 "niplus", "nplus", "subsetplus", "supsetplus", \
458 "subsetpluseq", "supsetpluseq", "Lbag", "Rbag", \
459 "llbracket", "rrbracket", "llparenthesis", \
460 "rrparenthesis", "binampersand", "bindnasrepma", \
461 "trianglelefteqslant", "trianglerighteqslant", \
462 "ntrianglelefteqslant", "ntrianglerighteqslant", \
463 "llfloor", "rrfloor", "llceil", "rrceil", "arrownot", \
464 "Arrownot", "Mapstochar", "mapsfromchar", "Mapsfromchar", \
465 "leftrightarrowtriangle", "leftarrowtriangle", \
466 "rightarrowtriangle", \
467 "bigcurlyvee", "bigcurlywedge", "bigsqcap", "bigbox", \
468 "bigparallel", "biginterleave", "bignplus", \
469 "varcopyright", "longarrownot", "Longarrownot", \
470 "Mapsto", "mapsfrom", "Mapsfrom" "Longmapsto", \
471 "longmapsfrom", "Longmapsfrom"]
472 revert_use_package(document, "stmaryrd", commands, False)
476 def convert_use_stackrel(document):
477 "insert use_package stackrel"
478 convert_use_package(document, "stackrel")
481 def revert_use_stackrel(document):
482 "remove use_package stackrel"
483 commands = ["stackrel"]
484 revert_use_package(document, "stackrel", commands, False)
487 def convert_cite_engine_type(document):
488 "Determine the \\cite_engine_type from the citation engine."
489 i = find_token(document.header, "\\cite_engine", 0)
492 engine = get_value(document.header, "\\cite_engine", i)
494 engine, type = engine.split("_")
496 type = {"basic": "numerical", "jurabib": "authoryear"}[engine]
497 document.header[i] = "\\cite_engine " + engine
498 document.header.insert(i + 1, "\\cite_engine_type " + type)
501 def revert_cite_engine_type(document):
502 "Natbib had the type appended with an underscore."
503 engine_type = "numerical"
504 i = find_token(document.header, "\\cite_engine_type" , 0)
506 document.warning("No \\cite_engine_type line. Assuming numerical.")
508 engine_type = get_value(document.header, "\\cite_engine_type", i)
509 del document.header[i]
511 # We are looking for the natbib citation engine
512 i = find_token(document.header, "\\cite_engine natbib", 0)
515 document.header[i] = "\\cite_engine natbib_" + engine_type
518 def convert_cite_engine_type_default(document):
519 "Convert \\cite_engine_type to default for the basic citation engine."
520 i = find_token(document.header, "\\cite_engine basic", 0)
523 i = find_token(document.header, "\\cite_engine_type" , 0)
526 document.header[i] = "\\cite_engine_type default"
529 def revert_cite_engine_type_default(document):
530 """Revert \\cite_engine_type default.
532 Revert to numerical for the basic cite engine, otherwise to authoryear."""
533 engine_type = "authoryear"
534 i = find_token(document.header, "\\cite_engine_type default" , 0)
537 j = find_token(document.header, "\\cite_engine basic", 0)
539 engine_type = "numerical"
540 document.header[i] = "\\cite_engine_type " + engine_type
543 # this is the same, as revert_use_cancel() except for the default
544 def revert_cancel(document):
545 "add cancel to the preamble if necessary"
546 commands = ["cancelto", "cancel", "bcancel", "xcancel"]
547 revert_use_package(document, "cancel", commands, False)
550 def revert_verbatim(document):
551 " Revert verbatim einvironments completely to TeX-code. "
554 subst_end = ['\end_layout', '', '\\begin_layout Plain Layout',
556 '\\begin_layout Plain Layout', '', '',
559 '\\end_layout', '', '\\end_inset',
560 '', '', '\\end_layout']
561 subst_begin = ['\\begin_layout Standard', '\\noindent',
562 '\\begin_inset ERT', 'status collapsed', '',
563 '\\begin_layout Plain Layout', '', '', '\\backslash',
565 '\\end_layout', '', '\\begin_layout Plain Layout', '']
567 i = find_token(document.body, "\\begin_layout Verbatim", i)
570 j = find_end_of_layout(document.body, i)
572 document.warning("Malformed LyX document: Can't find end of Verbatim layout")
575 # delete all line breaks insets (there are no other insets)
578 n = find_token(document.body, "\\begin_inset Newline newline", l)
580 n = find_token(document.body, "\\begin_inset Newline linebreak", l)
583 m = find_end_of_inset(document.body, n)
584 del(document.body[m:m+1])
585 document.body[n:n+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
588 # consecutive verbatim environments need to be connected
589 k = find_token(document.body, "\\begin_layout Verbatim", j)
590 if k == j + 2 and consecutive == False:
592 document.body[j:j+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
593 document.body[i:i+1] = subst_begin
595 if k == j + 2 and consecutive == True:
596 document.body[j:j+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
597 del(document.body[i:i+1])
599 if k != j + 2 and consecutive == True:
600 document.body[j:j+1] = subst_end
601 # the next paragraph must not be indented
602 document.body[j+19:j+19] = ['\\noindent']
603 del(document.body[i:i+1])
607 document.body[j:j+1] = subst_end
608 # the next paragraph must not be indented
609 document.body[j+19:j+19] = ['\\noindent']
610 document.body[i:i+1] = subst_begin
613 def revert_tipa(document):
614 " Revert native TIPA insets to mathed or ERT. "
617 i = find_token(document.body, "\\begin_inset IPA", i)
620 j = find_end_of_inset(document.body, i)
622 document.warning("Malformed LyX document: Can't find end of IPA inset")
626 n = find_token(document.body, "\\begin_layout", i, j)
628 document.warning("Malformed LyX document: IPA inset has no embedded layout")
631 m = find_end_of_layout(document.body, n)
633 document.warning("Malformed LyX document: Can't find end of embedded layout")
636 content = document.body[n+1:m]
637 p = find_token(document.body, "\\begin_layout", m, j)
638 if p != -1 or len(content) > 1:
640 content = document.body[i+1:j]
642 # IPA insets with multiple pars need to be wrapped by \begin{IPA}...\end{IPA}
643 document.body[i:j+1] = ['\\end_layout', '', '\\begin_layout Standard'] + put_cmd_in_ert("\\begin{IPA}") + ['\\end_layout'] + content + ['\\begin_layout Standard'] + put_cmd_in_ert("\\end{IPA}")
644 add_to_preamble(document, ["\\usepackage{tipa,tipx}"])
646 # single-par IPA insets can be reverted to mathed
647 document.body[i:j+1] = ["\\begin_inset Formula $\\text{\\textipa{" + content[0] + "}}$", "\\end_inset"]
651 def revert_cell_rotation(document):
652 "Revert cell rotations to TeX-code"
654 load_rotating = False
658 # first, let's find out if we need to do anything
659 i = find_token(document.body, '<cell ', i)
662 j = document.body[i].find('rotate="')
664 k = document.body[i].find('"', j + 8)
665 value = document.body[i][j + 8 : k]
667 rgx = re.compile(r' rotate="[^"]+?"')
668 # remove rotate option
669 document.body[i] = rgx.sub('', document.body[i])
671 rgx = re.compile(r' rotate="[^"]+?"')
672 document.body[i] = rgx.sub('rotate="true"', document.body[i])
674 rgx = re.compile(r' rotate="[^"]+?"')
676 # remove rotate option
677 document.body[i] = rgx.sub('', document.body[i])
679 document.body[i + 5 : i + 5] = \
680 put_cmd_in_ert("\\end{turn}")
681 document.body[i + 4 : i + 4] = \
682 put_cmd_in_ert("\\begin{turn}{" + value + "}")
688 add_to_preamble(document, ["\\@ifundefined{turnbox}{\usepackage{rotating}}{}"])
691 def convert_cell_rotation(document):
692 'Convert cell rotation statements from "true" to "90"'
696 # first, let's find out if we need to do anything
697 i = find_token(document.body, '<cell ', i)
700 j = document.body[i].find('rotate="true"')
702 rgx = re.compile(r'rotate="[^"]+?"')
703 # convert "true" to "90"
704 document.body[i] = rgx.sub('rotate="90"', document.body[i])
709 def revert_table_rotation(document):
710 "Revert table rotations to TeX-code"
712 load_rotating = False
716 # first, let's find out if we need to do anything
717 i = find_token(document.body, '<features ', i)
720 j = document.body[i].find('rotate="')
722 end_table = find_token(document.body, '</lyxtabular>', j)
723 k = document.body[i].find('"', j + 8)
724 value = document.body[i][j + 8 : k]
726 rgx = re.compile(r' rotate="[^"]+?"')
727 # remove rotate option
728 document.body[i] = rgx.sub('', document.body[i])
730 rgx = re.compile(r'rotate="[^"]+?"')
731 document.body[i] = rgx.sub('rotate="true"', document.body[i])
733 rgx = re.compile(r' rotate="[^"]+?"')
735 # remove rotate option
736 document.body[i] = rgx.sub('', document.body[i])
738 document.body[end_table + 3 : end_table + 3] = \
739 put_cmd_in_ert("\\end{turn}")
740 document.body[i - 2 : i - 2] = \
741 put_cmd_in_ert("\\begin{turn}{" + value + "}")
747 add_to_preamble(document, ["\\@ifundefined{turnbox}{\usepackage{rotating}}{}"])
750 def convert_table_rotation(document):
751 'Convert table rotation statements from "true" to "90"'
755 # first, let's find out if we need to do anything
756 i = find_token(document.body, '<features ', i)
759 j = document.body[i].find('rotate="true"')
761 rgx = re.compile(r'rotate="[^"]+?"')
762 # convert "true" to "90"
763 document.body[i] = rgx.sub('rotate="90"', document.body[i])
768 def convert_listoflistings(document):
769 'Convert ERT \lstlistoflistings to TOC lstlistoflistings inset'
770 # We can support roundtrip because the command is so simple
773 i = find_token(document.body, "\\begin_inset ERT", i)
776 j = find_end_of_inset(document.body, i)
778 document.warning("Malformed LyX document: Can't find end of ERT inset")
781 ert = get_ert(document.body, i)
782 if ert == "\\lstlistoflistings{}":
783 document.body[i:j] = ["\\begin_inset CommandInset toc", "LatexCommand lstlistoflistings", ""]
789 def revert_listoflistings(document):
790 'Convert TOC lstlistoflistings inset to ERT lstlistoflistings'
793 i = find_token(document.body, "\\begin_inset CommandInset toc", i)
796 if document.body[i+1] == "LatexCommand lstlistoflistings":
797 j = find_end_of_inset(document.body, i)
799 document.warning("Malformed LyX document: Can't find end of TOC inset")
802 subst = put_cmd_in_ert("\\lstlistoflistings{}")
803 document.body[i:j+1] = subst
804 add_to_preamble(document, ["\\usepackage{listings}"])
808 def convert_use_amssymb(document):
809 "insert use_package amssymb"
810 regexp = re.compile(r'(\\use_package\s+amsmath)')
811 i = find_re(document.header, regexp, 0)
813 document.warning("Malformed LyX document: Can't find \\use_package amsmath.")
815 value = get_value(document.header, "\\use_package" , i).split()[1]
818 useamsmath = int(value)
820 document.warning("Invalid \\use_package amsmath: " + value + ". Assuming auto.")
822 j = find_token(document.preamble, "\\usepackage{amssymb}", 0)
824 document.header.insert(i + 1, "\\use_package amssymb %d" % useamsmath)
826 document.header.insert(i + 1, "\\use_package amssymb 2")
827 del document.preamble[j]
830 def revert_use_amssymb(document):
831 "remove use_package amssymb"
832 regexp1 = re.compile(r'(\\use_package\s+amsmath)')
833 regexp2 = re.compile(r'(\\use_package\s+amssymb)')
834 i = find_re(document.header, regexp1, 0)
835 j = find_re(document.header, regexp2, 0)
836 value1 = "1" # default is auto
837 value2 = "1" # default is auto
839 value1 = get_value(document.header, "\\use_package" , i).split()[1]
841 value2 = get_value(document.header, "\\use_package" , j).split()[1]
842 del document.header[j]
843 if value1 != value2 and value2 == "2": # on
844 add_to_preamble(document, ["\\usepackage{amssymb}"])
847 def convert_use_cancel(document):
848 "insert use_package cancel"
849 convert_use_package(document, "cancel")
852 def revert_use_cancel(document):
853 "remove use_package cancel"
854 commands = ["cancel", "bcancel", "xcancel", "cancelto"]
855 revert_use_package(document, "cancel", commands, True)
858 def revert_ancientgreek(document):
859 "Set the document language for ancientgreek to greek"
861 if document.language == "ancientgreek":
862 document.language = "greek"
863 i = find_token(document.header, "\\language", 0)
865 document.header[i] = "\\language greek"
868 j = find_token(document.body, "\\lang ancientgreek", j)
872 document.body[j] = document.body[j].replace("\\lang ancientgreek", "\\lang greek")
876 def revert_languages(document):
877 "Set the document language for new supported languages to English"
880 "coptic", "divehi", "hindi", "kurmanji", "lao", "marathi", "occitan", "sanskrit",
881 "syriac", "tamil", "telugu", "urdu"
883 for n in range(len(languages)):
884 if document.language == languages[n]:
885 document.language = "english"
886 i = find_token(document.header, "\\language", 0)
888 document.header[i] = "\\language english"
890 while j < len(document.body):
891 j = find_token(document.body, "\\lang " + languages[n], j)
893 document.body[j] = document.body[j].replace("\\lang " + languages[n], "\\lang english")
896 j = len(document.body)
899 def convert_armenian(document):
900 "Use polyglossia and thus non-TeX fonts for Armenian"
902 if document.language == "armenian":
903 i = find_token(document.header, "\\use_non_tex_fonts", 0)
905 document.header[i] = "\\use_non_tex_fonts true"
908 def revert_armenian(document):
909 "Use ArmTeX and thus TeX fonts for Armenian"
911 if document.language == "armenian":
912 i = find_token(document.header, "\\use_non_tex_fonts", 0)
914 document.header[i] = "\\use_non_tex_fonts false"
917 def revert_libertine(document):
918 " Revert native libertine font definition to LaTeX "
920 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
921 i = find_token(document.header, "\\font_roman libertine", 0)
924 j = find_token(document.header, "\\font_osf true", 0)
927 preamble = "\\usepackage"
929 document.header[j] = "\\font_osf false"
932 preamble += "[lining]"
933 preamble += "{libertine-type1}"
934 add_to_preamble(document, [preamble])
935 document.header[i] = "\\font_roman default"
938 def revert_txtt(document):
939 " Revert native txtt font definition to LaTeX "
941 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
942 i = find_token(document.header, "\\font_typewriter txtt", 0)
944 preamble = "\\renewcommand{\\ttdefault}{txtt}"
945 add_to_preamble(document, [preamble])
946 document.header[i] = "\\font_typewriter default"
949 def revert_mathdesign(document):
950 " Revert native mathdesign font definition to LaTeX "
952 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
958 i = find_token(document.header, "\\font_roman", 0)
961 val = get_value(document.header, "\\font_roman", i)
962 if val in mathdesign_dict.keys():
963 preamble = "\\usepackage[%s" % mathdesign_dict[val]
965 j = find_token(document.header, "\\font_osf true", 0)
968 document.header[j] = "\\font_osf false"
969 l = find_token(document.header, "\\font_sc true", 0)
972 document.header[l] = "\\font_sc false"
974 preamble += ",expert"
975 preamble += "]{mathdesign}"
976 add_to_preamble(document, [preamble])
977 document.header[i] = "\\font_roman default"
980 def revert_texgyre(document):
981 " Revert native TeXGyre font definition to LaTeX "
983 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
984 texgyre_fonts = ["tgadventor", "tgbonum", "tgchorus", "tgcursor", \
985 "tgheros", "tgpagella", "tgschola", "tgtermes"]
986 i = find_token(document.header, "\\font_roman", 0)
988 val = get_value(document.header, "\\font_roman", i)
989 if val in texgyre_fonts:
990 preamble = "\\usepackage{%s}" % val
991 add_to_preamble(document, [preamble])
992 document.header[i] = "\\font_roman default"
993 i = find_token(document.header, "\\font_sans", 0)
995 val = get_value(document.header, "\\font_sans", i)
996 if val in texgyre_fonts:
997 preamble = "\\usepackage{%s}" % val
998 add_to_preamble(document, [preamble])
999 document.header[i] = "\\font_sans default"
1000 i = find_token(document.header, "\\font_typewriter", 0)
1002 val = get_value(document.header, "\\font_typewriter", i)
1003 if val in texgyre_fonts:
1004 preamble = "\\usepackage{%s}" % val
1005 add_to_preamble(document, [preamble])
1006 document.header[i] = "\\font_typewriter default"
1009 def revert_ipadeco(document):
1010 " Revert IPA decorations to ERT "
1013 i = find_token(document.body, "\\begin_inset IPADeco", i)
1016 end = find_end_of_inset(document.body, i)
1018 document.warning("Can't find end of inset at line " + str(i))
1021 line = document.body[i]
1022 rx = re.compile(r'\\begin_inset IPADeco (.*)$')
1024 decotype = m.group(1)
1025 if decotype != "toptiebar" and decotype != "bottomtiebar":
1026 document.warning("Invalid IPADeco type: " + decotype)
1029 blay = find_token(document.body, "\\begin_layout Plain Layout", i, end)
1031 document.warning("Can't find layout for inset at line " + str(i))
1034 bend = find_end_of_layout(document.body, blay)
1036 document.warning("Malformed LyX document: Could not find end of IPADeco inset's layout.")
1039 substi = ["\\begin_inset ERT", "status collapsed", "",
1040 "\\begin_layout Plain Layout", "", "", "\\backslash",
1041 decotype + "{", "\\end_layout", "", "\\end_inset"]
1042 substj = ["\\size default", "", "\\begin_inset ERT", "status collapsed", "",
1043 "\\begin_layout Plain Layout", "", "}", "\\end_layout", "", "\\end_inset"]
1044 # do the later one first so as not to mess up the numbering
1045 document.body[bend:end + 1] = substj
1046 document.body[i:blay + 1] = substi
1047 i = end + len(substi) + len(substj) - (end - bend) - (blay - i) - 2
1048 add_to_preamble(document, "\\usepackage{tipa}")
1051 def revert_ipachar(document):
1052 ' Revert \\IPAChar to ERT '
1055 while i < len(document.body):
1056 m = re.match(r'(.*)\\IPAChar \\(\w+\{\w+\})(.*)', document.body[i])
1060 ipachar = m.group(2)
1063 '\\begin_inset ERT',
1064 'status collapsed', '',
1065 '\\begin_layout Standard',
1066 '', '', '\\backslash',
1071 document.body[i: i+1] = subst
1076 add_to_preamble(document, "\\usepackage{tone}")
1079 def revert_minionpro(document):
1080 " Revert native MinionPro font definition to LaTeX "
1082 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1083 i = find_token(document.header, "\\font_roman minionpro", 0)
1086 j = find_token(document.header, "\\font_osf true", 0)
1089 preamble = "\\usepackage"
1091 document.header[j] = "\\font_osf false"
1094 preamble += "{MinionPro}"
1095 add_to_preamble(document, [preamble])
1096 document.header[i] = "\\font_roman default"
1099 def revert_mathfonts(document):
1100 " Revert native math font definitions to LaTeX "
1102 i = find_token(document.header, "\\font_math", 0)
1105 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1106 val = get_value(document.header, "\\font_math", i)
1107 if val == "eulervm":
1108 add_to_preamble(document, "\\usepackage{eulervm}")
1109 elif val == "default":
1111 "lmodern": "\\renewcommand{\\rmdefault}{lmr}",
1112 "minionpro": "\\usepackage[onlytext,lf]{MinionPro}",
1113 "minionpro-osf": "\\usepackage[onlytext]{MinionPro}",
1114 "palatino": "\\renewcommand{\\rmdefault}{ppl}",
1115 "palatino-osf": "\\renewcommand{\\rmdefault}{pplj}",
1116 "times": "\\renewcommand{\\rmdefault}{ptm}",
1117 "utopia": "\\renewcommand{\\rmdefault}{futs}",
1118 "utopia-osf": "\\renewcommand{\\rmdefault}{futj}",
1120 j = find_token(document.header, "\\font_roman", 0)
1122 rm = get_value(document.header, "\\font_roman", j)
1123 k = find_token(document.header, "\\font_osf true", 0)
1126 if rm in mathfont_dict.keys():
1127 add_to_preamble(document, mathfont_dict[rm])
1128 document.header[j] = "\\font_roman default"
1130 document.header[k] = "\\font_osf false"
1131 del document.header[i]
1134 def revert_mdnomath(document):
1135 " Revert mathdesign and fourier without math "
1137 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1139 "md-charter": "mdbch",
1140 "md-utopia": "mdput",
1141 "md-garamond": "mdugm"
1143 i = find_token(document.header, "\\font_roman", 0)
1146 val = get_value(document.header, "\\font_roman", i)
1147 if val in mathdesign_dict.keys():
1148 j = find_token(document.header, "\\font_math", 0)
1150 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1151 mval = get_value(document.header, "\\font_math", j)
1152 if mval == "default":
1153 document.header[i] = "\\font_roman default"
1154 add_to_preamble(document, "\\renewcommand{\\rmdefault}{%s}" % mathdesign_dict[val])
1156 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1159 def convert_mdnomath(document):
1160 " Change mathdesign font name "
1162 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1164 "mdbch": "md-charter",
1165 "mdput": "md-utopia",
1166 "mdugm": "md-garamond"
1168 i = find_token(document.header, "\\font_roman", 0)
1171 val = get_value(document.header, "\\font_roman", i)
1172 if val in mathdesign_dict.keys():
1173 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1176 def revert_newtxmath(document):
1177 " Revert native newtxmath definitions to LaTeX "
1179 i = find_token(document.header, "\\font_math", 0)
1182 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1183 val = get_value(document.header, "\\font_math", i)
1185 "libertine-ntxm": "\\usepackage[libertine]{newtxmath}",
1186 "minion-ntxm": "\\usepackage[minion]{newtxmath}",
1187 "newtxmath": "\\usepackage{newtxmath}",
1189 if val in mathfont_dict.keys():
1190 add_to_preamble(document, mathfont_dict[val])
1191 document.header[i] = "\\font_math auto"
1194 def revert_biolinum(document):
1195 " Revert native biolinum font definition to LaTeX "
1197 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1198 i = find_token(document.header, "\\font_sans biolinum", 0)
1201 j = find_token(document.header, "\\font_osf true", 0)
1204 preamble = "\\usepackage"
1207 preamble += "{biolinum-type1}"
1208 add_to_preamble(document, [preamble])
1209 document.header[i] = "\\font_sans default"
1212 def revert_uop(document):
1213 " Revert native URW Classico (Optima) font definition to LaTeX "
1215 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1216 i = find_token(document.header, "\\font_sans uop", 0)
1218 preamble = "\\renewcommand{\\sfdefault}{uop}"
1219 add_to_preamble(document, [preamble])
1220 document.header[i] = "\\font_sans default"
1223 def convert_latexargs(document):
1224 " Convert InsetArgument to new syntax "
1226 if find_token(document.body, "\\begin_inset Argument", 0) == -1:
1230 # A list of layouts (document classes) with only optional or no arguments.
1231 # These can be safely converted to the new syntax
1232 # (I took the liberty to add some of my personal layouts/modules here; JSP)
1233 safe_layouts = ["aa", "aapaper", "aastex", "achemso", "acmsiggraph", "AEA",
1234 "agu-dtd", "agums", "agutex", "amsart", "amsbook", "apa",
1235 "arab-article", "armenian-article", "article-beamer", "article",
1236 "beamer", "book", "broadway", "chess", "cl2emult", "ctex-article",
1237 "ctex-book", "ctex-report", "dinbrief", "docbook-book", "docbook-chapter",
1238 "docbook", "docbook-section", "doublecol-new", "dtk", "ectaart", "egs",
1239 "elsarticle", "elsart", "entcs", "europecv", "extarticle", "extbook",
1240 "extletter", "extreport", "foils", "frletter", "g-brief2", "g-brief",
1241 "heb-article", "heb-letter", "hollywood", "IEEEtran", "ijmpc", "ijmpd",
1242 "iopart", "isprs", "jarticle", "jasatex", "jbook", "jgrga", "jreport",
1243 "jsarticle", "jsbeamer", "jsbook", "jss", "kluwer", "latex8", "letter", "lettre",
1244 "literate-article", "literate-book", "literate-report", "llncs", "ltugboat",
1245 "memoir", "moderncv", "mwart", "mwbk", "mwrep", "paper", "powerdot",
1246 "recipebook", "report", "revtex4", "revtex", "scrartcl", "scrarticle-beamer",
1247 "scrbook", "scrlettr", "scrlttr2", "scrreprt", "seminar", "siamltex",
1248 "sigplanconf", "simplecv", "singlecol", "singlecol-new", "slides", "spie",
1249 "svglobal3", "svglobal", "svjog", "svmono", "svmult", "svprobth", "tarticle",
1250 "tbook", "treport", "tufte-book", "tufte-handout"]
1251 # A list of "safe" modules, same as above
1252 safe_modules = ["biblatex", "beameraddons", "beamersession", "braille", "customHeadersFooters",
1253 "endnotes", "enumitem", "eqs-within-sections", "figs-within-sections", "fix-cm",
1254 "fixltx2e", "foottoend", "hanging", "jscharstyles", "knitr", "lilypond",
1255 "linguistics", "linguisticx", "logicalmkup", "minimalistic", "nomindex", "noweb",
1256 "pdfcomment", "sweave", "tabs-within-sections", "theorems-ams-bytype",
1257 "theorems-ams-extended-bytype", "theorems-ams-extended", "theorems-ams", "theorems-bytype",
1258 "theorems-chap-bytype", "theorems-chap", "theorems-named", "theorems-sec-bytype",
1259 "theorems-sec", "theorems-starred", "theorems-std", "todonotes"]
1260 # Modules we need to take care of
1261 caveat_modules = ["initials"]
1262 # information about the relevant styles in caveat_modules (number of opt and req args)
1263 # use this if we get more caveat_modules. For now, use hard coding (see below).
1264 # initials = [{'Layout' : 'Initial', 'opt' : 1, 'req' : 1}]
1266 # Is this a known safe layout?
1267 safe_layout = document.textclass in safe_layouts
1269 document.warning("Lyx2lyx knows nothing about textclass '%s'. "
1270 "Please check if short title insets have been converted correctly."
1271 % document.textclass)
1272 # Do we use unsafe or unknown modules
1273 mods = document.get_module_list()
1274 unknown_modules = False
1275 used_caveat_modules = list()
1277 if mod in safe_modules:
1279 if mod in caveat_modules:
1280 used_caveat_modules.append(mod)
1282 unknown_modules = True
1283 document.warning("Lyx2lyx knows nothing about module '%s'. "
1284 "Please check if short title insets have been converted correctly."
1289 i = find_token(document.body, "\\begin_inset Argument", i)
1293 if not safe_layout or unknown_modules:
1294 # We cannot do more here since we have no access to this layout.
1295 # InsetArgument itself will do the real work
1296 # (see InsetArgument::updateBuffer())
1297 document.body[i] = "\\begin_inset Argument 999"
1301 # Find containing paragraph layout
1302 parent = get_containing_layout(document.body, i)
1304 document.warning("Malformed LyX document: Can't find parent paragraph layout")
1311 if len(used_caveat_modules) > 0:
1312 # We know for now that this must be the initials module with the Initial layout
1313 # If we get more such modules, we need some automating.
1314 if parent[0] == "Initial":
1315 # Layout has 1 opt and 1 req arg.
1316 # Count the actual arguments
1318 for p in range(parbeg, parend):
1319 if document.body[p] == "\\begin_inset Argument":
1324 # Collect all arguments in this paragraph
1326 for p in range(parbeg, parend):
1327 if document.body[p] == "\\begin_inset Argument":
1329 if allowed_opts != -1:
1330 # We have less arguments than opt + required.
1331 # required must take precedence.
1332 if argnr > allowed_opts and argnr < first_req:
1334 document.body[p] = "\\begin_inset Argument %d" % argnr
1338 def revert_latexargs(document):
1339 " Revert InsetArgument to old syntax "
1342 rx = re.compile(r'^\\begin_inset Argument (\d+)$')
1345 # Search for Argument insets
1346 i = find_token(document.body, "\\begin_inset Argument", i)
1349 m = rx.match(document.body[i])
1351 # No ID: inset already reverted
1354 # Find containing paragraph layout
1355 parent = get_containing_layout(document.body, i)
1357 document.warning("Malformed LyX document: Can't find parent paragraph layout")
1362 realparbeg = parent[3]
1363 # Collect all arguments in this paragraph
1365 for p in range(parbeg, parend):
1366 m = rx.match(document.body[p])
1368 val = int(m.group(1))
1369 j = find_end_of_inset(document.body, p)
1370 # Revert to old syntax
1371 document.body[p] = "\\begin_inset Argument"
1373 document.warning("Malformed LyX document: Can't find end of Argument inset")
1376 args[val] = document.body[p : j + 1]
1378 realparend = realparend - len(document.body[p : j + 1])
1379 # Remove arg inset at this position
1380 del document.body[p : j + 1]
1383 # Now sort the arg insets
1385 for f in sorted(args):
1388 # Insert the sorted arg insets at paragraph begin
1389 document.body[realparbeg : realparbeg] = subst
1391 i = realparbeg + 1 + len(subst)
1394 def revert_Argument_to_TeX_brace(document, line, endline, n, nmax, environment, opt):
1396 Reverts an InsetArgument to TeX-code
1398 revert_Argument_to_TeX_brace(document, LineOfBegin, LineOfEnd, StartArgument, EndArgument, isEnvironment, isOpt)
1399 LineOfBegin is the line of the \begin_layout or \begin_inset statement
1400 LineOfEnd is the line of the \end_layout or \end_inset statement, if "0" is given, the end of the file is used instead
1401 StartArgument is the number of the first argument that needs to be converted
1402 EndArgument is the number of the last argument that needs to be converted or the last defined one
1403 isEnvironment must be true, if the layout is for a LaTeX environment
1404 isOpt must be true, if the argument is an optional one
1408 while lineArg != -1 and n < nmax + 1:
1409 lineArg = find_token(document.body, "\\begin_inset Argument " + str(n), line)
1410 if lineArg > endline and endline != 0:
1413 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", lineArg)
1414 # we have to assure that no other inset is in the Argument
1415 beginInset = find_token(document.body, "\\begin_inset", beginPlain)
1416 endInset = find_token(document.body, "\\end_inset", beginPlain)
1419 while beginInset < endInset and beginInset != -1:
1420 beginInset = find_token(document.body, "\\begin_inset", k)
1421 endInset = find_token(document.body, "\\end_inset", l)
1424 if environment == False:
1426 document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("}{")
1427 del(document.body[lineArg : beginPlain + 1])
1430 document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("]")
1431 document.body[lineArg : beginPlain + 1] = put_cmd_in_ert("[")
1434 document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("}")
1435 document.body[lineArg : beginPlain + 1] = put_cmd_in_ert("{")
1441 def convert_TeX_brace_to_Argument(document, line, n, nmax, inset, environment):
1443 Converts TeX code for mandatory arguments to an InsetArgument
1444 The conversion of TeX code for optional arguments must be done with another routine
1445 !!! Be careful if the braces are different in your case as expected here:
1446 - "}{" separates mandatory arguments of commands
1447 - "}" + "{" separates mandatory arguments of commands
1448 - "}" + " " + "{" separates mandatory arguments of commands
1449 - { and } surround a mandatory argument of an environment
1451 convert_TeX_brace_to_Argument(document, LineOfBeginLayout/Inset, StartArgument, EndArgument, isInset, isEnvironment)
1452 LineOfBeginLayout/Inset is the line of the \begin_layout or \begin_inset statement
1453 StartArgument is the number of the first ERT that needs to be converted
1454 EndArgument is the number of the last ERT that needs to be converted
1455 isInset must be true, if braces inside an InsetLayout needs to be converted
1456 isEnvironment must be true, if the layout is for a LaTeX environment
1458 Todo: this routine can currently handle only one mandatory argument of environments
1463 while lineERT != -1 and n < nmax + 1:
1464 lineERT = find_token(document.body, "\\begin_inset ERT", lineERT)
1465 if environment == False and lineERT != -1:
1466 bracePair = find_token(document.body, "}{", lineERT)
1467 # assure that the "}{" is in this ERT
1468 if bracePair == lineERT + 5:
1469 end = find_token(document.body, "\\end_inset", bracePair)
1470 document.body[lineERT : end + 1] = ["\\end_layout", "", "\\end_inset"]
1472 # in the case that n > 1 we have optional arguments before
1473 # therefore detect them if any
1475 # first check if there is an argument
1476 lineArg = find_token(document.body, "\\begin_inset Argument", line)
1477 if lineArg < lineERT and lineArg != -1:
1478 # we have an argument, so now search backwards for its end
1479 # we must now assure that we don't find other insets like e.g. a newline
1480 endInsetArg = lineERT
1481 endLayoutArg = endInsetArg
1482 while endInsetArg != endLayoutArg + 2 and endInsetArg != -1:
1483 endInsetArg = endInsetArg - 1
1484 endLayoutArg = endInsetArg
1485 endInsetArg = find_token_backwards(document.body, "\\end_inset", endInsetArg)
1486 endLayoutArg = find_token_backwards(document.body, "\\end_layout", endLayoutArg)
1487 line = endInsetArg + 1
1489 document.body[line + 1 : line + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1491 document.body[line + 4 : line + 4] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1493 document.body[endn : endn] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1497 # now check the case that we have "}" + "{" in two ERTs
1499 endBrace = find_token(document.body, "}", lineERT)
1500 if endBrace == lineERT + 5:
1501 beginBrace = find_token(document.body, "{", endBrace)
1502 # assure that the ERTs are consecutive (11 or 12 depending if there is a space between the ERTs or not)
1503 if beginBrace == endBrace + 11 or beginBrace == endBrace + 12:
1504 end = find_token(document.body, "\\end_inset", beginBrace)
1505 document.body[lineERT : end + 1] = ["\\end_layout", "", "\\end_inset"]
1507 # in the case that n > 1 we have optional arguments before
1508 # therefore detect them if any
1510 # first check if there is an argument
1511 lineArg = find_token(document.body, "\\begin_inset Argument", line)
1512 if lineArg < lineERT and lineArg != -1:
1513 # we have an argument, so now search backwards for its end
1514 # we must now assure that we don't find other insets like e.g. a newline
1515 endInsetArg = lineERT
1516 endLayoutArg = endInsetArg
1517 while endInsetArg != endLayoutArg + 2 and endInsetArg != -1:
1518 endInsetArg = endInsetArg - 1
1519 endLayoutArg = endInsetArg
1520 endInsetArg = find_token_backwards(document.body, "\\end_inset", endInsetArg)
1521 endLayoutArg = find_token_backwards(document.body, "\\end_layout", endLayoutArg)
1522 line = endInsetArg + 1
1524 document.body[line + 1 : line + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1526 document.body[line + 4 : line + 4] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1528 document.body[endn : endn] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1531 # set the line where the next argument will be inserted
1532 if beginBrace == endBrace + 11:
1537 lineERT = lineERT + 1
1538 if environment == True and lineERT != -1:
1539 opening = find_token(document.body, "{", lineERT)
1540 if opening == lineERT + 5: # assure that the "{" is in this ERT
1541 end = find_token(document.body, "\\end_inset", opening)
1542 document.body[lineERT : end + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
1544 lineERT2 = find_token(document.body, "\\begin_inset ERT", lineERT)
1545 closing = find_token(document.body, "}", lineERT2)
1546 if closing == lineERT2 + 5: # assure that the "}" is in this ERT
1547 end2 = find_token(document.body, "\\end_inset", closing)
1548 document.body[lineERT2 : end2 + 1] = ["\\end_layout", "", "\\end_inset"]
1550 lineERT = lineERT + 1
1553 def revert_IEEEtran(document):
1555 Reverts InsetArgument of
1558 Biography without photo
1561 if document.textclass == "IEEEtran":
1568 i = find_token(document.body, "\\begin_layout Page headings", i)
1570 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1573 i2 = find_token(document.body, "\\begin_inset Flex Paragraph Start", i2)
1575 revert_Argument_to_TeX_brace(document, i2, 0, 1, 1, False, False)
1578 j = find_token(document.body, "\\begin_layout Biography without photo", j)
1580 revert_Argument_to_TeX_brace(document, j, 0, 1, 1, True, False)
1583 k = find_token(document.body, "\\begin_layout Biography", k)
1584 kA = find_token(document.body, "\\begin_layout Biography without photo", k)
1585 if k == kA and k != -1:
1589 # start with the second argument, therefore 2
1590 revert_Argument_to_TeX_brace(document, k, 0, 2, 2, True, False)
1592 if i == -1 and i2 == -1 and j == -1 and k == -1:
1596 def revert_IEEEtran_2(document):
1598 Reverts Flex Paragraph Start to TeX-code
1600 if document.textclass == "IEEEtran":
1604 begin = find_token(document.body, "\\begin_inset Flex Paragraph Start", begin)
1606 end1 = find_end_of_inset(document.body, begin)
1607 document.body[end1 - 2 : end1 + 1] = put_cmd_in_ert("}")
1608 document.body[begin : begin + 4] = put_cmd_in_ert("\\IEEEPARstart{")
1614 def convert_IEEEtran(document):
1619 Biography without photo
1622 if document.textclass == "IEEEtran":
1628 i = find_token(document.body, "\\begin_layout Page headings", i)
1630 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1633 j = find_token(document.body, "\\begin_layout Biography without photo", j)
1635 convert_TeX_brace_to_Argument(document, j, 1, 1, False, True)
1638 # assure that we don't handle Biography Biography without photo
1639 k = find_token(document.body, "\\begin_layout Biography", k)
1640 kA = find_token(document.body, "\\begin_layout Biography without photo", k - 1)
1641 if k == kA and k != -1:
1645 # the argument we want to convert is the second one
1646 convert_TeX_brace_to_Argument(document, k, 2, 2, False, True)
1648 if i == -1 and j == -1 and k == -1:
1652 def revert_AASTeX(document):
1653 " Reverts InsetArgument of Altaffilation to TeX-code "
1654 if document.textclass == "aastex":
1658 i = find_token(document.body, "\\begin_layout Altaffilation", i)
1660 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1666 def convert_AASTeX(document):
1667 " Converts ERT of Altaffilation to InsetArgument "
1668 if document.textclass == "aastex":
1672 i = find_token(document.body, "\\begin_layout Altaffilation", i)
1674 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1680 def revert_AGUTeX(document):
1681 " Reverts InsetArgument of Author affiliation to TeX-code "
1682 if document.textclass == "agutex":
1686 i = find_token(document.body, "\\begin_layout Author affiliation", i)
1688 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1694 def convert_AGUTeX(document):
1695 " Converts ERT of Author affiliation to InsetArgument "
1696 if document.textclass == "agutex":
1700 i = find_token(document.body, "\\begin_layout Author affiliation", i)
1702 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1708 def revert_IJMP(document):
1709 " Reverts InsetArgument of MarkBoth to TeX-code "
1710 if document.textclass == "ijmpc" or document.textclass == "ijmpd":
1714 i = find_token(document.body, "\\begin_layout MarkBoth", i)
1716 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1722 def convert_IJMP(document):
1723 " Converts ERT of MarkBoth to InsetArgument "
1724 if document.textclass == "ijmpc" or document.textclass == "ijmpd":
1728 i = find_token(document.body, "\\begin_layout MarkBoth", i)
1730 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1736 def revert_SIGPLAN(document):
1737 " Reverts InsetArguments of SIGPLAN to TeX-code "
1738 if document.textclass == "sigplanconf":
1743 i = find_token(document.body, "\\begin_layout Conference", i)
1745 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1748 j = find_token(document.body, "\\begin_layout Author", j)
1750 revert_Argument_to_TeX_brace(document, j, 0, 1, 2, False, False)
1752 if i == -1 and j == -1:
1756 def convert_SIGPLAN(document):
1757 " Converts ERT of SIGPLAN to InsetArgument "
1758 if document.textclass == "sigplanconf":
1763 i = find_token(document.body, "\\begin_layout Conference", i)
1765 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1768 j = find_token(document.body, "\\begin_layout Author", j)
1770 convert_TeX_brace_to_Argument(document, j, 1, 2, False, False)
1772 if i == -1 and j == -1:
1776 def revert_SIGGRAPH(document):
1777 " Reverts InsetArgument of Flex CRcat to TeX-code "
1778 if document.textclass == "acmsiggraph":
1782 i = find_token(document.body, "\\begin_inset Flex CRcat", i)
1784 revert_Argument_to_TeX_brace(document, i, 0, 1, 3, False, False)
1790 def convert_SIGGRAPH(document):
1791 " Converts ERT of Flex CRcat to InsetArgument "
1792 if document.textclass == "acmsiggraph":
1796 i = find_token(document.body, "\\begin_inset Flex CRcat", i)
1798 convert_TeX_brace_to_Argument(document, i, 1, 3, True, False)
1804 def revert_EuropeCV(document):
1805 " Reverts InsetArguments of europeCV to TeX-code "
1806 if document.textclass == "europecv":
1813 i = find_token(document.body, "\\begin_layout Item", i)
1815 revert_Argument_to_TeX_brace(document, i, 0, 2, 2, False, False)
1818 j = find_token(document.body, "\\begin_layout BulletedItem", j)
1820 revert_Argument_to_TeX_brace(document, j, 0, 2, 2, False, False)
1823 k = find_token(document.body, "\\begin_layout Language", k)
1825 revert_Argument_to_TeX_brace(document, k, 0, 2, 6, False, False)
1828 m = find_token(document.body, "\\begin_layout LastLanguage", m)
1830 revert_Argument_to_TeX_brace(document, m, 0, 2, 6, False, False)
1832 if i == -1 and j == -1 and k == -1 and m == -1:
1836 def convert_EuropeCV(document):
1837 " Converts ERT of europeCV to InsetArgument "
1838 if document.textclass == "europecv":
1845 i = find_token(document.body, "\\begin_layout Item", i)
1847 convert_TeX_brace_to_Argument(document, i, 2, 2, False, False)
1850 j = find_token(document.body, "\\begin_layout BulletedItem", j)
1852 convert_TeX_brace_to_Argument(document, j, 2, 2, False, False)
1855 k = find_token(document.body, "\\begin_layout Language", k)
1857 convert_TeX_brace_to_Argument(document, k, 2, 6, False, False)
1860 m = find_token(document.body, "\\begin_layout LastLanguage", m)
1862 convert_TeX_brace_to_Argument(document, m, 2, 6, False, False)
1864 if i == -1 and j == -1 and k == -1 and m == -1:
1868 def revert_ModernCV(document):
1869 " Reverts InsetArguments of modernCV to TeX-code "
1870 if document.textclass == "moderncv":
1877 j = find_token(document.body, "\\begin_layout Entry", j)
1879 revert_Argument_to_TeX_brace(document, j, 0, 1, 5, False, False)
1882 k = find_token(document.body, "\\begin_layout Item", k)
1884 revert_Argument_to_TeX_brace(document, k, 0, 1, 1, False, False)
1887 m = find_token(document.body, "\\begin_layout ItemWithComment", m)
1889 revert_Argument_to_TeX_brace(document, m, 0, 1, 2, False, False)
1890 document.body[m] = document.body[m].replace("\\begin_layout ItemWithComment", "\\begin_layout Language")
1893 o = find_token(document.body, "\\begin_layout DoubleItem", o)
1895 revert_Argument_to_TeX_brace(document, o, 0, 1, 3, False, False)
1896 document.body[o] = document.body[o].replace("\\begin_layout DoubleItem", "\\begin_layout Computer")
1898 if j == -1 and k == -1 and m == -1 and o == -1:
1902 def revert_ModernCV_2(document):
1903 " Reverts the Flex:Column inset of modernCV to TeX-code "
1904 if document.textclass == "moderncv":
1909 flex = find_token(document.body, "\\begin_inset Flex Column", flex)
1911 flexEnd = find_end_of_inset(document.body, flex)
1912 wasOpt = revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, False, True)
1913 revert_Argument_to_TeX_brace(document, flex, 0, 2, 2, False, False)
1914 flexEnd = find_end_of_inset(document.body, flex)
1916 document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\cvcolumn")
1918 document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\cvcolumn{")
1919 document.body[flexEnd + 4 : flexEnd + 7] = put_cmd_in_ert("}")
1925 def revert_ModernCV_3(document):
1926 " Reverts the Column style of modernCV to TeX-code "
1927 if document.textclass == "moderncv":
1928 # revert the layouts
1929 revert_ModernCV(document)
1931 # get the position of the end of the last column inset
1932 LastFlexEnd = revert_ModernCV_2(document)
1935 p = find_token(document.body, "\\begin_layout Columns", p)
1937 pEnd = find_end_of_layout(document.body, p)
1938 document.body[p] = document.body[p].replace("\\begin_layout Columns", "\\begin_layout Standard")
1939 if LastFlexEnd != -1:
1940 document.body[p + 1 : p + 1] = put_cmd_in_ert("\\begin{cvcolumns}")
1941 document.body[LastFlexEnd + 24 : LastFlexEnd + 24] = put_cmd_in_ert("\\end{cvcolumns}")
1947 def convert_ModernCV(document):
1948 " Converts ERT of modernCV to InsetArgument "
1949 if document.textclass == "moderncv":
1957 i = find_token(document.body, "\\begin_layout DoubleItem", i)
1959 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
1960 document.body[o] = document.body[o].replace("\\begin_layout DoubleItem", "\\begin_layout DoubleListItem")
1963 j = find_token(document.body, "\\begin_layout Entry", j)
1965 convert_TeX_brace_to_Argument(document, j, 1, 5, False, False)
1968 k = find_token(document.body, "\\begin_layout Item", k)
1970 convert_TeX_brace_to_Argument(document, k, 1, 1, False, False)
1973 m = find_token(document.body, "\\begin_layout Language", m)
1975 convert_TeX_brace_to_Argument(document, m, 1, 2, False, False)
1977 if i == -1 and j == -1 and k == -1 and m == -1:
1981 def revert_Initials(document):
1982 " Reverts InsetArgument of Initial to TeX-code "
1986 i = find_token(document.body, "\\begin_layout Initial", i)
1988 # first arg (optional) and second arg (first mandatory) are supported in LyX 2.0.x
1989 revert_Argument_to_TeX_brace(document, i, 0, 3, 3, False, False)
1995 def convert_Initials(document):
1996 " Converts ERT of Initial to InsetArgument "
2000 i = find_token(document.body, "\\begin_layout Initial", i)
2002 convert_TeX_brace_to_Argument(document, i, 3, 3, False, False)
2008 def revert_literate(document):
2009 " Revert Literate document to old format "
2010 if del_token(document.header, "noweb", 0):
2011 document.textclass = "literate-" + document.textclass
2014 i = find_token(document.body, "\\begin_layout Chunk", i)
2017 document.body[i] = "\\begin_layout Scrap"
2021 def convert_literate(document):
2022 " Convert Literate document to new format"
2023 i = find_token(document.header, "\\textclass", 0)
2024 if (i != -1) and "literate-" in document.header[i]:
2025 document.textclass = document.header[i].replace("\\textclass literate-", "")
2026 j = find_token(document.header, "\\begin_modules", 0)
2028 document.header.insert(j + 1, "noweb")
2030 document.header.insert(i + 1, "\\end_modules")
2031 document.header.insert(i + 1, "noweb")
2032 document.header.insert(i + 1, "\\begin_modules")
2035 i = find_token(document.body, "\\begin_layout Scrap", i)
2038 document.body[i] = "\\begin_layout Chunk"
2042 def revert_itemargs(document):
2043 " Reverts \\item arguments to TeX-code "
2046 i = find_token(document.body, "\\begin_inset Argument item:", i)
2049 j = find_end_of_inset(document.body, i)
2050 # Find containing paragraph layout
2051 parent = get_containing_layout(document.body, i)
2053 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2057 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2058 endPlain = find_end_of_layout(document.body, beginPlain)
2059 content = document.body[beginPlain + 1 : endPlain]
2060 del document.body[i:j+1]
2061 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2062 document.body[parbeg : parbeg] = subst
2066 def revert_garamondx_newtxmath(document):
2067 " Revert native garamond newtxmath definition to LaTeX "
2069 i = find_token(document.header, "\\font_math", 0)
2072 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
2073 val = get_value(document.header, "\\font_math", i)
2074 if val == "garamondx-ntxm":
2075 add_to_preamble(document, "\\usepackage[garamondx]{newtxmath}")
2076 document.header[i] = "\\font_math auto"
2079 def revert_garamondx(document):
2080 " Revert native garamond font definition to LaTeX "
2082 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
2083 i = find_token(document.header, "\\font_roman garamondx", 0)
2086 j = find_token(document.header, "\\font_osf true", 0)
2089 preamble = "\\usepackage"
2091 preamble += "[osfI]"
2092 preamble += "{garamondx}"
2093 add_to_preamble(document, [preamble])
2094 document.header[i] = "\\font_roman default"
2097 def convert_beamerargs(document):
2098 " Converts beamer arguments to new layout "
2100 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2101 if document.textclass not in beamer_classes:
2104 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
2105 list_layouts = ["Itemize", "Enumerate", "Description"]
2106 rx = re.compile(r'^\\begin_inset Argument (\d+)$')
2110 i = find_token(document.body, "\\begin_inset Argument", i)
2113 # Find containing paragraph layout
2114 parent = get_containing_layout(document.body, i)
2116 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2121 layoutname = parent[0]
2122 for p in range(parbeg, parend):
2123 if layoutname in shifted_layouts:
2124 m = rx.match(document.body[p])
2126 argnr = int(m.group(1))
2128 document.body[p] = "\\begin_inset Argument %d" % argnr
2129 if layoutname == "AgainFrame":
2130 m = rx.match(document.body[p])
2132 document.body[p] = "\\begin_inset Argument 3"
2133 if document.body[p + 4] == "\\begin_inset ERT":
2134 if document.body[p + 9].startswith("<"):
2135 # This is an overlay specification
2137 document.body[p + 9] = document.body[p + 9][1:]
2138 if document.body[p + 9].endswith(">"):
2140 document.body[p + 9] = document.body[p + 9][:-1]
2142 document.body[p] = "\\begin_inset Argument 2"
2143 if layoutname in list_layouts:
2144 m = rx.match(document.body[p])
2146 if m.group(1) == "1":
2147 if document.body[p + 4] == "\\begin_inset ERT":
2148 if document.body[p + 9].startswith("<"):
2149 # This is an overlay specification
2151 document.body[p + 9] = document.body[p + 9][1:]
2152 if document.body[p + 9].endswith(">"):
2154 document.body[p + 9] = document.body[p + 9][:-1]
2155 elif layoutname != "Itemize":
2157 document.body[p] = "\\begin_inset Argument 2"
2161 def convert_againframe_args(document):
2162 " Converts beamer AgainFrame to new layout "
2164 # FIXME: This currently only works if the arguments are in one single ERT
2166 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2167 if document.textclass not in beamer_classes:
2172 i = find_token(document.body, "\\begin_layout AgainFrame", i)
2175 parent = get_containing_layout(document.body, i)
2177 document.warning("Wrong parent layout!")
2181 if document.body[parbeg] == "\\begin_inset ERT":
2182 ertcont = parbeg + 5
2183 if document.body[ertcont].startswith("[<"):
2184 # This is a default overlay specification
2186 document.body[ertcont] = document.body[ertcont][2:]
2187 if document.body[ertcont].endswith(">]"):
2189 document.body[ertcont] = document.body[ertcont][:-2]
2190 elif document.body[ertcont].endswith("]"):
2192 tok = document.body[ertcont].find('>][')
2194 subst = [document.body[ertcont][:tok],
2195 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2196 'status collapsed', '', '\\begin_layout Plain Layout',
2197 document.body[ertcont][tok + 3:-1]]
2198 document.body[ertcont : ertcont + 1] = subst
2199 # Convert to ArgInset
2200 document.body[parbeg] = "\\begin_inset Argument 2"
2203 elif document.body[ertcont].startswith("<"):
2204 # This is an overlay specification
2206 document.body[ertcont] = document.body[ertcont][1:]
2207 if document.body[ertcont].endswith(">"):
2209 document.body[ertcont] = document.body[ertcont][:-1]
2210 # Convert to ArgInset
2211 document.body[parbeg] = "\\begin_inset Argument 1"
2212 elif document.body[ertcont].endswith(">]"):
2214 tok = document.body[ertcont].find('>[<')
2216 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2217 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2218 'status collapsed', '', '\\begin_layout Plain Layout',
2219 document.body[ertcont][tok + 3:-2]]
2220 # Convert to ArgInset
2221 document.body[parbeg] = "\\begin_inset Argument 1"
2222 elif document.body[ertcont].endswith("]"):
2224 tok = document.body[ertcont].find('>[<')
2227 tokk = document.body[ertcont].find('>][')
2229 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2230 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2231 'status collapsed', '', '\\begin_layout Plain Layout',
2232 document.body[ertcont][tok + 3:tokk],
2233 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2234 'status collapsed', '', '\\begin_layout Plain Layout',
2235 document.body[ertcont][tokk + 3:-1]]
2237 tokk = document.body[ertcont].find('>[')
2239 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tokk],
2240 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2241 'status collapsed', '', '\\begin_layout Plain Layout',
2242 document.body[ertcont][tokk + 2:-1]]
2243 # Convert to ArgInset
2244 document.body[parbeg] = "\\begin_inset Argument 1"
2247 elif document.body[ertcont].startswith("["):
2248 # This is an ERT option
2250 document.body[ertcont] = document.body[ertcont][1:]
2251 if document.body[ertcont].endswith("]"):
2253 document.body[ertcont] = document.body[ertcont][:-1]
2254 # Convert to ArgInset
2255 document.body[parbeg] = "\\begin_inset Argument 3"
2261 def convert_corollary_args(document):
2262 " Converts beamer corrolary-style ERT arguments native InsetArgs "
2264 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2265 if document.textclass not in beamer_classes:
2268 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2269 for lay in corollary_layouts:
2272 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2275 parent = get_containing_layout(document.body, i)
2277 document.warning("Wrong parent layout!")
2281 if document.body[parbeg] == "\\begin_inset ERT":
2282 ertcont = parbeg + 5
2283 if document.body[ertcont].startswith("<"):
2284 # This is an overlay specification
2286 document.body[ertcont] = document.body[ertcont][1:]
2287 if document.body[ertcont].endswith(">"):
2289 document.body[ertcont] = document.body[ertcont][:-1]
2290 elif document.body[ertcont].endswith("]"):
2292 tok = document.body[ertcont].find('>[')
2294 subst = [document.body[ertcont][:tok],
2295 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2296 'status collapsed', '', '\\begin_layout Plain Layout',
2297 document.body[ertcont][tok + 2:-1]]
2298 document.body[ertcont : ertcont + 1] = subst
2299 # Convert to ArgInset
2300 document.body[parbeg] = "\\begin_inset Argument 1"
2303 elif document.body[ertcont].startswith("["):
2304 # This is an ERT option
2306 document.body[ertcont] = document.body[ertcont][1:]
2307 if document.body[ertcont].endswith("]"):
2309 document.body[ertcont] = document.body[ertcont][:-1]
2310 # Convert to ArgInset
2311 document.body[parbeg] = "\\begin_inset Argument 2"
2318 def convert_quote_args(document):
2319 " Converts beamer quote style ERT args to native InsetArgs "
2321 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2322 if document.textclass not in beamer_classes:
2325 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2326 for lay in quote_layouts:
2329 i = find_token(document.body, "\\begin_layout " + lay, i)
2332 parent = get_containing_layout(document.body, i)
2334 document.warning("Wrong parent layout!")
2338 if document.body[parbeg] == "\\begin_inset ERT":
2339 if document.body[i + 6].startswith("<"):
2340 # This is an overlay specification
2342 document.body[i + 6] = document.body[i + 6][1:]
2343 if document.body[i + 6].endswith(">"):
2345 document.body[i + 6] = document.body[i + 6][:-1]
2346 # Convert to ArgInset
2347 document.body[i + 1] = "\\begin_inset Argument 1"
2351 def revert_beamerargs(document):
2352 " Reverts beamer arguments to old layout "
2354 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2355 if document.textclass not in beamer_classes:
2359 list_layouts = ["Itemize", "Enumerate", "Description"]
2360 headings = ["Part", "Section", "Section*", "Subsection", "Subsection*",
2361 "Subsubsection", "Subsubsection*", "FrameSubtitle", "NoteItem"]
2362 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2363 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2364 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2367 i = find_token(document.body, "\\begin_inset Argument", i)
2370 # Find containing paragraph layout
2371 parent = get_containing_layout(document.body, i)
2373 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2378 realparbeg = parent[3]
2379 layoutname = parent[0]
2381 for p in range(parbeg, parend):
2385 if layoutname in headings:
2386 m = rx.match(document.body[p])
2390 # Find containing paragraph layout
2391 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2392 endPlain = find_end_of_layout(document.body, beginPlain)
2393 endInset = find_end_of_inset(document.body, p)
2394 argcontent = document.body[beginPlain + 1 : endPlain]
2396 realparend = realparend - len(document.body[p : endInset + 1])
2398 del document.body[p : endInset + 1]
2399 if layoutname == "FrameSubtitle":
2400 pre = put_cmd_in_ert("\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2401 elif layoutname == "NoteItem":
2402 pre = put_cmd_in_ert("\\note<") + argcontent + put_cmd_in_ert(">[item]")
2403 elif layoutname.endswith('*'):
2404 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower()[:-1] + "<") + argcontent + put_cmd_in_ert(">*")
2406 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2407 secarg = find_token(document.body, "\\begin_inset Argument 2", parbeg, parend)
2409 # Find containing paragraph layout
2410 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", secarg)
2411 endPlain = find_end_of_layout(document.body, beginPlain)
2412 endInset = find_end_of_inset(document.body, secarg)
2413 argcontent = document.body[beginPlain + 1 : endPlain]
2415 realparend = realparend - len(document.body[secarg : endInset + 1])
2416 del document.body[secarg : endInset + 1]
2417 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2418 pre += put_cmd_in_ert("{")
2419 document.body[parbeg] = "\\begin_layout Standard"
2420 document.body[realparbeg : realparbeg] = pre
2421 pe = find_end_of_layout(document.body, parbeg)
2422 post = put_cmd_in_ert("}")
2423 document.body[pe : pe] = post
2424 realparend += len(pre) + len(post)
2425 if layoutname == "AgainFrame":
2426 m = rx.match(document.body[p])
2430 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2431 endPlain = find_end_of_layout(document.body, beginPlain)
2432 endInset = find_end_of_inset(document.body, p)
2433 content = document.body[beginPlain + 1 : endPlain]
2435 realparend = realparend - len(document.body[p : endInset + 1])
2437 del document.body[p : endInset + 1]
2438 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2439 document.body[realparbeg : realparbeg] = subst
2440 if layoutname == "Overprint":
2441 m = rx.match(document.body[p])
2445 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2446 endPlain = find_end_of_layout(document.body, beginPlain)
2447 endInset = find_end_of_inset(document.body, p)
2448 content = document.body[beginPlain + 1 : endPlain]
2450 realparend = realparend - len(document.body[p : endInset + 1])
2452 del document.body[p : endInset + 1]
2453 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2454 document.body[realparbeg : realparbeg] = subst
2455 if layoutname == "OverlayArea":
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 in list_layouts:
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]
2479 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2480 realparend = realparend + len(subst) - len(content)
2481 document.body[beginPlain + 1 : endPlain] = subst
2482 elif argnr == "item:1":
2483 j = find_end_of_inset(document.body, i)
2484 # Find containing paragraph layout
2485 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2486 endPlain = find_end_of_layout(document.body, beginPlain)
2487 content = document.body[beginPlain + 1 : endPlain]
2488 del document.body[i:j+1]
2489 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2490 document.body[realparbeg : realparbeg] = subst
2491 elif argnr == "item:2":
2492 j = find_end_of_inset(document.body, i)
2493 # Find containing paragraph layout
2494 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2495 endPlain = find_end_of_layout(document.body, beginPlain)
2496 content = document.body[beginPlain + 1 : endPlain]
2497 del document.body[i:j+1]
2498 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2499 document.body[realparbeg : realparbeg] = subst
2500 if layoutname in quote_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]
2510 realparend = realparend - len(document.body[p : endInset + 1])
2512 del document.body[p : endInset + 1]
2513 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2514 document.body[realparbeg : realparbeg] = subst
2515 if layoutname in corollary_layouts:
2516 m = rx.match(document.body[p])
2520 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2521 endPlain = find_end_of_layout(document.body, beginPlain)
2522 endInset = find_end_of_inset(document.body, p)
2523 content = document.body[beginPlain + 1 : endPlain]
2525 realparend = realparend - len(document.body[p : endInset + 1])
2527 del document.body[p : endInset + 1]
2528 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2529 document.body[realparbeg : realparbeg] = subst
2534 def revert_beamerargs2(document):
2535 " Reverts beamer arguments to old layout, step 2 "
2537 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2538 if document.textclass not in beamer_classes:
2542 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
2543 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2544 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2547 i = find_token(document.body, "\\begin_inset Argument", i)
2550 # Find containing paragraph layout
2551 parent = get_containing_layout(document.body, i)
2553 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2558 realparbeg = parent[3]
2559 layoutname = parent[0]
2561 for p in range(parbeg, parend):
2565 if layoutname in shifted_layouts:
2566 m = rx.match(document.body[p])
2570 document.body[p] = "\\begin_inset Argument 1"
2571 if layoutname in corollary_layouts:
2572 m = rx.match(document.body[p])
2576 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2577 endPlain = find_end_of_layout(document.body, beginPlain)
2578 endInset = find_end_of_inset(document.body, p)
2579 content = document.body[beginPlain + 1 : endPlain]
2581 realparend = realparend - len(document.body[p : endInset + 1])
2583 del document.body[p : endInset + 1]
2584 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2585 document.body[realparbeg : realparbeg] = subst
2586 if layoutname == "OverlayArea":
2587 m = rx.match(document.body[p])
2591 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2592 endPlain = find_end_of_layout(document.body, beginPlain)
2593 endInset = find_end_of_inset(document.body, p)
2594 content = document.body[beginPlain + 1 : endPlain]
2596 realparend = realparend - len(document.body[p : endInset + 1])
2598 del document.body[p : endInset + 1]
2599 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2600 document.body[realparbeg : realparbeg] = subst
2601 if layoutname == "AgainFrame":
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
2619 def revert_beamerargs3(document):
2620 " Reverts beamer arguments to old layout, step 3 "
2622 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2623 if document.textclass not in beamer_classes:
2626 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2629 i = find_token(document.body, "\\begin_inset Argument", i)
2632 # Find containing paragraph layout
2633 parent = get_containing_layout(document.body, i)
2635 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2640 realparbeg = parent[3]
2641 layoutname = parent[0]
2643 for p in range(parbeg, parend):
2647 if layoutname == "AgainFrame":
2648 m = rx.match(document.body[p])
2652 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2653 endPlain = find_end_of_layout(document.body, beginPlain)
2654 endInset = find_end_of_inset(document.body, p)
2655 content = document.body[beginPlain + 1 : endPlain]
2657 realparend = realparend - len(document.body[p : endInset + 1])
2659 del document.body[p : endInset + 1]
2660 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2661 document.body[realparbeg : realparbeg] = subst
2665 def revert_beamerflex(document):
2666 " Reverts beamer Flex insets "
2668 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2669 if document.textclass not in beamer_classes:
2672 new_flexes = {"Bold" : "\\textbf", "Emphasize" : "\\emph", "Only" : "\\only",
2673 "Uncover" : "\\uncover", "Visible" : "\\visible",
2674 "Invisible" : "\\invisible", "Alternative" : "\\alt",
2675 "Beamer_Note" : "\\note"}
2676 old_flexes = {"Alert" : "\\alert", "Structure" : "\\structure"}
2677 rx = re.compile(r'^\\begin_inset Flex (.+)$')
2681 i = find_token(document.body, "\\begin_inset Flex", i)
2684 m = rx.match(document.body[i])
2686 flextype = m.group(1)
2687 z = find_end_of_inset(document.body, i)
2689 document.warning("Can't find end of Flex " + flextype + " inset.")
2692 if flextype in new_flexes:
2693 pre = put_cmd_in_ert(new_flexes[flextype])
2694 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2696 argend = find_end_of_inset(document.body, arg)
2698 document.warning("Can't find end of Argument!")
2701 # Find containing paragraph layout
2702 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2703 endPlain = find_end_of_layout(document.body, beginPlain)
2704 argcontent = document.body[beginPlain + 1 : endPlain]
2706 z = z - len(document.body[arg : argend + 1])
2708 del document.body[arg : argend + 1]
2709 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2710 arg = find_token(document.body, "\\begin_inset Argument 2", i, z)
2712 argend = find_end_of_inset(document.body, arg)
2714 document.warning("Can't find end of Argument!")
2717 # Find containing paragraph layout
2718 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2719 endPlain = find_end_of_layout(document.body, beginPlain)
2720 argcontent = document.body[beginPlain + 1 : endPlain]
2722 z = z - len(document.body[arg : argend + 1])
2724 del document.body[arg : argend + 1]
2725 if flextype == "Alternative":
2726 pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
2728 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2729 pre += put_cmd_in_ert("{")
2730 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2731 endPlain = find_end_of_layout(document.body, beginPlain)
2733 z = z - len(document.body[i : beginPlain + 1])
2735 document.body[i : beginPlain + 1] = pre
2736 post = put_cmd_in_ert("}")
2737 document.body[z - 2 : z + 1] = post
2738 elif flextype in old_flexes:
2739 pre = put_cmd_in_ert(old_flexes[flextype])
2740 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2744 argend = find_end_of_inset(document.body, arg)
2746 document.warning("Can't find end of Argument!")
2749 # Find containing paragraph layout
2750 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2751 endPlain = find_end_of_layout(document.body, beginPlain)
2752 argcontent = document.body[beginPlain + 1 : endPlain]
2754 z = z - len(document.body[arg : argend + 1])
2756 del document.body[arg : argend + 1]
2757 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2758 pre += put_cmd_in_ert("{")
2759 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2760 endPlain = find_end_of_layout(document.body, beginPlain)
2762 z = z - len(document.body[i : beginPlain + 1])
2764 document.body[i : beginPlain + 1] = pre
2765 post = put_cmd_in_ert("}")
2766 document.body[z - 2 : z + 1] = post
2771 def revert_beamerblocks(document):
2772 " Reverts beamer block arguments to ERT "
2774 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2775 if document.textclass not in beamer_classes:
2778 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2780 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2783 i = find_token(document.body, "\\begin_inset Argument", i)
2786 # Find containing paragraph layout
2787 parent = get_containing_layout(document.body, i)
2789 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2794 realparbeg = parent[3]
2795 layoutname = parent[0]
2797 for p in range(parbeg, parend):
2801 if layoutname in blocks:
2802 m = rx.match(document.body[p])
2806 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2807 endPlain = find_end_of_layout(document.body, beginPlain)
2808 endInset = find_end_of_inset(document.body, p)
2809 content = document.body[beginPlain + 1 : endPlain]
2811 realparend = realparend - len(document.body[p : endInset + 1])
2813 del document.body[p : endInset + 1]
2814 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2815 document.body[realparbeg : realparbeg] = subst
2817 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2818 endPlain = find_end_of_layout(document.body, beginPlain)
2819 endInset = find_end_of_inset(document.body, p)
2820 content = document.body[beginPlain + 1 : endPlain]
2822 realparend = realparend - len(document.body[p : endInset + 1])
2824 del document.body[p : endInset + 1]
2825 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2826 document.body[realparbeg : realparbeg] = subst
2831 def convert_beamerblocks(document):
2832 " Converts beamer block ERT args to native InsetArgs "
2834 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2835 if document.textclass not in beamer_classes:
2838 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2842 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2845 parent = get_containing_layout(document.body, i)
2846 if parent == False or parent[1] != i:
2847 document.warning("Wrong parent layout!")
2853 if document.body[parbeg] == "\\begin_inset ERT":
2854 ertcont = parbeg + 5
2856 if document.body[ertcont].startswith("<"):
2857 # This is an overlay specification
2859 document.body[ertcont] = document.body[ertcont][1:]
2860 if document.body[ertcont].endswith(">"):
2862 document.body[ertcont] = document.body[ertcont][:-1]
2863 # Convert to ArgInset
2864 document.body[parbeg] = "\\begin_inset Argument 1"
2865 elif document.body[ertcont].endswith("}"):
2867 tok = document.body[ertcont].find('>{')
2869 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2870 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2871 'status collapsed', '', '\\begin_layout Plain Layout',
2872 document.body[ertcont][tok + 2:-1]]
2873 # Convert to ArgInset
2874 document.body[parbeg] = "\\begin_inset Argument 1"
2875 elif document.body[ertcont].startswith("{"):
2876 # This is the block title
2877 if document.body[ertcont].endswith("}"):
2878 # strip off the braces
2879 document.body[ertcont] = document.body[ertcont][1:-1]
2880 # Convert to ArgInset
2881 document.body[parbeg] = "\\begin_inset Argument 2"
2882 elif count_pars_in_inset(document.body, ertcont) > 1:
2883 # Multipar ERT. Skip this.
2886 convert_TeX_brace_to_Argument(document, i, 2, 2, False, True)
2889 j = find_end_of_layout(document.body, i)
2891 document.warning("end of layout not found!")
2892 k = find_token(document.body, "\\begin_inset Argument", i, j)
2894 document.warning("InsetArgument not found!")
2896 l = find_end_of_inset(document.body, k)
2897 m = find_token(document.body, "\\begin_inset ERT", l, j)
2905 def convert_overprint(document):
2906 " Convert old beamer overprint layouts to ERT "
2908 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2909 if document.textclass not in beamer_classes:
2914 i = find_token(document.body, "\\begin_layout Overprint", i)
2917 # Find end of sequence
2918 j = find_end_of_sequence(document.body, i)
2920 document.warning("Malformed LyX document. Cannot find end of Overprint sequence!")
2924 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
2926 if document.body[j] == "\\end_deeper":
2927 esubst = ["", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
2929 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
2930 endseq = endseq + len(esubst) - len(document.body[j : j])
2931 document.body[j : j] = esubst
2932 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
2934 argend = find_end_of_layout(document.body, argbeg)
2936 document.warning("Malformed LyX document. Cannot find end of Overprint argument!")
2939 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
2940 endPlain = find_end_of_layout(document.body, beginPlain)
2941 content = document.body[beginPlain + 1 : endPlain]
2943 endseq = endseq - len(document.body[argbeg : argend + 1])
2945 del document.body[argbeg : argend + 1]
2946 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2948 endseq = endseq - len(document.body[i : i])
2949 document.body[i : i] = subst + ["\\end_layout"]
2950 endseq += len(subst)
2952 for p in range(i, endseq):
2953 if document.body[p] == "\\begin_layout Overprint":
2954 document.body[p] = "\\begin_layout Standard"
2959 def revert_overprint(document):
2960 " Revert old beamer overprint layouts to ERT "
2962 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2963 if document.textclass not in beamer_classes:
2968 i = find_token(document.body, "\\begin_layout Overprint", i)
2971 # Find end of sequence
2972 j = find_end_of_sequence(document.body, i)
2974 document.warning("Malformed LyX document. Cannot find end of Overprint sequence!")
2978 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
2979 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}")
2980 endseq = endseq + len(esubst) - len(document.body[j : j])
2981 if document.body[j] == "\\end_deeper":
2982 document.body[j : j] = ["\\end_deeper", ""] + esubst
2984 document.body[j : j] = esubst
2987 if document.body[r] == "\\begin_deeper":
2988 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
2990 document.body[r] = ""
2991 document.body[s] = ""
2995 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
2997 argend = find_end_of_inset(document.body, argbeg)
2999 document.warning("Malformed LyX document. Cannot find end of Overprint argument!")
3002 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3003 endPlain = find_end_of_layout(document.body, beginPlain)
3004 content = document.body[beginPlain + 1 : endPlain]
3006 endseq = endseq - len(document.body[argbeg : argend])
3008 del document.body[argbeg : argend + 1]
3009 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3011 endseq = endseq - len(document.body[i : i])
3012 document.body[i : i] = subst + ["\\end_layout"]
3013 endseq += len(subst)
3019 if document.body[p] == "\\begin_layout Overprint":
3020 q = find_end_of_layout(document.body, p)
3022 document.warning("Malformed LyX document. Cannot find end of Overprint layout!")
3025 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\onslide")
3026 argbeg = find_token(document.body, "\\begin_inset Argument item:1", p, q)
3028 argend = find_end_of_inset(document.body, argbeg)
3030 document.warning("Malformed LyX document. Cannot find end of Overprint item argument!")
3033 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3034 endPlain = find_end_of_layout(document.body, beginPlain)
3035 content = document.body[beginPlain + 1 : endPlain]
3037 endseq = endseq - len(document.body[argbeg : argend + 1])
3039 del document.body[argbeg : argend + 1]
3040 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3041 endseq = endseq - len(document.body[p : p + 1]) + len(subst)
3042 document.body[p : p + 1] = subst
3048 def revert_frametitle(document):
3049 " Reverts beamer frametitle layout to ERT "
3051 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3052 if document.textclass not in beamer_classes:
3055 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
3058 i = find_token(document.body, "\\begin_layout FrameTitle", i)
3061 j = find_end_of_layout(document.body, i)
3063 document.warning("Malformed LyX document: Can't find end of FrameTitle layout")
3067 document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
3068 endlay += len(put_cmd_in_ert("}"))
3069 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\frametitle")
3070 for p in range(i, j):
3073 m = rx.match(document.body[p])
3077 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3078 endPlain = find_end_of_layout(document.body, beginPlain)
3079 endInset = find_end_of_inset(document.body, p)
3080 content = document.body[beginPlain + 1 : endPlain]
3082 endlay = endlay - len(document.body[p : endInset + 1])
3084 del document.body[p : endInset + 1]
3085 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3087 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3088 endPlain = find_end_of_layout(document.body, beginPlain)
3089 endInset = find_end_of_inset(document.body, p)
3090 content = document.body[beginPlain + 1 : endPlain]
3092 endlay = endlay - len(document.body[p : endInset + 1])
3094 del document.body[p : endInset + 1]
3095 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3097 subst += put_cmd_in_ert("{")
3098 document.body[i : i + 1] = subst
3102 def convert_epigraph(document):
3103 " Converts memoir epigraph to new syntax "
3105 if document.textclass != "memoir":
3110 i = find_token(document.body, "\\begin_layout Epigraph", i)
3113 j = find_end_of_layout(document.body, i)
3115 document.warning("Malformed LyX document: Can't find end of Epigraph layout")
3120 ert = find_token(document.body, "\\begin_inset ERT", i, j)
3122 endInset = find_end_of_inset(document.body, ert)
3123 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", ert)
3124 endPlain = find_end_of_layout(document.body, beginPlain)
3125 ertcont = beginPlain + 2
3126 if document.body[ertcont] == "}{":
3128 # Convert to ArgInset
3129 endlay = endlay - 2 * len(document.body[j])
3130 begsubst = ['\\begin_inset Argument post:1', 'status collapsed', '',
3131 '\\begin_layout Plain Layout']
3132 endsubst = ['\\end_layout', '', '\\end_inset', '', document.body[j]]
3133 document.body[j : j + 1] = endsubst
3134 document.body[endInset + 1 : endInset + 1] = begsubst
3136 endlay += len(begsubst) + len(endsubst)
3137 endlay = endlay - len(document.body[ert : endInset + 1])
3138 del document.body[ert : endInset + 1]
3143 def revert_epigraph(document):
3144 " Reverts memoir epigraph argument to ERT "
3146 if document.textclass != "memoir":
3151 i = find_token(document.body, "\\begin_layout Epigraph", i)
3154 j = find_end_of_layout(document.body, i)
3156 document.warning("Malformed LyX document: Can't find end of Epigraph layout")
3161 p = find_token(document.body, "\\begin_layout Argument post:1", i, j)
3163 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3164 endPlain = find_end_of_layout(document.body, beginPlain)
3165 endInset = find_end_of_inset(document.body, p)
3166 content = document.body[beginPlain + 1 : endPlain]
3168 endlay = endlay - len(document.body[p : endInset + 1])
3170 del document.body[p : endInset + 1]
3171 subst += put_cmd_in_ert("}{") + content
3173 subst += put_cmd_in_ert("}{")
3175 document.body[j : j] = subst + document.body[j : j]
3179 def convert_captioninsets(document):
3180 " Converts caption insets to new syntax "
3184 i = find_token(document.body, "\\begin_inset Caption", i)
3187 document.body[i] = "\\begin_inset Caption Standard"
3191 def revert_captioninsets(document):
3192 " Reverts caption insets to old syntax "
3196 i = find_token(document.body, "\\begin_inset Caption Standard", i)
3199 document.body[i] = "\\begin_inset Caption"
3203 def convert_captionlayouts(document):
3204 " Convert caption layouts to caption insets. "
3207 "Captionabove": "Above",
3208 "Captionbelow": "Below",
3209 "FigCaption" : "FigCaption",
3210 "Table_Caption" : "Table",
3211 "CenteredCaption" : "Centered",
3212 "Bicaption" : "Bicaption",
3217 i = find_token(document.body, "\\begin_layout", i)
3220 val = get_value(document.body, "\\begin_layout", i)
3221 if val in caption_dict.keys():
3222 j = find_end_of_layout(document.body, i)
3224 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3227 document.body[j:j] = ["\\end_layout", "", "\\end_inset", "", ""]
3228 document.body[i:i+1] = ["\\begin_layout %s" % document.default_layout,
3229 "\\begin_inset Caption %s" % caption_dict[val], "",
3230 "\\begin_layout %s" % document.default_layout]
3234 def revert_captionlayouts(document):
3235 " Revert caption insets to caption layouts. "
3238 "Above" : "Captionabove",
3239 "Below" : "Captionbelow",
3240 "FigCaption" : "FigCaption",
3241 "Table" : "Table_Caption",
3242 "Centered" : "CenteredCaption",
3243 "Bicaption" : "Bicaption",
3247 rx = re.compile(r'^\\begin_inset Caption (\S+)$')
3249 i = find_token(document.body, "\\begin_inset Caption", i)
3253 m = rx.match(document.body[i])
3257 if val not in caption_dict.keys():
3261 # We either need to delete the previous \begin_layout line, or we
3262 # need to end the previous layout if this inset is not in the first
3263 # position of the paragraph.
3264 layout_before = find_token_backwards(document.body, "\\begin_layout", i)
3265 if layout_before == -1:
3266 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3268 layout_line = document.body[layout_before]
3269 del_layout_before = True
3270 l = layout_before + 1
3272 if document.body[l] != "":
3273 del_layout_before = False
3276 if del_layout_before:
3277 del document.body[layout_before:i]
3280 document.body[i:i] = ["\\end_layout", ""]
3283 # Find start of layout in the inset and end of inset
3284 j = find_token(document.body, "\\begin_layout", i)
3286 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3288 k = find_end_of_inset(document.body, i)
3290 document.warning("Malformed LyX document: Missing `\\end_inset'.")
3293 # We either need to delete the following \end_layout line, or we need
3294 # to restart the old layout if this inset is not at the paragraph end.
3295 layout_after = find_token(document.body, "\\end_layout", k)
3296 if layout_after == -1:
3297 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3299 del_layout_after = True
3301 while l < layout_after:
3302 if document.body[l] != "":
3303 del_layout_after = False
3306 if del_layout_after:
3307 del document.body[k+1:layout_after+1]
3309 document.body[k+1:k+1] = [layout_line, ""]
3311 # delete \begin_layout and \end_inset and replace \begin_inset with
3312 # "\begin_layout XXX". This works because we can only have one
3313 # paragraph in the caption inset: The old \end_layout will be recycled.
3314 del document.body[k]
3315 if document.body[k] == "":
3316 del document.body[k]
3317 del document.body[j]
3318 if document.body[j] == "":
3319 del document.body[j]
3320 document.body[i] = "\\begin_layout %s" % caption_dict[val]
3321 if document.body[i+1] == "":
3322 del document.body[i+1]
3326 def revert_fragileframe(document):
3327 " Reverts beamer FragileFrame layout to ERT "
3329 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3330 if document.textclass not in beamer_classes:
3335 i = find_token(document.body, "\\begin_layout FragileFrame", i)
3338 # Find end of sequence
3339 j = find_end_of_sequence(document.body, i)
3341 document.warning("Malformed LyX document. Cannot find end of FragileFrame sequence!")
3345 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{frame}")
3346 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{frame}")
3347 endseq = endseq + len(esubst) - len(document.body[j : j])
3348 if document.body[j] == "\\end_deeper":
3349 document.body[j : j] = ["\\end_deeper", ""] + esubst
3351 document.body[j : j] = esubst
3352 for q in range(i, j):
3353 if document.body[q] == "\\begin_layout FragileFrame":
3354 document.body[q] = "\\begin_layout %s" % document.default_layout
3357 if document.body[r] == "\\begin_deeper":
3358 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3360 document.body[r] = ""
3361 document.body[s] = ""
3365 for p in range(1, 5):
3366 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, j)
3369 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3370 endPlain = find_end_of_layout(document.body, beginPlain)
3371 endInset = find_end_of_inset(document.body, arg)
3372 content = document.body[beginPlain + 1 : endPlain]
3374 j = j - len(document.body[arg : endInset + 1])
3376 del document.body[arg : endInset + 1]
3377 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3379 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3380 endPlain = find_end_of_layout(document.body, beginPlain)
3381 endInset = find_end_of_inset(document.body, arg)
3382 content = document.body[beginPlain + 1 : endPlain]
3384 j = j - len(document.body[arg : endInset + 1])
3386 del document.body[arg : endInset + 1]
3387 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3389 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3390 endPlain = find_end_of_layout(document.body, beginPlain)
3391 endInset = find_end_of_inset(document.body, arg)
3392 content = document.body[beginPlain + 1 : endPlain]
3394 j = j - len(document.body[arg : endInset + 1])
3396 del document.body[arg : endInset + 1]
3397 subst += put_cmd_in_ert("[fragile,") + content + put_cmd_in_ert("]")
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 subst += put_cmd_in_ert("[fragile]")
3411 document.body[i : i + 1] = subst
3415 def revert_newframes(document):
3416 " Reverts beamer Frame and PlainFrame layouts to old forms "
3418 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3419 if document.textclass not in beamer_classes:
3423 "Frame" : "BeginFrame",
3424 "PlainFrame" : "BeginPlainFrame",
3427 rx = re.compile(r'^\\begin_layout (\S+)$')
3430 i = find_token(document.body, "\\begin_layout", i)
3434 m = rx.match(document.body[i])
3438 if val not in frame_dict.keys():
3441 # Find end of sequence
3442 j = find_end_of_sequence(document.body, i)
3444 document.warning("Malformed LyX document. Cannot find end of Frame sequence!")
3448 subst = ["\\begin_layout %s" % frame_dict[val]]
3449 esubst = ["\\end_layout", "", "\\begin_layout EndFrame", "", "\\end_layout"]
3450 endseq = endseq + len(esubst) - len(document.body[j : j])
3451 if document.body[j] == "\\end_deeper":
3452 document.body[j : j] = ["\\end_deeper", ""] + esubst
3454 document.body[j : j] = esubst
3455 for q in range(i, j):
3456 if document.body[q] == "\\begin_layout %s" % val:
3457 document.body[q] = "\\begin_layout %s" % document.default_layout
3460 if document.body[r] == "\\begin_deeper":
3461 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3463 document.body[r] = ""
3464 document.body[s] = ""
3468 l = find_end_of_layout(document.body, i)
3469 for p in range(1, 5):
3470 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, l)
3473 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3474 endPlain = find_end_of_layout(document.body, beginPlain)
3475 endInset = find_end_of_inset(document.body, arg)
3476 content = document.body[beginPlain + 1 : endPlain]
3478 l = l - len(document.body[arg : endInset + 1])
3480 del document.body[arg : endInset + 1]
3481 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3483 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3484 endPlain = find_end_of_layout(document.body, beginPlain)
3485 endInset = find_end_of_inset(document.body, arg)
3486 content = document.body[beginPlain + 1 : endPlain]
3488 l = l - len(document.body[arg : endInset + 1])
3490 del document.body[arg : endInset + 1]
3491 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3493 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3494 endPlain = find_end_of_layout(document.body, beginPlain)
3495 endInset = find_end_of_inset(document.body, arg)
3496 content = document.body[beginPlain + 1 : endPlain]
3498 l = l - len(document.body[arg : endInset + 1])
3500 del document.body[arg : endInset + 1]
3501 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
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]
3513 document.body[i : i + 1] = subst
3516 # known encodings that do not change their names (same LyX and LaTeX names)
3517 known_enc_tuple = ("auto", "default", "ansinew", "applemac", "armscii8", "ascii",
3518 "cp437", "cp437de", "cp850", "cp852", "cp855", "cp858", "cp862", "cp865", "cp866",
3519 "cp1250", "cp1251", "cp1252", "cp1255", "cp1256", "cp1257", "koi8-r", "koi8-u",
3520 "pt154", "pt254", "tis620-0", "utf8", "utf8x", "utf8-plain")
3522 def convert_encodings(document):
3523 "Use the LyX names of the encodings instead of the LaTeX names."
3524 LaTeX2LyX_enc_dict = {
3525 "8859-6": "iso8859-6",
3526 "8859-8": "iso8859-8",
3528 "euc": "euc-jp-platex",
3533 "iso88595": "iso8859-5",
3534 "iso-8859-7": "iso8859-7",
3536 "jis": "jis-platex",
3538 "l7xenc": "iso8859-13",
3539 "latin1": "iso8859-1",
3540 "latin2": "iso8859-2",
3541 "latin3": "iso8859-3",
3542 "latin4": "iso8859-4",
3543 "latin5": "iso8859-9",
3544 "latin9": "iso8859-15",
3545 "latin10": "iso8859-16",
3546 "SJIS": "shift-jis",
3547 "sjis": "shift-jis-platex",
3550 i = find_token(document.header, "\\inputencoding" , 0)
3553 val = get_value(document.header, "\\inputencoding", i)
3554 if val in LaTeX2LyX_enc_dict.keys():
3555 document.header[i] = "\\inputencoding %s" % LaTeX2LyX_enc_dict[val]
3556 elif val not in known_enc_tuple:
3557 document.warning("Ignoring unknown input encoding: `%s'" % val)
3560 def revert_encodings(document):
3561 """Revert to using the LaTeX names of the encodings instead of the LyX names.
3562 Also revert utf8-platex to sjis, the language default when using Japanese.
3564 LyX2LaTeX_enc_dict = {
3569 "euc-jp-platex": "euc",
3572 "iso8859-1": "latin1",
3573 "iso8859-2": "latin2",
3574 "iso8859-3": "latin3",
3575 "iso8859-4": "latin4",
3576 "iso8859-5": "iso88595",
3577 "iso8859-6": "8859-6",
3578 "iso8859-7": "iso-8859-7",
3579 "iso8859-8": "8859-8",
3580 "iso8859-9": "latin5",
3581 "iso8859-13": "l7xenc",
3582 "iso8859-15": "latin9",
3583 "iso8859-16": "latin10",
3585 "jis-platex": "jis",
3586 "shift-jis": "SJIS",
3587 "shift-jis-platex": "sjis",
3589 "utf8-platex": "sjis"
3591 i = find_token(document.header, "\\inputencoding" , 0)
3594 val = get_value(document.header, "\\inputencoding", i)
3595 if val in LyX2LaTeX_enc_dict.keys():
3596 document.header[i] = "\\inputencoding %s" % LyX2LaTeX_enc_dict[val]
3597 elif val not in known_enc_tuple:
3598 document.warning("Ignoring unknown input encoding: `%s'" % val)
3601 def revert_IEEEtran_3(document):
3603 Reverts Flex Insets to TeX-code
3605 if document.textclass == "IEEEtran":
3611 h = find_token(document.body, "\\begin_inset Flex Author Mark", h)
3613 endh = find_end_of_inset(document.body, h)
3614 document.body[endh - 2 : endh + 1] = put_cmd_in_ert("}")
3615 document.body[h : h + 4] = put_cmd_in_ert("\\IEEEauthorrefmark{")
3618 i = find_token(document.body, "\\begin_inset Flex Author Name", i)
3620 endi = find_end_of_inset(document.body, i)
3621 document.body[endi - 2 : endi + 1] = put_cmd_in_ert("}")
3622 document.body[i : i + 4] = put_cmd_in_ert("\\IEEEauthorblockN{")
3625 j = find_token(document.body, "\\begin_inset Flex Author Affiliation", j)
3627 endj = find_end_of_inset(document.body, j)
3628 document.body[endj - 2 : endj + 1] = put_cmd_in_ert("}")
3629 document.body[j : j + 4] = put_cmd_in_ert("\\IEEEauthorblockA{")
3631 if i == -1 and j == -1 and h == -1:
3635 def revert_kurier_fonts(document):
3636 " Revert kurier font definition to LaTeX "
3638 i = find_token(document.header, "\\font_math", 0)
3640 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3641 val = get_value(document.header, "\\font_math", i)
3642 if val == "kurier-math":
3643 add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
3644 "\\usepackage[math]{kurier}\n" \
3645 "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
3646 document.header[i] = "\\font_math auto"
3648 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3649 kurier_fonts = ["kurier", "kurierc", "kurierl", "kurierlc"]
3650 k = find_token(document.header, "\\font_sans kurier", 0)
3652 sf = get_value(document.header, "\\font_sans", k)
3653 if sf in kurier_fonts:
3654 add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
3655 document.header[k] = "\\font_sans default"
3657 def revert_iwona_fonts(document):
3658 " Revert iwona font definition to LaTeX "
3660 i = find_token(document.header, "\\font_math", 0)
3662 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3663 val = get_value(document.header, "\\font_math", i)
3664 if val == "iwona-math":
3665 add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
3666 "\\usepackage[math]{iwona}\n" \
3667 "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
3668 document.header[i] = "\\font_math auto"
3670 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3671 iwona_fonts = ["iwona", "iwonac", "iwonal", "iwonalc"]
3672 k = find_token(document.header, "\\font_sans iwona", 0)
3674 sf = get_value(document.header, "\\font_sans", k)
3675 if sf in iwona_fonts:
3676 add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
3677 document.header[k] = "\\font_sans default"
3680 def revert_new_libertines(document):
3681 " Revert new libertine font definition to LaTeX "
3683 if find_token(document.header, "\\use_non_tex_fonts true", 0) != -1:
3686 i = find_token(document.header, "\\font_typewriter libertine-mono", 0)
3688 preamble = "\\usepackage"
3689 sc = find_token(document.header, "\\font_tt_scale", 0)
3691 scval = get_value(document.header, "\\font_tt_scale", sc)
3693 preamble += "[scale=%f]" % (float(scval) / 100)
3694 document.header[sc] = "\\font_tt_scale 100"
3695 preamble += "{libertineMono-type1}"
3696 add_to_preamble(document, [preamble])
3697 document.header[i] = "\\font_typewriter default"
3699 k = find_token(document.header, "\\font_sans biolinum", 0)
3701 preamble = "\\usepackage"
3703 j = find_token(document.header, "\\font_osf true", 0)
3708 sc = find_token(document.header, "\\font_sf_scale", 0)
3710 scval = get_value(document.header, "\\font_sf_scale", sc)
3712 options += ",scale=%f" % (float(scval) / 100)
3713 document.header[sc] = "\\font_sf_scale 100"
3715 preamble += "[" + options +"]"
3716 preamble += "{biolinum-type1}"
3717 add_to_preamble(document, [preamble])
3718 document.header[k] = "\\font_sans default"
3721 def convert_lyxframes(document):
3722 " Converts old beamer frames to new style "
3724 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3725 if document.textclass not in beamer_classes:
3728 framebeg = ["BeginFrame", "BeginPlainFrame"]
3729 frameend = ["EndFrame", "BeginFrame", "BeginPlainFrame", "AgainFrame", "Section", "Section*",
3730 "Subsection", "Subsection*", "Subsubsection", "Subsubsection*"]
3731 for lay in framebeg:
3734 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
3737 parent = get_containing_layout(document.body, i)
3738 if parent == False or parent[1] != i:
3739 document.warning("Wrong parent layout!")
3742 frametype = parent[0]
3746 # Step I: Convert ERT arguments
3747 # FIXME: This currently only works if the arguments are in one single ERT
3749 if document.body[parbeg] == "\\begin_inset ERT":
3750 ertend = find_end_of_inset(document.body, parbeg)
3752 document.warning("Malformed LyX document: missing ERT \\end_inset")
3754 ertcont = parbeg + 5
3755 if document.body[ertcont].startswith("[<"):
3756 # This is a default overlay specification
3758 document.body[ertcont] = document.body[ertcont][2:]
3759 if document.body[ertcont].endswith(">]"):
3761 document.body[ertcont] = document.body[ertcont][:-2]
3762 elif document.body[ertcont].endswith("]"):
3764 tok = document.body[ertcont].find('>][')
3766 subst = [document.body[ertcont][:tok],
3767 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
3768 'status collapsed', '', '\\begin_layout Plain Layout',
3769 document.body[ertcont][tok + 3:-1]]
3770 document.body[ertcont : ertcont + 1] = subst
3772 # Convert to ArgInset
3773 document.body[parbeg] = "\\begin_inset Argument 2"
3774 elif document.body[ertcont].startswith("<"):
3775 # This is an overlay specification
3777 document.body[ertcont] = document.body[ertcont][1:]
3778 if document.body[ertcont].endswith(">"):
3780 document.body[ertcont] = document.body[ertcont][:-1]
3781 # Convert to ArgInset
3782 document.body[parbeg] = "\\begin_inset Argument 1"
3783 elif document.body[ertcont].endswith(">]"):
3785 tok = document.body[ertcont].find('>[<')
3787 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
3788 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
3789 'status collapsed', '', '\\begin_layout Plain Layout',
3790 document.body[ertcont][tok + 3:-2]]
3791 # Convert to ArgInset
3792 document.body[parbeg] = "\\begin_inset Argument 1"
3794 elif document.body[ertcont].endswith("]"):
3796 tok = document.body[ertcont].find('>[<')
3799 tokk = document.body[ertcont].find('>][')
3801 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
3802 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
3803 'status collapsed', '', '\\begin_layout Plain Layout',
3804 document.body[ertcont][tok + 3:tokk],
3805 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
3806 'status collapsed', '', '\\begin_layout Plain Layout',
3807 document.body[ertcont][tokk + 3:-1]]
3810 tokk = document.body[ertcont].find('>[')
3812 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tokk],
3813 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
3814 'status collapsed', '', '\\begin_layout Plain Layout',
3815 document.body[ertcont][tokk + 2:-1]]
3817 # Convert to ArgInset
3818 document.body[parbeg] = "\\begin_inset Argument 1"
3819 elif document.body[ertcont].startswith("["):
3820 # This is an ERT option
3822 document.body[ertcont] = document.body[ertcont][1:]
3823 if document.body[ertcont].endswith("]"):
3825 document.body[ertcont] = document.body[ertcont][:-1]
3826 # Convert to ArgInset
3827 document.body[parbeg] = "\\begin_inset Argument 3"
3828 # End of argument conversion
3829 # Step II: Now rename the layout and convert the title to an argument
3830 j = find_end_of_layout(document.body, i)
3831 document.body[j : j + 1] = ['\\end_layout', '', '\\end_inset', '', '\\end_layout']
3832 if lay == "BeginFrame":
3833 document.body[i] = "\\begin_layout Frame"
3835 document.body[i] = "\\begin_layout PlainFrame"
3836 document.body[ertend + 1 : ertend + 1] = ['\\begin_inset Argument 4',
3837 'status open', '', '\\begin_layout Plain Layout']
3838 # Step III: find real frame end
3842 fend = find_token(document.body, "\\begin_layout", jj)
3844 document.warning("Malformed LyX document: No real frame end!")
3846 val = get_value(document.body, "\\begin_layout", fend)
3847 if val not in frameend:
3850 old = document.body[fend]
3851 if val == frametype:
3852 document.body[fend : fend] = ['\\end_deeper', '', '\\begin_layout Separator', '', '\\end_layout']
3854 document.body[fend : fend] = ['\\end_deeper']
3855 document.body[j + 1 : j + 1] = ['', '\\begin_deeper']
3860 def remove_endframes(document):
3861 " Remove deprecated beamer endframes "
3863 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3864 if document.textclass not in beamer_classes:
3869 i = find_token_exact(document.body, "\\begin_layout EndFrame", i)
3872 j = find_end_of_layout(document.body, i)
3874 document.warning("Malformed LyX document: Missing \\end_layout to EndFrame")
3877 del document.body[i : j + 1]
3880 def revert_powerdot_flexes(document):
3881 " Reverts powerdot flex insets "
3883 if document.textclass != "powerdot":
3886 flexes = {"Onslide" : "\\onslide",
3887 "Onslide*" : "\\onslide*",
3888 "Onslide+" : "\\onslide+"}
3889 rx = re.compile(r'^\\begin_inset Flex (.+)$')
3893 i = find_token(document.body, "\\begin_inset Flex", i)
3896 m = rx.match(document.body[i])
3898 flextype = m.group(1)
3899 z = find_end_of_inset(document.body, i)
3901 document.warning("Can't find end of Flex " + flextype + " inset.")
3904 if flextype in flexes:
3905 pre = put_cmd_in_ert(flexes[flextype])
3906 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
3908 argend = find_end_of_inset(document.body, arg)
3910 document.warning("Can't find end of Argument!")
3913 # Find containing paragraph layout
3914 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3915 endPlain = find_end_of_layout(document.body, beginPlain)
3916 argcontent = document.body[beginPlain + 1 : endPlain]
3918 z = z - len(document.body[arg : argend + 1])
3920 del document.body[arg : argend + 1]
3921 pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
3922 pre += put_cmd_in_ert("{")
3923 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
3924 endPlain = find_end_of_layout(document.body, beginPlain)
3926 z = z - len(document.body[i : beginPlain + 1])
3928 document.body[i : beginPlain + 1] = pre
3929 post = put_cmd_in_ert("}")
3930 document.body[z - 2 : z + 1] = post
3934 def revert_powerdot_pause(document):
3935 " Reverts powerdot pause layout to ERT "
3937 if document.textclass != "powerdot":
3942 i = find_token(document.body, "\\begin_layout Pause", i)
3945 j = find_end_of_layout(document.body, i)
3947 document.warning("Malformed LyX document: Can't find end of Pause layout")
3951 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\pause")
3952 for p in range(i, j):
3955 arg = find_token(document.body, "\\begin_inset Argument 1", i, j)
3957 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3958 endPlain = find_end_of_layout(document.body, beginPlain)
3959 endInset = find_end_of_inset(document.body, p)
3960 content = document.body[beginPlain + 1 : endPlain]
3962 endlay = endlay - len(document.body[p : endInset + 1])
3964 del document.body[p : endInset + 1]
3965 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3967 document.body[i : i + 1] = subst
3971 def revert_powerdot_itemargs(document):
3972 " Reverts powerdot item arguments to ERT "
3974 if document.textclass != "powerdot":
3978 list_layouts = ["Itemize", "ItemizeType1", "Enumerate", "EnumerateType1"]
3979 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
3982 i = find_token(document.body, "\\begin_inset Argument", i)
3985 # Find containing paragraph layout
3986 parent = get_containing_layout(document.body, i)
3988 document.warning("Malformed LyX document: Can't find parent paragraph layout")
3993 realparbeg = parent[3]
3994 layoutname = parent[0]
3996 for p in range(parbeg, parend):
4000 if layoutname in list_layouts:
4001 m = rx.match(document.body[p])
4004 if argnr == "item:1":
4005 j = find_end_of_inset(document.body, i)
4006 # Find containing paragraph layout
4007 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
4008 endPlain = find_end_of_layout(document.body, beginPlain)
4009 content = document.body[beginPlain + 1 : endPlain]
4010 del document.body[i:j+1]
4011 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
4012 document.body[realparbeg : realparbeg] = subst
4013 elif argnr == "item:2":
4014 j = find_end_of_inset(document.body, i)
4015 # Find containing paragraph layout
4016 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
4017 endPlain = find_end_of_layout(document.body, beginPlain)
4018 content = document.body[beginPlain + 1 : endPlain]
4019 del document.body[i:j+1]
4020 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
4021 document.body[realparbeg : realparbeg] = subst
4026 def revert_powerdot_columns(document):
4027 " Reverts powerdot twocolumn to TeX-code "
4028 if document.textclass != "powerdot":
4031 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
4034 i = find_token(document.body, "\\begin_layout Twocolumn", i)
4037 j = find_end_of_layout(document.body, i)
4039 document.warning("Malformed LyX document: Can't find end of Twocolumn layout")
4043 document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
4044 endlay += len(put_cmd_in_ert("}"))
4045 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\twocolumn")
4046 for p in range(i, j):
4049 m = rx.match(document.body[p])
4053 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
4054 endPlain = find_end_of_layout(document.body, beginPlain)
4055 endInset = find_end_of_inset(document.body, p)
4056 content = document.body[beginPlain + 1 : endPlain]
4058 endlay = endlay - len(document.body[p : endInset + 1])
4060 del document.body[p : endInset + 1]
4061 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
4063 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
4064 endPlain = find_end_of_layout(document.body, beginPlain)
4065 endInset = find_end_of_inset(document.body, p)
4066 content = document.body[beginPlain + 1 : endPlain]
4068 endlay = endlay - len(document.body[p : endInset + 1])
4070 del document.body[p : endInset + 1]
4071 subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
4073 subst += put_cmd_in_ert("{")
4074 document.body[i : i + 1] = subst
4078 def revert_mbox_fbox(document):
4079 'Convert revert mbox/fbox boxes to TeX-code'
4082 i = find_token(document.body, "\\begin_inset Box", i)
4085 j = find_token(document.body, "width", i)
4087 document.warning("Malformed LyX document: Can't find box width")
4089 width = get_value(document.body, "width", j)
4090 k = find_end_of_inset(document.body, j)
4092 document.warning("Malformed LyX document: Can't find end of box inset")
4095 BeginLayout = find_token(document.body, "\\begin_layout Plain Layout", j)
4096 EndLayout = find_token(document.body, "\\end_layout", BeginLayout)
4097 # replace if width is ""
4099 document.body[EndLayout:k + 1] = put_cmd_in_ert("}")
4100 if document.body[i] == "\\begin_inset Box Frameless":
4101 document.body[i:BeginLayout + 1] = put_cmd_in_ert("\\mbox{")
4102 if document.body[i] == "\\begin_inset Box Boxed":
4103 document.body[i:BeginLayout + 1] = put_cmd_in_ert("\\fbox{")
4107 def revert_starred_caption(document):
4108 " Reverts unnumbered longtable caption insets "
4112 i = find_token(document.body, "\\begin_inset Caption LongTableNoNumber", i)
4115 # This is not equivalent, but since the caption inset is a full blown
4116 # text inset a true conversion to ERT is too difficult.
4117 document.body[i] = "\\begin_inset Caption Standard"
4121 def revert_forced_local_layout(document):
4124 i = find_token(document.header, "\\begin_forced_local_layout", i)
4127 j = find_end_of(document.header, i, "\\begin_forced_local_layout", "\\end_forced_local_layout")
4129 # this should not happen
4131 regexp = re.compile(r'\s*forcelocal', re.IGNORECASE)
4132 k = find_re(document.header, regexp, i, j)
4134 del document.header[k]
4136 k = find_re(document.header, regexp, i, j)
4137 k = find_token(document.header, "\\begin_local_layout", 0)
4139 document.header[i] = "\\begin_local_layout"
4140 document.header[j] = "\\end_local_layout"
4142 l = find_end_of(document.header, k, "\\begin_local_layout", "\\end_local_layout")
4144 # this should not happen
4146 lines = document.header[i+1 : j]
4148 document.header[k+1 : k+1] = lines
4149 document.header[i : j ] = []
4151 document.header[i : j ] = []
4152 document.header[k+1 : k+1] = lines
4155 def revert_aa1(document):
4156 " Reverts InsetArguments of aa to TeX-code "
4157 if document.textclass == "aa":
4161 i = find_token(document.body, "\\begin_layout Abstract (structured)", i)
4163 revert_Argument_to_TeX_brace(document, i, 0, 1, 4, False, False)
4169 def revert_aa2(document):
4170 " Reverts InsetArguments of aa to TeX-code "
4171 if document.textclass == "aa":
4175 i = find_token(document.body, "\\begin_layout Abstract (structured)", i)
4177 document.body[i] = "\\begin_layout Abstract"
4187 supported_versions = ["2.1.0","2.1"]
4190 [415, [convert_undertilde]],
4192 [417, [convert_japanese_encodings]],
4195 [420, [convert_biblio_style]],
4196 [421, [convert_longtable_captions]],
4197 [422, [convert_use_packages]],
4198 [423, [convert_use_mathtools]],
4199 [424, [convert_cite_engine_type]],
4203 [428, [convert_cell_rotation]],
4204 [429, [convert_table_rotation]],
4205 [430, [convert_listoflistings]],
4206 [431, [convert_use_amssymb]],
4208 [433, [convert_armenian]],
4216 [441, [convert_mdnomath]],
4221 [446, [convert_latexargs]],
4222 [447, [convert_IEEEtran, convert_AASTeX, convert_AGUTeX, convert_IJMP, convert_SIGPLAN, convert_SIGGRAPH, convert_EuropeCV, convert_Initials, convert_ModernCV]],
4223 [448, [convert_literate]],
4226 [451, [convert_beamerargs, convert_againframe_args, convert_corollary_args, convert_quote_args]],
4227 [452, [convert_beamerblocks]],
4228 [453, [convert_use_stmaryrd]],
4229 [454, [convert_overprint]],
4231 [456, [convert_epigraph]],
4232 [457, [convert_use_stackrel]],
4233 [458, [convert_captioninsets, convert_captionlayouts]],
4238 [463, [convert_encodings]],
4239 [464, [convert_use_cancel]],
4240 [465, [convert_lyxframes, remove_endframes]],
4246 [471, [convert_cite_engine_type_default]],
4251 [471, [revert_aa1,revert_aa2]],
4252 [470, [revert_cite_engine_type_default]],
4253 [469, [revert_forced_local_layout]],
4254 [468, [revert_starred_caption]],
4255 [467, [revert_mbox_fbox]],
4256 [466, [revert_iwona_fonts]],
4257 [465, [revert_powerdot_flexes, revert_powerdot_pause, revert_powerdot_itemargs, revert_powerdot_columns]],
4259 [463, [revert_use_cancel]],
4260 [462, [revert_encodings]],
4261 [461, [revert_new_libertines]],
4262 [460, [revert_kurier_fonts]],
4263 [459, [revert_IEEEtran_3]],
4264 [458, [revert_fragileframe, revert_newframes]],
4265 [457, [revert_captioninsets, revert_captionlayouts]],
4266 [456, [revert_use_stackrel]],
4267 [455, [revert_epigraph]],
4268 [454, [revert_frametitle]],
4269 [453, [revert_overprint]],
4270 [452, [revert_use_stmaryrd]],
4271 [451, [revert_beamerblocks]],
4272 [450, [revert_beamerargs, revert_beamerargs2, revert_beamerargs3, revert_beamerflex]],
4273 [449, [revert_garamondx, revert_garamondx_newtxmath]],
4274 [448, [revert_itemargs]],
4275 [447, [revert_literate]],
4276 [446, [revert_IEEEtran, revert_IEEEtran_2, revert_AASTeX, revert_AGUTeX, revert_IJMP, revert_SIGPLAN, revert_SIGGRAPH, revert_EuropeCV, revert_Initials, revert_ModernCV_3]],
4277 [445, [revert_latexargs]],
4278 [444, [revert_uop]],
4279 [443, [revert_biolinum]],
4281 [441, [revert_newtxmath]],
4282 [440, [revert_mdnomath]],
4283 [439, [revert_mathfonts]],
4284 [438, [revert_minionpro]],
4285 [437, [revert_ipadeco, revert_ipachar]],
4286 [436, [revert_texgyre]],
4287 [435, [revert_mathdesign]],
4288 [434, [revert_txtt]],
4289 [433, [revert_libertine]],
4290 [432, [revert_armenian]],
4291 [431, [revert_languages, revert_ancientgreek]],
4292 [430, [revert_use_amssymb]],
4293 [429, [revert_listoflistings]],
4294 [428, [revert_table_rotation]],
4295 [427, [revert_cell_rotation]],
4296 [426, [revert_tipa]],
4297 [425, [revert_verbatim]],
4298 [424, [revert_cancel]],
4299 [423, [revert_cite_engine_type]],
4300 [422, [revert_use_mathtools]],
4301 [421, [revert_use_packages]],
4302 [420, [revert_longtable_captions]],
4303 [419, [revert_biblio_style]],
4304 [418, [revert_australian]],
4305 [417, [revert_justification]],
4306 [416, [revert_japanese_encodings]],
4307 [415, [revert_negative_space, revert_math_spaces]],
4308 [414, [revert_undertilde]],
4309 [413, [revert_visible_space]]
4313 if __name__ == "__main__":